From: Tomas Henzl <thenzl@redhat.com> Date: Tue, 17 Aug 2010 15:03:43 -0400 Subject: [scsi] mptsas: enable TLR for SSP TAPE drives Message-id: <20100817150342.6769.21692.sendpatchset@localhost.localdomain> Patchwork-id: 27663 O-Subject: [RHEL5.6 PATCH5/5] mptsas: Enable TLR for SSP TAPE drives Bugzilla: 599420 RH-Acked-by: Stanislaw Gruszka <sgruszka@redhat.com> If TLR is supported for end device, MPT2SAS driver will enable the TLR bit in the SCSI_IO for every request. If there is a response with MPI2_SCSITASKMGMT_RSP_INVALID_FRAME, the driver will turn off the TLR logic. For RAID volume sas_is_tlr_enabled call will hit BUG at scsi_transport_sas.c:163, since raid volume is not visible to sas transport layer. Now Added check to make sure arg pass in sas_is_tlr_enabled() is not a volume. http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=84f0b04a0e3b279a0b0a851b93eb403a626ca4b8 http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=3ed215259f2d8cd937abc833dc76e309173aaa52 Signed-off-by: Jarod Wilson <jarod@redhat.com> diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index 6168d32..dd451c0 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c @@ -1387,6 +1387,18 @@ _scsih_display_sata_capabilities(struct MPT2SAS_ADAPTER *ioc, } /** + * _scsih_is_raid - return boolean indicating device is raid volume + * @dev the device struct object + */ +static int +_scsih_is_raid(struct device *dev) +{ + struct scsi_device *sdev = to_scsi_device(dev); + + return (sdev->channel == RAID_CHANNEL) ? 1 : 0; +} + +/** * _scsih_get_volume_capabilities - volume capabilities * @ioc: per adapter object * @sas_device: the raid_device object @@ -1447,6 +1459,32 @@ _scsih_get_volume_capabilities(struct MPT2SAS_ADAPTER *ioc, } /** + * _scsih_enable_tlr - setting TLR flags + * @ioc: per adapter object + * @sdev: scsi device struct + * + * Enabling Transaction Layer Retries for tape devices when + * vpd page 0x90 is present + * + */ +static void +_scsih_enable_tlr(struct MPT2SAS_ADAPTER *ioc, struct scsi_device *sdev) +{ + /* only for TAPE */ + if (sdev->type != TYPE_TAPE) + return; + + if (!(ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR)) + return; + + sas_enable_tlr(sdev); + sdev_printk(KERN_INFO, sdev, "TLR %s\n", + sas_is_tlr_enabled(sdev) ? "Enabled" : "Disabled"); + return; + +} + +/** * _scsih_slave_configure - device configure routine. * @sdev: scsi device struct * @@ -1589,8 +1627,10 @@ _scsih_slave_configure(struct scsi_device *sdev) _scsih_change_queue_depth(sdev, qdepth); - if (ssp_target) + if (ssp_target) { sas_read_port_mode_page(sdev); + _scsih_enable_tlr(ioc, sdev); + } #if defined(EEDP_SUPPORT) if (ssp_target && (!(sas_target_priv_data->flags & @@ -2644,8 +2684,9 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *)) } else mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; - - if ((sas_device_priv_data->flags & MPT_DEVICE_TLR_ON)) + /* Make sure Device is not raid volume */ + if (!_scsih_is_raid(&scmd->device->sdev_gendev) && + sas_is_tlr_enabled(scmd->device)) mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON; smid = mpt2sas_base_get_smid(ioc, ioc->scsi_io_cb_idx); @@ -3031,15 +3072,17 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply) } /* turning off TLR */ + scsi_state = mpi_reply->SCSIState; + if (scsi_state & MPI2_SCSI_STATE_RESPONSE_INFO_VALID) + response_code = + le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF; if (!sas_device_priv_data->tlr_snoop_check) { sas_device_priv_data->tlr_snoop_check++; - if (sas_device_priv_data->flags & MPT_DEVICE_TLR_ON) { - response_code = (le32_to_cpu(mpi_reply->ResponseInfo) - >> 24); - if (response_code == - MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) - sas_device_priv_data->flags &= - ~MPT_DEVICE_TLR_ON; + if (!_scsih_is_raid(&scmd->device->sdev_gendev) && + sas_is_tlr_enabled(scmd->device) && + response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) { + sas_disable_tlr(scmd->device); + sdev_printk(KERN_INFO, scmd->device, "TLR disabled\n"); } } @@ -3051,7 +3094,6 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 VF_ID, u32 reply) else log_info = 0; ioc_status &= MPI2_IOCSTATUS_MASK; - scsi_state = mpi_reply->SCSIState; scsi_status = mpi_reply->SCSIStatus; if (ioc_status == MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&