aboutsummaryrefslogtreecommitdiff
path: root/drivers/scsi
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2006-03-11 11:42:34 +0900
committerJeff Garzik <jeff@garzik.org>2006-03-11 19:29:42 -0500
commit10d996ad1990ec2338c463042db6d5ef4f347187 (patch)
treea06a602f278f820475f16523e12927b5abb980c4 /drivers/scsi
parent75deb6fa985bd3162b9472f1fc394e23294da816 (diff)
[PATCH] sata_sil24: exit early from softreset if SStatus reports no device
sata_sil24 softreset routine used to check sata_dev_present() after SRST is complete in the hope that SRST may do some good even when SStatus reports no device. This is okay as long as SRST timeout is short (> 100ms in the current code) but it seems that not all SATA devices are happy with short SRST timeout. This patch makes softreset exit early without performing actual SRST if SStatus reports no device in preparation for lengthening SRST timeout. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/sata_sil24.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c
index 8fb62427be8..fa1a5ac6063 100644
--- a/drivers/scsi/sata_sil24.c
+++ b/drivers/scsi/sata_sil24.c
@@ -440,6 +440,12 @@ static int sil24_softreset(struct ata_port *ap, int verbose,
DPRINTK("ENTER\n");
+ if (!sata_dev_present(ap)) {
+ DPRINTK("PHY reports no device\n");
+ *class = ATA_DEV_NONE;
+ goto out;
+ }
+
/* temporarily turn off IRQs during SRST */
irq_enable = readl(port + PORT_IRQ_ENABLE_SET);
writel(irq_enable, port + PORT_IRQ_ENABLE_CLR);
@@ -469,18 +475,18 @@ static int sil24_softreset(struct ata_port *ap, int verbose,
/* restore IRQs */
writel(irq_enable, port + PORT_IRQ_ENABLE_SET);
- if (sata_dev_present(ap)) {
- if (!(irq_stat & PORT_IRQ_COMPLETE)) {
- DPRINTK("EXIT, srst failed\n");
- return -EIO;
- }
-
- sil24_update_tf(ap);
- *class = ata_dev_classify(&pp->tf);
+ if (!(irq_stat & PORT_IRQ_COMPLETE)) {
+ DPRINTK("EXIT, srst failed\n");
+ return -EIO;
}
+
+ sil24_update_tf(ap);
+ *class = ata_dev_classify(&pp->tf);
+
if (*class == ATA_DEV_UNKNOWN)
*class = ATA_DEV_NONE;
+ out:
DPRINTK("EXIT, class=%u\n", *class);
return 0;
}