diff options
author | Kashyap, Desai <kashyap.desai@lsi.com> | 2009-12-16 08:26:28 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-02-08 19:19:44 -0500 |
commit | 84f0b04a0e3b279a0b0a851b93eb403a626ca4b8 (patch) | |
tree | 0e7437b032ad129b3b0f97c96c5831ef44b3967b /drivers/scsi/mpt2sas/mpt2sas_scsih.c | |
parent | f4af3c14113d1b0d98d5a5e717b8aa1f484065b6 (diff) |
[SCSI] mpt2sas: Enable TLR for SSP TAPE drives (Added SAS Transport APIs)
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.
[jejb: updated to new transport class TLR API]
Signed-off-by: Kashyap Desai <kashyap.desai@lsi.com>
Reviewed-by: Eric Moore <Eric.moore@lsi.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_scsih.c')
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_scsih.c | 55 |
1 files changed, 35 insertions, 20 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index ca984cbc8e2f..344a22ad2f33 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c | |||
@@ -1309,7 +1309,6 @@ _scsih_slave_alloc(struct scsi_device *sdev) | |||
1309 | struct MPT2SAS_DEVICE *sas_device_priv_data; | 1309 | struct MPT2SAS_DEVICE *sas_device_priv_data; |
1310 | struct scsi_target *starget; | 1310 | struct scsi_target *starget; |
1311 | struct _raid_device *raid_device; | 1311 | struct _raid_device *raid_device; |
1312 | struct _sas_device *sas_device; | ||
1313 | unsigned long flags; | 1312 | unsigned long flags; |
1314 | 1313 | ||
1315 | sas_device_priv_data = kzalloc(sizeof(struct scsi_device), GFP_KERNEL); | 1314 | sas_device_priv_data = kzalloc(sizeof(struct scsi_device), GFP_KERNEL); |
@@ -1336,21 +1335,8 @@ _scsih_slave_alloc(struct scsi_device *sdev) | |||
1336 | if (raid_device) | 1335 | if (raid_device) |
1337 | raid_device->sdev = sdev; /* raid is single lun */ | 1336 | raid_device->sdev = sdev; /* raid is single lun */ |
1338 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); | 1337 | spin_unlock_irqrestore(&ioc->raid_device_lock, flags); |
1339 | } else { | ||
1340 | /* set TLR bit for SSP devices */ | ||
1341 | if (!(ioc->facts.IOCCapabilities & | ||
1342 | MPI2_IOCFACTS_CAPABILITY_TLR)) | ||
1343 | goto out; | ||
1344 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | ||
1345 | sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, | ||
1346 | sas_device_priv_data->sas_target->sas_address); | ||
1347 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
1348 | if (sas_device && sas_device->device_info & | ||
1349 | MPI2_SAS_DEVICE_INFO_SSP_TARGET) | ||
1350 | sas_device_priv_data->flags |= MPT_DEVICE_TLR_ON; | ||
1351 | } | 1338 | } |
1352 | 1339 | ||
1353 | out: | ||
1354 | return 0; | 1340 | return 0; |
1355 | } | 1341 | } |
1356 | 1342 | ||
@@ -1617,6 +1603,32 @@ _scsih_get_volume_capabilities(struct MPT2SAS_ADAPTER *ioc, | |||
1617 | } | 1603 | } |
1618 | 1604 | ||
1619 | /** | 1605 | /** |
1606 | * _scsih_enable_tlr - setting TLR flags | ||
1607 | * @ioc: per adapter object | ||
1608 | * @sdev: scsi device struct | ||
1609 | * | ||
1610 | * Enabling Transaction Layer Retries for tape devices when | ||
1611 | * vpd page 0x90 is present | ||
1612 | * | ||
1613 | */ | ||
1614 | static void | ||
1615 | _scsih_enable_tlr(struct MPT2SAS_ADAPTER *ioc, struct scsi_device *sdev) | ||
1616 | { | ||
1617 | /* only for TAPE */ | ||
1618 | if (sdev->type != TYPE_TAPE) | ||
1619 | return; | ||
1620 | |||
1621 | if (!(ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR)) | ||
1622 | return; | ||
1623 | |||
1624 | sas_enable_tlr(sdev); | ||
1625 | sdev_printk(KERN_INFO, sdev, "TLR %s\n", | ||
1626 | sas_is_tlr_enabled(sdev) ? "Enabled" : "Disabled"); | ||
1627 | return; | ||
1628 | |||
1629 | } | ||
1630 | |||
1631 | /** | ||
1620 | * _scsih_slave_configure - device configure routine. | 1632 | * _scsih_slave_configure - device configure routine. |
1621 | * @sdev: scsi device struct | 1633 | * @sdev: scsi device struct |
1622 | * | 1634 | * |
@@ -1761,8 +1773,10 @@ _scsih_slave_configure(struct scsi_device *sdev) | |||
1761 | 1773 | ||
1762 | _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT); | 1774 | _scsih_change_queue_depth(sdev, qdepth, SCSI_QDEPTH_DEFAULT); |
1763 | 1775 | ||
1764 | if (ssp_target) | 1776 | if (ssp_target) { |
1765 | sas_read_port_mode_page(sdev); | 1777 | sas_read_port_mode_page(sdev); |
1778 | _scsih_enable_tlr(ioc, sdev); | ||
1779 | } | ||
1766 | return 0; | 1780 | return 0; |
1767 | } | 1781 | } |
1768 | 1782 | ||
@@ -3049,7 +3063,7 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *)) | |||
3049 | } else | 3063 | } else |
3050 | mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; | 3064 | mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ; |
3051 | 3065 | ||
3052 | if ((sas_device_priv_data->flags & MPT_DEVICE_TLR_ON)) | 3066 | if (sas_is_tlr_enabled(scmd->device)) |
3053 | mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON; | 3067 | mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON; |
3054 | 3068 | ||
3055 | smid = mpt2sas_base_get_smid_scsiio(ioc, ioc->scsi_io_cb_idx, scmd); | 3069 | smid = mpt2sas_base_get_smid_scsiio(ioc, ioc->scsi_io_cb_idx, scmd); |
@@ -3438,10 +3452,11 @@ _scsih_io_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
3438 | le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF; | 3452 | le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF; |
3439 | if (!sas_device_priv_data->tlr_snoop_check) { | 3453 | if (!sas_device_priv_data->tlr_snoop_check) { |
3440 | sas_device_priv_data->tlr_snoop_check++; | 3454 | sas_device_priv_data->tlr_snoop_check++; |
3441 | if ((sas_device_priv_data->flags & MPT_DEVICE_TLR_ON) && | 3455 | if (sas_is_tlr_enabled(scmd->device) && |
3442 | response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) | 3456 | response_code == MPI2_SCSITASKMGMT_RSP_INVALID_FRAME) { |
3443 | sas_device_priv_data->flags &= | 3457 | sas_disable_tlr(scmd->device); |
3444 | ~MPT_DEVICE_TLR_ON; | 3458 | sdev_printk(KERN_INFO, scmd->device, "TLR disabled\n"); |
3459 | } | ||
3445 | } | 3460 | } |
3446 | 3461 | ||
3447 | xfer_cnt = le32_to_cpu(mpi_reply->TransferCount); | 3462 | xfer_cnt = le32_to_cpu(mpi_reply->TransferCount); |