aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2006-05-31 05:27:59 -0400
committerTejun Heo <htejun@gmail.com>2006-05-31 05:27:59 -0400
commite8e008e7b5ed8c65675cc9b3e778b8bb909f65ab (patch)
tree88ab9cff204c3a09630b145835bb0f7576a72791 /drivers
parent135da34573f6d3bab2976a75063f7232a4311a74 (diff)
[PATCH] sata_sil24: update sil24_hardreset()
Use phy debouncing instead of unconditional wait after DEV_RST and make sil24_hardreset() to request followup SRST as that's the only way to wait for !BSY. Note that the original implementation never worked - if the cached status was !BSY, ata_busy_sleep() finished immediately; otherwise, it timed out regardless of the actual device status. Signed-off-by: Tejun Heo <htejun@gmail.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/sata_sil24.c26
1 files changed, 14 insertions, 12 deletions
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c
index a39e8d0332c6..4a830903393d 100644
--- a/drivers/scsi/sata_sil24.c
+++ b/drivers/scsi/sata_sil24.c
@@ -591,7 +591,7 @@ static int sil24_hardreset(struct ata_port *ap, unsigned int *class)
591{ 591{
592 void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; 592 void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
593 const char *reason; 593 const char *reason;
594 int tout_msec; 594 int tout_msec, rc;
595 u32 tmp; 595 u32 tmp;
596 596
597 /* sil24 does the right thing(tm) without any protection */ 597 /* sil24 does the right thing(tm) without any protection */
@@ -605,10 +605,14 @@ static int sil24_hardreset(struct ata_port *ap, unsigned int *class)
605 tmp = ata_wait_register(port + PORT_CTRL_STAT, 605 tmp = ata_wait_register(port + PORT_CTRL_STAT,
606 PORT_CS_DEV_RST, PORT_CS_DEV_RST, 10, tout_msec); 606 PORT_CS_DEV_RST, PORT_CS_DEV_RST, 10, tout_msec);
607 607
608 /* SStatus oscillates between zero and valid status for short 608 /* SStatus oscillates between zero and valid status after
609 * duration after DEV_RST, give it time to settle. 609 * DEV_RST, debounce it.
610 */ 610 */
611 msleep(100); 611 rc = sata_phy_debounce(ap, sata_deb_timing_before_fsrst);
612 if (rc) {
613 reason = "PHY debouncing failed";
614 goto err;
615 }
612 616
613 if (tmp & PORT_CS_DEV_RST) { 617 if (tmp & PORT_CS_DEV_RST) {
614 if (ata_port_offline(ap)) 618 if (ata_port_offline(ap))
@@ -617,15 +621,13 @@ static int sil24_hardreset(struct ata_port *ap, unsigned int *class)
617 goto err; 621 goto err;
618 } 622 }
619 623
620 if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) { 624 /* Sil24 doesn't store signature FIS after hardreset, so we
621 reason = "device not ready"; 625 * can't wait for BSY to clear. Some devices take a long time
622 goto err; 626 * to get ready and those devices will choke if we don't wait
623 } 627 * for BSY clearance here. Tell libata to perform follow-up
624 628 * softreset.
625 /* sil24 doesn't report device class code after hardreset,
626 * leave *class alone.
627 */ 629 */
628 return 0; 630 return -EAGAIN;
629 631
630 err: 632 err:
631 ata_port_printk(ap, KERN_ERR, "hardreset failed (%s)\n", reason); 633 ata_port_printk(ap, KERN_ERR, "hardreset failed (%s)\n", reason);