diff options
author | Dan Williams <dan.j.williams@intel.com> | 2011-11-30 23:23:33 -0800 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-02-19 14:09:32 -0600 |
commit | b52df4174dff7e587f6fbfb21e3c2cb57109e5cf (patch) | |
tree | 1e53cb4a62519dda60babc240bbd3b7f69c5b1f4 /drivers/scsi/libsas/sas_ata.c | |
parent | 3a2cdf391b62919d3d2862cdce3d70b9a7a99673 (diff) | |
download | lwn-b52df4174dff7e587f6fbfb21e3c2cb57109e5cf.tar.gz lwn-b52df4174dff7e587f6fbfb21e3c2cb57109e5cf.zip |
[SCSI] libsas: use libata-eh-reset for sata rediscovery fis transmit failures
Since sata devices can take several seconds to recover the link on reset
the 0.5 seconds that libsas currently waits may not be enough. Instead
if we are rediscovering a phy that was previously attached to a sata
device let libata handle any resets to encourage the device to transmit
the initial fis.
Once sas_ata_hard_reset() and lldds learn how to honor 'deadline' libsas
should stop encountering phys in an intermediate state, until then this
will loop until the fis is transmitted or ->attached_sas_addr gets
cleared, but in the more likely initial discovery case we keep existing
behavior.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/libsas/sas_ata.c')
-rw-r--r-- | drivers/scsi/libsas/sas_ata.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index a8ace8d24e66..48cadf88c399 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c @@ -679,3 +679,22 @@ int sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q, return rtn; } + +void sas_ata_schedule_reset(struct domain_device *dev) +{ + struct ata_eh_info *ehi; + struct ata_port *ap; + unsigned long flags; + + if (!dev_is_sata(dev)) + return; + + ap = dev->sata_dev.ap; + ehi = &ap->link.eh_info; + + spin_lock_irqsave(ap->lock, flags); + ehi->err_mask |= AC_ERR_TIMEOUT; + ehi->action |= ATA_EH_RESET; + ata_port_schedule_eh(ap); + spin_unlock_irqrestore(ap->lock, flags); +} |