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.c57
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
54enum { 54enum {
@@ -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
516static int ahci_poll_register(void __iomem *reg, u32 mask, u32 val, 519static 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
534static 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
648static int ahci_hardreset(struct ata_port *ap, int verbose, unsigned int *class) 635static 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)