aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/sata_sil24.c43
1 files changed, 40 insertions, 3 deletions
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c
index be4817e6502b..4180c81f639c 100644
--- a/drivers/scsi/sata_sil24.c
+++ b/drivers/scsi/sata_sil24.c
@@ -521,10 +521,47 @@ static int sil24_softreset(struct ata_port *ap, unsigned int *class)
521 521
522static int sil24_hardreset(struct ata_port *ap, unsigned int *class) 522static int sil24_hardreset(struct ata_port *ap, unsigned int *class)
523{ 523{
524 unsigned int dummy_class; 524 void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
525 const char *reason;
526 int tout_msec;
527 u32 tmp;
528
529 /* sil24 does the right thing(tm) without any protection */
530 ata_set_sata_spd(ap);
531
532 tout_msec = 100;
533 if (sata_dev_present(ap))
534 tout_msec = 5000;
535
536 writel(PORT_CS_DEV_RST, port + PORT_CTRL_STAT);
537 tmp = ata_wait_register(port + PORT_CTRL_STAT,
538 PORT_CS_DEV_RST, PORT_CS_DEV_RST, 10, tout_msec);
539
540 /* SStatus oscillates between zero and valid status for short
541 * duration after DEV_RST, give it time to settle.
542 */
543 msleep(100);
544
545 if (tmp & PORT_CS_DEV_RST) {
546 if (!sata_dev_present(ap))
547 return 0;
548 reason = "link not ready";
549 goto err;
550 }
551
552 if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) {
553 reason = "device not ready";
554 goto err;
555 }
525 556
526 /* sil24 doesn't report device signature after hard reset */ 557 /* sil24 doesn't report device class code after hardreset,
527 return sata_std_hardreset(ap, &dummy_class); 558 * leave *class alone.
559 */
560 return 0;
561
562 err:
563 printk(KERN_ERR "ata%u: hardreset failed (%s)\n", ap->id, reason);
564 return -EIO;
528} 565}
529 566
530static int sil24_probe_reset(struct ata_port *ap, unsigned int *classes) 567static int sil24_probe_reset(struct ata_port *ap, unsigned int *classes)