aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ahci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/ahci.c')
-rw-r--r--drivers/scsi/ahci.c52
1 files changed, 18 insertions, 34 deletions
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c
index b4f8fb1d628b..1b8429cb3c96 100644
--- a/drivers/scsi/ahci.c
+++ b/drivers/scsi/ahci.c
@@ -48,7 +48,7 @@
48#include <asm/io.h> 48#include <asm/io.h>
49 49
50#define DRV_NAME "ahci" 50#define DRV_NAME "ahci"
51#define DRV_VERSION "1.2" 51#define DRV_VERSION "1.3"
52 52
53 53
54enum { 54enum {
@@ -516,25 +516,7 @@ static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, u32 opts)
516 pp->cmd_slot[0].tbl_addr_hi = cpu_to_le32((pp->cmd_tbl_dma >> 16) >> 16); 516 pp->cmd_slot[0].tbl_addr_hi = cpu_to_le32((pp->cmd_tbl_dma >> 16) >> 16);
517} 517}
518 518
519static int ahci_poll_register(void __iomem *reg, u32 mask, u32 val, 519static int ahci_softreset(struct ata_port *ap, unsigned int *class)
520 unsigned long interval_msec,
521 unsigned long timeout_msec)
522{
523 unsigned long timeout;
524 u32 tmp;
525
526 timeout = jiffies + (timeout_msec * HZ) / 1000;
527 do {
528 tmp = readl(reg);
529 if ((tmp & mask) == val)
530 return 0;
531 msleep(interval_msec);
532 } while (time_before(jiffies, timeout));
533
534 return -1;
535}
536
537static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class)
538{ 520{
539 struct ahci_host_priv *hpriv = ap->host_set->private_data; 521 struct ahci_host_priv *hpriv = ap->host_set->private_data;
540 struct ahci_port_priv *pp = ap->private_data; 522 struct ahci_port_priv *pp = ap->private_data;
@@ -543,11 +525,18 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class)
543 const u32 cmd_fis_len = 5; /* five dwords */ 525 const u32 cmd_fis_len = 5; /* five dwords */
544 const char *reason = NULL; 526 const char *reason = NULL;
545 struct ata_taskfile tf; 527 struct ata_taskfile tf;
528 u32 tmp;
546 u8 *fis; 529 u8 *fis;
547 int rc; 530 int rc;
548 531
549 DPRINTK("ENTER\n"); 532 DPRINTK("ENTER\n");
550 533
534 if (!sata_dev_present(ap)) {
535 DPRINTK("PHY reports no device\n");
536 *class = ATA_DEV_NONE;
537 return 0;
538 }
539
551 /* prepare for SRST (AHCI-1.1 10.4.1) */ 540 /* prepare for SRST (AHCI-1.1 10.4.1) */
552 rc = ahci_stop_engine(ap); 541 rc = ahci_stop_engine(ap);
553 if (rc) { 542 if (rc) {
@@ -558,8 +547,6 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class)
558 /* check BUSY/DRQ, perform Command List Override if necessary */ 547 /* check BUSY/DRQ, perform Command List Override if necessary */
559 ahci_tf_read(ap, &tf); 548 ahci_tf_read(ap, &tf);
560 if (tf.command & (ATA_BUSY | ATA_DRQ)) { 549 if (tf.command & (ATA_BUSY | ATA_DRQ)) {
561 u32 tmp;
562
563 if (!(hpriv->cap & HOST_CAP_CLO)) { 550 if (!(hpriv->cap & HOST_CAP_CLO)) {
564 rc = -EIO; 551 rc = -EIO;
565 reason = "port busy but no CLO"; 552 reason = "port busy but no CLO";
@@ -569,10 +556,10 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class)
569 tmp = readl(port_mmio + PORT_CMD); 556 tmp = readl(port_mmio + PORT_CMD);
570 tmp |= PORT_CMD_CLO; 557 tmp |= PORT_CMD_CLO;
571 writel(tmp, port_mmio + PORT_CMD); 558 writel(tmp, port_mmio + PORT_CMD);
572 readl(port_mmio + PORT_CMD); /* flush */
573 559
574 if (ahci_poll_register(port_mmio + PORT_CMD, PORT_CMD_CLO, 0x0, 560 tmp = ata_wait_register(port_mmio + PORT_CMD,
575 1, 500)) { 561 PORT_CMD_CLO, PORT_CMD_CLO, 1, 500);
562 if (tmp & PORT_CMD_CLO) {
576 rc = -EIO; 563 rc = -EIO;
577 reason = "CLO failed"; 564 reason = "CLO failed";
578 goto fail_restart; 565 goto fail_restart;
@@ -593,9 +580,9 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class)
593 fis[1] &= ~(1 << 7); /* turn off Command FIS bit */ 580 fis[1] &= ~(1 << 7); /* turn off Command FIS bit */
594 581
595 writel(1, port_mmio + PORT_CMD_ISSUE); 582 writel(1, port_mmio + PORT_CMD_ISSUE);
596 readl(port_mmio + PORT_CMD_ISSUE); /* flush */
597 583
598 if (ahci_poll_register(port_mmio + PORT_CMD_ISSUE, 0x1, 0x0, 1, 500)) { 584 tmp = ata_wait_register(port_mmio + PORT_CMD_ISSUE, 0x1, 0x1, 1, 500);
585 if (tmp & 0x1) {
599 rc = -EIO; 586 rc = -EIO;
600 reason = "1st FIS failed"; 587 reason = "1st FIS failed";
601 goto fail; 588 goto fail;
@@ -640,22 +627,19 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class)
640 fail_restart: 627 fail_restart:
641 ahci_start_engine(ap); 628 ahci_start_engine(ap);
642 fail: 629 fail:
643 if (verbose) 630 printk(KERN_ERR "ata%u: softreset failed (%s)\n",
644 printk(KERN_ERR "ata%u: softreset failed (%s)\n", 631 ap->id, reason);
645 ap->id, reason);
646 else
647 DPRINTK("EXIT, rc=%d reason=\"%s\"\n", rc, reason);
648 return rc; 632 return rc;
649} 633}
650 634
651static int ahci_hardreset(struct ata_port *ap, int verbose, unsigned int *class) 635static int ahci_hardreset(struct ata_port *ap, unsigned int *class)
652{ 636{
653 int rc; 637 int rc;
654 638
655 DPRINTK("ENTER\n"); 639 DPRINTK("ENTER\n");
656 640
657 ahci_stop_engine(ap); 641 ahci_stop_engine(ap);
658 rc = sata_std_hardreset(ap, verbose, class); 642 rc = sata_std_hardreset(ap, class);
659 ahci_start_engine(ap); 643 ahci_start_engine(ap);
660 644
661 if (rc == 0) 645 if (rc == 0)