diff options
Diffstat (limited to 'drivers/scsi/ahci.c')
-rw-r--r-- | drivers/scsi/ahci.c | 57 |
1 files changed, 22 insertions, 35 deletions
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index ffba65656a..1b8429cb3c 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 | ||
54 | enum { | 54 | enum { |
@@ -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, |
@@ -293,6 +292,10 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
293 | board_ahci }, /* JMicron JMB360 */ | 292 | board_ahci }, /* JMicron JMB360 */ |
294 | { 0x197b, 0x2363, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 293 | { 0x197b, 0x2363, PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
295 | board_ahci }, /* JMicron JMB363 */ | 294 | board_ahci }, /* JMicron JMB363 */ |
295 | { PCI_VENDOR_ID_ATI, 0x4380, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
296 | board_ahci }, /* ATI SB600 non-raid */ | ||
297 | { PCI_VENDOR_ID_ATI, 0x4381, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
298 | board_ahci }, /* ATI SB600 raid */ | ||
296 | { } /* terminate list */ | 299 | { } /* terminate list */ |
297 | }; | 300 | }; |
298 | 301 | ||
@@ -513,25 +516,7 @@ static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, u32 opts) | |||
513 | 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); |
514 | } | 517 | } |
515 | 518 | ||
516 | static int ahci_poll_register(void __iomem *reg, u32 mask, u32 val, | 519 | static int ahci_softreset(struct ata_port *ap, unsigned int *class) |
517 | unsigned long interval_msec, | ||
518 | unsigned long timeout_msec) | ||
519 | { | ||
520 | unsigned long timeout; | ||
521 | u32 tmp; | ||
522 | |||
523 | timeout = jiffies + (timeout_msec * HZ) / 1000; | ||
524 | do { | ||
525 | tmp = readl(reg); | ||
526 | if ((tmp & mask) == val) | ||
527 | return 0; | ||
528 | msleep(interval_msec); | ||
529 | } while (time_before(jiffies, timeout)); | ||
530 | |||
531 | return -1; | ||
532 | } | ||
533 | |||
534 | static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class) | ||
535 | { | 520 | { |
536 | struct ahci_host_priv *hpriv = ap->host_set->private_data; | 521 | struct ahci_host_priv *hpriv = ap->host_set->private_data; |
537 | struct ahci_port_priv *pp = ap->private_data; | 522 | struct ahci_port_priv *pp = ap->private_data; |
@@ -540,11 +525,18 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class) | |||
540 | const u32 cmd_fis_len = 5; /* five dwords */ | 525 | const u32 cmd_fis_len = 5; /* five dwords */ |
541 | const char *reason = NULL; | 526 | const char *reason = NULL; |
542 | struct ata_taskfile tf; | 527 | struct ata_taskfile tf; |
528 | u32 tmp; | ||
543 | u8 *fis; | 529 | u8 *fis; |
544 | int rc; | 530 | int rc; |
545 | 531 | ||
546 | DPRINTK("ENTER\n"); | 532 | DPRINTK("ENTER\n"); |
547 | 533 | ||
534 | if (!sata_dev_present(ap)) { | ||
535 | DPRINTK("PHY reports no device\n"); | ||
536 | *class = ATA_DEV_NONE; | ||
537 | return 0; | ||
538 | } | ||
539 | |||
548 | /* prepare for SRST (AHCI-1.1 10.4.1) */ | 540 | /* prepare for SRST (AHCI-1.1 10.4.1) */ |
549 | rc = ahci_stop_engine(ap); | 541 | rc = ahci_stop_engine(ap); |
550 | if (rc) { | 542 | if (rc) { |
@@ -555,8 +547,6 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class) | |||
555 | /* check BUSY/DRQ, perform Command List Override if necessary */ | 547 | /* check BUSY/DRQ, perform Command List Override if necessary */ |
556 | ahci_tf_read(ap, &tf); | 548 | ahci_tf_read(ap, &tf); |
557 | if (tf.command & (ATA_BUSY | ATA_DRQ)) { | 549 | if (tf.command & (ATA_BUSY | ATA_DRQ)) { |
558 | u32 tmp; | ||
559 | |||
560 | if (!(hpriv->cap & HOST_CAP_CLO)) { | 550 | if (!(hpriv->cap & HOST_CAP_CLO)) { |
561 | rc = -EIO; | 551 | rc = -EIO; |
562 | reason = "port busy but no CLO"; | 552 | reason = "port busy but no CLO"; |
@@ -566,10 +556,10 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class) | |||
566 | tmp = readl(port_mmio + PORT_CMD); | 556 | tmp = readl(port_mmio + PORT_CMD); |
567 | tmp |= PORT_CMD_CLO; | 557 | tmp |= PORT_CMD_CLO; |
568 | writel(tmp, port_mmio + PORT_CMD); | 558 | writel(tmp, port_mmio + PORT_CMD); |
569 | readl(port_mmio + PORT_CMD); /* flush */ | ||
570 | 559 | ||
571 | if (ahci_poll_register(port_mmio + PORT_CMD, PORT_CMD_CLO, 0x0, | 560 | tmp = ata_wait_register(port_mmio + PORT_CMD, |
572 | 1, 500)) { | 561 | PORT_CMD_CLO, PORT_CMD_CLO, 1, 500); |
562 | if (tmp & PORT_CMD_CLO) { | ||
573 | rc = -EIO; | 563 | rc = -EIO; |
574 | reason = "CLO failed"; | 564 | reason = "CLO failed"; |
575 | goto fail_restart; | 565 | goto fail_restart; |
@@ -590,9 +580,9 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class) | |||
590 | fis[1] &= ~(1 << 7); /* turn off Command FIS bit */ | 580 | fis[1] &= ~(1 << 7); /* turn off Command FIS bit */ |
591 | 581 | ||
592 | writel(1, port_mmio + PORT_CMD_ISSUE); | 582 | writel(1, port_mmio + PORT_CMD_ISSUE); |
593 | readl(port_mmio + PORT_CMD_ISSUE); /* flush */ | ||
594 | 583 | ||
595 | 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) { | ||
596 | rc = -EIO; | 586 | rc = -EIO; |
597 | reason = "1st FIS failed"; | 587 | reason = "1st FIS failed"; |
598 | goto fail; | 588 | goto fail; |
@@ -637,22 +627,19 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class) | |||
637 | fail_restart: | 627 | fail_restart: |
638 | ahci_start_engine(ap); | 628 | ahci_start_engine(ap); |
639 | fail: | 629 | fail: |
640 | if (verbose) | 630 | printk(KERN_ERR "ata%u: softreset failed (%s)\n", |
641 | printk(KERN_ERR "ata%u: softreset failed (%s)\n", | 631 | ap->id, reason); |
642 | ap->id, reason); | ||
643 | else | ||
644 | DPRINTK("EXIT, rc=%d reason=\"%s\"\n", rc, reason); | ||
645 | return rc; | 632 | return rc; |
646 | } | 633 | } |
647 | 634 | ||
648 | 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) |
649 | { | 636 | { |
650 | int rc; | 637 | int rc; |
651 | 638 | ||
652 | DPRINTK("ENTER\n"); | 639 | DPRINTK("ENTER\n"); |
653 | 640 | ||
654 | ahci_stop_engine(ap); | 641 | ahci_stop_engine(ap); |
655 | rc = sata_std_hardreset(ap, verbose, class); | 642 | rc = sata_std_hardreset(ap, class); |
656 | ahci_start_engine(ap); | 643 | ahci_start_engine(ap); |
657 | 644 | ||
658 | if (rc == 0) | 645 | if (rc == 0) |