[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>
This commit is contained in:
@@ -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)
|
|||||||
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)
|
|||||||
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);
|
||||||
|
Reference in New Issue
Block a user