diff options
Diffstat (limited to 'drivers/scsi/ahci.c')
-rw-r--r-- | drivers/scsi/ahci.c | 45 |
1 files changed, 11 insertions, 34 deletions
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index ff48066d4c4f..1b8429cb3c96 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c | |||
@@ -207,7 +207,6 @@ static struct scsi_host_template ahci_sht = { | |||
207 | .name = DRV_NAME, | 207 | .name = DRV_NAME, |
208 | .ioctl = ata_scsi_ioctl, | 208 | .ioctl = ata_scsi_ioctl, |
209 | .queuecommand = ata_scsi_queuecmd, | 209 | .queuecommand = ata_scsi_queuecmd, |
210 | .eh_strategy_handler = ata_scsi_error, | ||
211 | .can_queue = ATA_DEF_QUEUE, | 210 | .can_queue = ATA_DEF_QUEUE, |
212 | .this_id = ATA_SHT_THIS_ID, | 211 | .this_id = ATA_SHT_THIS_ID, |
213 | .sg_tablesize = AHCI_MAX_SG, | 212 | .sg_tablesize = AHCI_MAX_SG, |
@@ -517,25 +516,7 @@ static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, u32 opts) | |||
517 | 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); |
518 | } | 517 | } |
519 | 518 | ||
520 | static int ahci_poll_register(void __iomem *reg, u32 mask, u32 val, | 519 | static int ahci_softreset(struct ata_port *ap, unsigned int *class) |
521 | unsigned long interval_msec, | ||
522 | unsigned long timeout_msec) | ||
523 | { | ||
524 | unsigned long timeout; | ||
525 | u32 tmp; | ||
526 | |||
527 | timeout = jiffies + (timeout_msec * HZ) / 1000; | ||
528 | do { | ||
529 | tmp = readl(reg); | ||
530 | if ((tmp & mask) == val) | ||
531 | return 0; | ||
532 | msleep(interval_msec); | ||
533 | } while (time_before(jiffies, timeout)); | ||
534 | |||
535 | return -1; | ||
536 | } | ||
537 | |||
538 | static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class) | ||
539 | { | 520 | { |
540 | struct ahci_host_priv *hpriv = ap->host_set->private_data; | 521 | struct ahci_host_priv *hpriv = ap->host_set->private_data; |
541 | struct ahci_port_priv *pp = ap->private_data; | 522 | struct ahci_port_priv *pp = ap->private_data; |
@@ -544,6 +525,7 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class) | |||
544 | const u32 cmd_fis_len = 5; /* five dwords */ | 525 | const u32 cmd_fis_len = 5; /* five dwords */ |
545 | const char *reason = NULL; | 526 | const char *reason = NULL; |
546 | struct ata_taskfile tf; | 527 | struct ata_taskfile tf; |
528 | u32 tmp; | ||
547 | u8 *fis; | 529 | u8 *fis; |
548 | int rc; | 530 | int rc; |
549 | 531 | ||
@@ -565,8 +547,6 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class) | |||
565 | /* check BUSY/DRQ, perform Command List Override if necessary */ | 547 | /* check BUSY/DRQ, perform Command List Override if necessary */ |
566 | ahci_tf_read(ap, &tf); | 548 | ahci_tf_read(ap, &tf); |
567 | if (tf.command & (ATA_BUSY | ATA_DRQ)) { | 549 | if (tf.command & (ATA_BUSY | ATA_DRQ)) { |
568 | u32 tmp; | ||
569 | |||
570 | if (!(hpriv->cap & HOST_CAP_CLO)) { | 550 | if (!(hpriv->cap & HOST_CAP_CLO)) { |
571 | rc = -EIO; | 551 | rc = -EIO; |
572 | reason = "port busy but no CLO"; | 552 | reason = "port busy but no CLO"; |
@@ -576,10 +556,10 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class) | |||
576 | tmp = readl(port_mmio + PORT_CMD); | 556 | tmp = readl(port_mmio + PORT_CMD); |
577 | tmp |= PORT_CMD_CLO; | 557 | tmp |= PORT_CMD_CLO; |
578 | writel(tmp, port_mmio + PORT_CMD); | 558 | writel(tmp, port_mmio + PORT_CMD); |
579 | readl(port_mmio + PORT_CMD); /* flush */ | ||
580 | 559 | ||
581 | if (ahci_poll_register(port_mmio + PORT_CMD, PORT_CMD_CLO, 0x0, | 560 | tmp = ata_wait_register(port_mmio + PORT_CMD, |
582 | 1, 500)) { | 561 | PORT_CMD_CLO, PORT_CMD_CLO, 1, 500); |
562 | if (tmp & PORT_CMD_CLO) { | ||
583 | rc = -EIO; | 563 | rc = -EIO; |
584 | reason = "CLO failed"; | 564 | reason = "CLO failed"; |
585 | goto fail_restart; | 565 | goto fail_restart; |
@@ -600,9 +580,9 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class) | |||
600 | fis[1] &= ~(1 << 7); /* turn off Command FIS bit */ | 580 | fis[1] &= ~(1 << 7); /* turn off Command FIS bit */ |
601 | 581 | ||
602 | writel(1, port_mmio + PORT_CMD_ISSUE); | 582 | writel(1, port_mmio + PORT_CMD_ISSUE); |
603 | readl(port_mmio + PORT_CMD_ISSUE); /* flush */ | ||
604 | 583 | ||
605 | 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) { | ||
606 | rc = -EIO; | 586 | rc = -EIO; |
607 | reason = "1st FIS failed"; | 587 | reason = "1st FIS failed"; |
608 | goto fail; | 588 | goto fail; |
@@ -647,22 +627,19 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class) | |||
647 | fail_restart: | 627 | fail_restart: |
648 | ahci_start_engine(ap); | 628 | ahci_start_engine(ap); |
649 | fail: | 629 | fail: |
650 | if (verbose) | 630 | printk(KERN_ERR "ata%u: softreset failed (%s)\n", |
651 | printk(KERN_ERR "ata%u: softreset failed (%s)\n", | 631 | ap->id, reason); |
652 | ap->id, reason); | ||
653 | else | ||
654 | DPRINTK("EXIT, rc=%d reason=\"%s\"\n", rc, reason); | ||
655 | return rc; | 632 | return rc; |
656 | } | 633 | } |
657 | 634 | ||
658 | static int ahci_hardreset(struct ata_port *ap, int verbose, unsigned int *class) | 635 | static int ahci_hardreset(struct ata_port *ap, unsigned int *class) |
659 | { | 636 | { |
660 | int rc; | 637 | int rc; |
661 | 638 | ||
662 | DPRINTK("ENTER\n"); | 639 | DPRINTK("ENTER\n"); |
663 | 640 | ||
664 | ahci_stop_engine(ap); | 641 | ahci_stop_engine(ap); |
665 | rc = sata_std_hardreset(ap, verbose, class); | 642 | rc = sata_std_hardreset(ap, class); |
666 | ahci_start_engine(ap); | 643 | ahci_start_engine(ap); |
667 | 644 | ||
668 | if (rc == 0) | 645 | if (rc == 0) |