提交 e8e008e7 编写于 作者: T Tejun Heo

[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: NTejun Heo <htejun@gmail.com>
上级 135da345
...@@ -591,7 +591,7 @@ static int sil24_hardreset(struct ata_port *ap, unsigned int *class) ...@@ -591,7 +591,7 @@ static int sil24_hardreset(struct ata_port *ap, unsigned int *class)
{ {
void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
const char *reason; const char *reason;
int tout_msec; int tout_msec, rc;
u32 tmp; u32 tmp;
/* sil24 does the right thing(tm) without any protection */ /* 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,10 +605,14 @@ static int sil24_hardreset(struct ata_port *ap, unsigned int *class)
tmp = ata_wait_register(port + PORT_CTRL_STAT, tmp = ata_wait_register(port + PORT_CTRL_STAT,
PORT_CS_DEV_RST, PORT_CS_DEV_RST, 10, tout_msec); PORT_CS_DEV_RST, PORT_CS_DEV_RST, 10, tout_msec);
/* SStatus oscillates between zero and valid status for short /* SStatus oscillates between zero and valid status after
* duration after DEV_RST, give it time to settle. * DEV_RST, debounce it.
*/ */
msleep(100); rc = sata_phy_debounce(ap, sata_deb_timing_before_fsrst);
if (rc) {
reason = "PHY debouncing failed";
goto err;
}
if (tmp & PORT_CS_DEV_RST) { if (tmp & PORT_CS_DEV_RST) {
if (ata_port_offline(ap)) if (ata_port_offline(ap))
...@@ -617,15 +621,13 @@ static int sil24_hardreset(struct ata_port *ap, unsigned int *class) ...@@ -617,15 +621,13 @@ static int sil24_hardreset(struct ata_port *ap, unsigned int *class)
goto err; goto err;
} }
if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) { /* Sil24 doesn't store signature FIS after hardreset, so we
reason = "device not ready"; * can't wait for BSY to clear. Some devices take a long time
goto err; * to get ready and those devices will choke if we don't wait
} * for BSY clearance here. Tell libata to perform follow-up
* softreset.
/* sil24 doesn't report device class code after hardreset,
* leave *class alone.
*/ */
return 0; return -EAGAIN;
err: err:
ata_port_printk(ap, KERN_ERR, "hardreset failed (%s)\n", reason); ata_port_printk(ap, KERN_ERR, "hardreset failed (%s)\n", reason);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册