[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_transport_sas.h>
|
||||
#include <scsi/scsi_dbg.h>
|
||||
#include <scsi/scsi_eh.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
|
||||
* @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);
|
||||
memset(mpi_request, 0, sizeof(Mpi2SCSIIORequest_t));
|
||||
_scsih_setup_eedp(scmd, mpi_request);
|
||||
mpi_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
|
||||
if (sas_device_priv_data->sas_target->flags &
|
||||
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:
|
||||
desc_ioc_state = "scsi ext terminated";
|
||||
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:
|
||||
desc_ioc_state = "unknown";
|
||||
break;
|
||||
|
@ -2939,6 +3049,11 @@ scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply)
|
|||
scmd->result = DID_RESET << 16;
|
||||
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_INVALID_FUNCTION:
|
||||
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;
|
||||
}
|
||||
|
||||
scsi_host_set_prot(shost, SHOST_DIF_TYPE1_PROTECTION
|
||||
| SHOST_DIF_TYPE3_PROTECTION);
|
||||
|
||||
/* event thread */
|
||||
snprintf(ioc->firmware_event_name, sizeof(ioc->firmware_event_name),
|
||||
"fw_event%d", ioc->id);
|
||||
|
|
Загрузка…
Ссылка в новой задаче