[SCSI] mpt2sas: T10 DIF Support
This add support for type 1 and 3 DIF support per the Oracle API. Signed-off-by: Eric Moore <eric.moore@lsi.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
This commit is contained in:
Родитель
6fcf41d1d8
Коммит
3c621b3ee1
|
@ -61,6 +61,7 @@
|
||||||
#include <scsi/scsi_tcq.h>
|
#include <scsi/scsi_tcq.h>
|
||||||
#include <scsi/scsi_transport_sas.h>
|
#include <scsi/scsi_transport_sas.h>
|
||||||
#include <scsi/scsi_dbg.h>
|
#include <scsi/scsi_dbg.h>
|
||||||
|
#include <scsi/scsi_eh.h>
|
||||||
|
|
||||||
#include "mpt2sas_debug.h"
|
#include "mpt2sas_debug.h"
|
||||||
|
|
||||||
|
|
|
@ -2389,6 +2389,106 @@ mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* _scsih_setup_eedp - setup MPI request for EEDP transfer
|
||||||
|
* @scmd: pointer to scsi command object
|
||||||
|
* @mpi_request: pointer to the SCSI_IO reqest message frame
|
||||||
|
*
|
||||||
|
* Supporting protection 1 and 3.
|
||||||
|
*
|
||||||
|
* Returns nothing
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
_scsih_setup_eedp(struct scsi_cmnd *scmd, Mpi2SCSIIORequest_t *mpi_request)
|
||||||
|
{
|
||||||
|
u16 eedp_flags;
|
||||||
|
unsigned char prot_op = scsi_get_prot_op(scmd);
|
||||||
|
unsigned char prot_type = scsi_get_prot_type(scmd);
|
||||||
|
|
||||||
|
if (prot_type == SCSI_PROT_DIF_TYPE0 ||
|
||||||
|
prot_type == SCSI_PROT_DIF_TYPE2 ||
|
||||||
|
prot_op == SCSI_PROT_NORMAL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (prot_op == SCSI_PROT_READ_STRIP)
|
||||||
|
eedp_flags = MPI2_SCSIIO_EEDPFLAGS_CHECK_REMOVE_OP;
|
||||||
|
else if (prot_op == SCSI_PROT_WRITE_INSERT)
|
||||||
|
eedp_flags = MPI2_SCSIIO_EEDPFLAGS_INSERT_OP;
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
|
||||||
|
mpi_request->EEDPBlockSize = scmd->device->sector_size;
|
||||||
|
|
||||||
|
switch (prot_type) {
|
||||||
|
case SCSI_PROT_DIF_TYPE1:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* enable ref/guard checking
|
||||||
|
* auto increment ref tag
|
||||||
|
*/
|
||||||
|
mpi_request->EEDPFlags = eedp_flags |
|
||||||
|
MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG |
|
||||||
|
MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG |
|
||||||
|
MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD;
|
||||||
|
mpi_request->CDB.EEDP32.PrimaryReferenceTag =
|
||||||
|
cpu_to_be32(scsi_get_lba(scmd));
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCSI_PROT_DIF_TYPE3:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* enable guard checking
|
||||||
|
*/
|
||||||
|
mpi_request->EEDPFlags = eedp_flags |
|
||||||
|
MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* _scsih_eedp_error_handling - return sense code for EEDP errors
|
||||||
|
* @scmd: pointer to scsi command object
|
||||||
|
* @ioc_status: ioc status
|
||||||
|
*
|
||||||
|
* Returns nothing
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
_scsih_eedp_error_handling(struct scsi_cmnd *scmd, u16 ioc_status)
|
||||||
|
{
|
||||||
|
u8 ascq;
|
||||||
|
u8 sk;
|
||||||
|
u8 host_byte;
|
||||||
|
|
||||||
|
switch (ioc_status) {
|
||||||
|
case MPI2_IOCSTATUS_EEDP_GUARD_ERROR:
|
||||||
|
ascq = 0x01;
|
||||||
|
break;
|
||||||
|
case MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR:
|
||||||
|
ascq = 0x02;
|
||||||
|
break;
|
||||||
|
case MPI2_IOCSTATUS_EEDP_REF_TAG_ERROR:
|
||||||
|
ascq = 0x03;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ascq = 0x00;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scmd->sc_data_direction == DMA_TO_DEVICE) {
|
||||||
|
sk = ILLEGAL_REQUEST;
|
||||||
|
host_byte = DID_ABORT;
|
||||||
|
} else {
|
||||||
|
sk = ABORTED_COMMAND;
|
||||||
|
host_byte = DID_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
scsi_build_sense_buffer(0, scmd->sense_buffer, sk, 0x10, ascq);
|
||||||
|
scmd->result = DRIVER_SENSE << 24 | (host_byte << 16) |
|
||||||
|
SAM_STAT_CHECK_CONDITION;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* scsih_qcmd - main scsi request entry point
|
* scsih_qcmd - main scsi request entry point
|
||||||
* @scmd: pointer to scsi command object
|
* @scmd: pointer to scsi command object
|
||||||
|
@ -2470,6 +2570,7 @@ scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
|
||||||
}
|
}
|
||||||
mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
|
mpi_request = mpt2sas_base_get_msg_frame(ioc, smid);
|
||||||
memset(mpi_request, 0, sizeof(Mpi2SCSIIORequest_t));
|
memset(mpi_request, 0, sizeof(Mpi2SCSIIORequest_t));
|
||||||
|
_scsih_setup_eedp(scmd, mpi_request);
|
||||||
mpi_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
|
mpi_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
|
||||||
if (sas_device_priv_data->sas_target->flags &
|
if (sas_device_priv_data->sas_target->flags &
|
||||||
MPT_TARGET_FLAGS_RAID_COMPONENT)
|
MPT_TARGET_FLAGS_RAID_COMPONENT)
|
||||||
|
@ -2604,6 +2705,15 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
|
||||||
case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED:
|
case MPI2_IOCSTATUS_SCSI_EXT_TERMINATED:
|
||||||
desc_ioc_state = "scsi ext terminated";
|
desc_ioc_state = "scsi ext terminated";
|
||||||
break;
|
break;
|
||||||
|
case MPI2_IOCSTATUS_EEDP_GUARD_ERROR:
|
||||||
|
desc_ioc_state = "eedp guard error";
|
||||||
|
break;
|
||||||
|
case MPI2_IOCSTATUS_EEDP_REF_TAG_ERROR:
|
||||||
|
desc_ioc_state = "eedp ref tag error";
|
||||||
|
break;
|
||||||
|
case MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR:
|
||||||
|
desc_ioc_state = "eedp app tag error";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
desc_ioc_state = "unknown";
|
desc_ioc_state = "unknown";
|
||||||
break;
|
break;
|
||||||
|
@ -2939,6 +3049,11 @@ scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply)
|
||||||
scmd->result = DID_RESET << 16;
|
scmd->result = DID_RESET << 16;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MPI2_IOCSTATUS_EEDP_GUARD_ERROR:
|
||||||
|
case MPI2_IOCSTATUS_EEDP_REF_TAG_ERROR:
|
||||||
|
case MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR:
|
||||||
|
_scsih_eedp_error_handling(scmd, ioc_status);
|
||||||
|
break;
|
||||||
case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR:
|
case MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR:
|
||||||
case MPI2_IOCSTATUS_INVALID_FUNCTION:
|
case MPI2_IOCSTATUS_INVALID_FUNCTION:
|
||||||
case MPI2_IOCSTATUS_INVALID_SGL:
|
case MPI2_IOCSTATUS_INVALID_SGL:
|
||||||
|
@ -5503,6 +5618,9 @@ scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||||
goto out_add_shost_fail;
|
goto out_add_shost_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scsi_host_set_prot(shost, SHOST_DIF_TYPE1_PROTECTION
|
||||||
|
| SHOST_DIF_TYPE3_PROTECTION);
|
||||||
|
|
||||||
/* event thread */
|
/* event thread */
|
||||||
snprintf(ioc->firmware_event_name, sizeof(ioc->firmware_event_name),
|
snprintf(ioc->firmware_event_name, sizeof(ioc->firmware_event_name),
|
||||||
"fw_event%d", ioc->id);
|
"fw_event%d", ioc->id);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче