diff options
-rw-r--r-- | drivers/scsi/sata_sil24.c | 43 |
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 | ||
522 | static int sil24_hardreset(struct ata_port *ap, unsigned int *class) | 522 | static 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 | ||
530 | static int sil24_probe_reset(struct ata_port *ap, unsigned int *classes) | 567 | static int sil24_probe_reset(struct ata_port *ap, unsigned int *classes) |