diff options
Diffstat (limited to 'drivers/scsi/ahci.c')
-rw-r--r-- | drivers/scsi/ahci.c | 159 |
1 files changed, 92 insertions, 67 deletions
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index a800fb51168b..98ce6bb62ff8 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c | |||
@@ -66,6 +66,8 @@ enum { | |||
66 | AHCI_IRQ_ON_SG = (1 << 31), | 66 | AHCI_IRQ_ON_SG = (1 << 31), |
67 | AHCI_CMD_ATAPI = (1 << 5), | 67 | AHCI_CMD_ATAPI = (1 << 5), |
68 | AHCI_CMD_WRITE = (1 << 6), | 68 | AHCI_CMD_WRITE = (1 << 6), |
69 | AHCI_CMD_RESET = (1 << 8), | ||
70 | AHCI_CMD_CLR_BUSY = (1 << 10), | ||
69 | 71 | ||
70 | RX_FIS_D2H_REG = 0x40, /* offset of D2H Register FIS data */ | 72 | RX_FIS_D2H_REG = 0x40, /* offset of D2H Register FIS data */ |
71 | 73 | ||
@@ -85,6 +87,7 @@ enum { | |||
85 | 87 | ||
86 | /* HOST_CAP bits */ | 88 | /* HOST_CAP bits */ |
87 | HOST_CAP_64 = (1 << 31), /* PCI DAC (64-bit DMA) support */ | 89 | HOST_CAP_64 = (1 << 31), /* PCI DAC (64-bit DMA) support */ |
90 | HOST_CAP_CLO = (1 << 24), /* Command List Override support */ | ||
88 | 91 | ||
89 | /* registers for each SATA port */ | 92 | /* registers for each SATA port */ |
90 | PORT_LST_ADDR = 0x00, /* command list DMA addr */ | 93 | PORT_LST_ADDR = 0x00, /* command list DMA addr */ |
@@ -138,6 +141,7 @@ enum { | |||
138 | PORT_CMD_LIST_ON = (1 << 15), /* cmd list DMA engine running */ | 141 | PORT_CMD_LIST_ON = (1 << 15), /* cmd list DMA engine running */ |
139 | PORT_CMD_FIS_ON = (1 << 14), /* FIS DMA engine running */ | 142 | PORT_CMD_FIS_ON = (1 << 14), /* FIS DMA engine running */ |
140 | PORT_CMD_FIS_RX = (1 << 4), /* Enable FIS receive DMA engine */ | 143 | PORT_CMD_FIS_RX = (1 << 4), /* Enable FIS receive DMA engine */ |
144 | PORT_CMD_CLO = (1 << 3), /* Command list override */ | ||
141 | PORT_CMD_POWER_ON = (1 << 2), /* Power up device */ | 145 | PORT_CMD_POWER_ON = (1 << 2), /* Power up device */ |
142 | PORT_CMD_SPIN_UP = (1 << 1), /* Spin up device */ | 146 | PORT_CMD_SPIN_UP = (1 << 1), /* Spin up device */ |
143 | PORT_CMD_START = (1 << 0), /* Enable port DMA engine */ | 147 | PORT_CMD_START = (1 << 0), /* Enable port DMA engine */ |
@@ -184,7 +188,7 @@ struct ahci_port_priv { | |||
184 | static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg); | 188 | static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg); |
185 | static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); | 189 | static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); |
186 | static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); | 190 | static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); |
187 | static int ahci_qc_issue(struct ata_queued_cmd *qc); | 191 | static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc); |
188 | static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *regs); | 192 | static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *regs); |
189 | static void ahci_phy_reset(struct ata_port *ap); | 193 | static void ahci_phy_reset(struct ata_port *ap); |
190 | static void ahci_irq_clear(struct ata_port *ap); | 194 | static void ahci_irq_clear(struct ata_port *ap); |
@@ -202,6 +206,7 @@ static struct scsi_host_template ahci_sht = { | |||
202 | .name = DRV_NAME, | 206 | .name = DRV_NAME, |
203 | .ioctl = ata_scsi_ioctl, | 207 | .ioctl = ata_scsi_ioctl, |
204 | .queuecommand = ata_scsi_queuecmd, | 208 | .queuecommand = ata_scsi_queuecmd, |
209 | .eh_timed_out = ata_scsi_timed_out, | ||
205 | .eh_strategy_handler = ata_scsi_error, | 210 | .eh_strategy_handler = ata_scsi_error, |
206 | .can_queue = ATA_DEF_QUEUE, | 211 | .can_queue = ATA_DEF_QUEUE, |
207 | .this_id = ATA_SHT_THIS_ID, | 212 | .this_id = ATA_SHT_THIS_ID, |
@@ -450,25 +455,81 @@ static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg_in, | |||
450 | writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4)); | 455 | writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4)); |
451 | } | 456 | } |
452 | 457 | ||
453 | static void ahci_phy_reset(struct ata_port *ap) | 458 | static int ahci_stop_engine(struct ata_port *ap) |
459 | { | ||
460 | void __iomem *mmio = ap->host_set->mmio_base; | ||
461 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | ||
462 | int work; | ||
463 | u32 tmp; | ||
464 | |||
465 | tmp = readl(port_mmio + PORT_CMD); | ||
466 | tmp &= ~PORT_CMD_START; | ||
467 | writel(tmp, port_mmio + PORT_CMD); | ||
468 | |||
469 | /* wait for engine to stop. TODO: this could be | ||
470 | * as long as 500 msec | ||
471 | */ | ||
472 | work = 1000; | ||
473 | while (work-- > 0) { | ||
474 | tmp = readl(port_mmio + PORT_CMD); | ||
475 | if ((tmp & PORT_CMD_LIST_ON) == 0) | ||
476 | return 0; | ||
477 | udelay(10); | ||
478 | } | ||
479 | |||
480 | return -EIO; | ||
481 | } | ||
482 | |||
483 | static void ahci_start_engine(struct ata_port *ap) | ||
484 | { | ||
485 | void __iomem *mmio = ap->host_set->mmio_base; | ||
486 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | ||
487 | u32 tmp; | ||
488 | |||
489 | tmp = readl(port_mmio + PORT_CMD); | ||
490 | tmp |= PORT_CMD_START; | ||
491 | writel(tmp, port_mmio + PORT_CMD); | ||
492 | readl(port_mmio + PORT_CMD); /* flush */ | ||
493 | } | ||
494 | |||
495 | static unsigned int ahci_dev_classify(struct ata_port *ap) | ||
454 | { | 496 | { |
455 | void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; | 497 | void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; |
456 | struct ata_taskfile tf; | 498 | struct ata_taskfile tf; |
499 | u32 tmp; | ||
500 | |||
501 | tmp = readl(port_mmio + PORT_SIG); | ||
502 | tf.lbah = (tmp >> 24) & 0xff; | ||
503 | tf.lbam = (tmp >> 16) & 0xff; | ||
504 | tf.lbal = (tmp >> 8) & 0xff; | ||
505 | tf.nsect = (tmp) & 0xff; | ||
506 | |||
507 | return ata_dev_classify(&tf); | ||
508 | } | ||
509 | |||
510 | static void ahci_fill_cmd_slot(struct ata_port *ap, u32 opts) | ||
511 | { | ||
512 | struct ahci_port_priv *pp = ap->private_data; | ||
513 | pp->cmd_slot[0].opts = cpu_to_le32(opts); | ||
514 | pp->cmd_slot[0].status = 0; | ||
515 | pp->cmd_slot[0].tbl_addr = cpu_to_le32(pp->cmd_tbl_dma & 0xffffffff); | ||
516 | pp->cmd_slot[0].tbl_addr_hi = cpu_to_le32((pp->cmd_tbl_dma >> 16) >> 16); | ||
517 | } | ||
518 | |||
519 | static void ahci_phy_reset(struct ata_port *ap) | ||
520 | { | ||
521 | void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; | ||
457 | struct ata_device *dev = &ap->device[0]; | 522 | struct ata_device *dev = &ap->device[0]; |
458 | u32 new_tmp, tmp; | 523 | u32 new_tmp, tmp; |
459 | 524 | ||
525 | ahci_stop_engine(ap); | ||
460 | __sata_phy_reset(ap); | 526 | __sata_phy_reset(ap); |
527 | ahci_start_engine(ap); | ||
461 | 528 | ||
462 | if (ap->flags & ATA_FLAG_PORT_DISABLED) | 529 | if (ap->flags & ATA_FLAG_PORT_DISABLED) |
463 | return; | 530 | return; |
464 | 531 | ||
465 | tmp = readl(port_mmio + PORT_SIG); | 532 | dev->class = ahci_dev_classify(ap); |
466 | tf.lbah = (tmp >> 24) & 0xff; | ||
467 | tf.lbam = (tmp >> 16) & 0xff; | ||
468 | tf.lbal = (tmp >> 8) & 0xff; | ||
469 | tf.nsect = (tmp) & 0xff; | ||
470 | |||
471 | dev->class = ata_dev_classify(&tf); | ||
472 | if (!ata_dev_present(dev)) { | 533 | if (!ata_dev_present(dev)) { |
473 | ata_port_disable(ap); | 534 | ata_port_disable(ap); |
474 | return; | 535 | return; |
@@ -533,42 +594,35 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc) | |||
533 | { | 594 | { |
534 | struct ata_port *ap = qc->ap; | 595 | struct ata_port *ap = qc->ap; |
535 | struct ahci_port_priv *pp = ap->private_data; | 596 | struct ahci_port_priv *pp = ap->private_data; |
597 | int is_atapi = is_atapi_taskfile(&qc->tf); | ||
536 | u32 opts; | 598 | u32 opts; |
537 | const u32 cmd_fis_len = 5; /* five dwords */ | 599 | const u32 cmd_fis_len = 5; /* five dwords */ |
538 | unsigned int n_elem; | 600 | unsigned int n_elem; |
539 | 601 | ||
540 | /* | 602 | /* |
541 | * Fill in command slot information (currently only one slot, | ||
542 | * slot 0, is currently since we don't do queueing) | ||
543 | */ | ||
544 | |||
545 | opts = cmd_fis_len; | ||
546 | if (qc->tf.flags & ATA_TFLAG_WRITE) | ||
547 | opts |= AHCI_CMD_WRITE; | ||
548 | if (is_atapi_taskfile(&qc->tf)) | ||
549 | opts |= AHCI_CMD_ATAPI; | ||
550 | |||
551 | pp->cmd_slot[0].opts = cpu_to_le32(opts); | ||
552 | pp->cmd_slot[0].status = 0; | ||
553 | pp->cmd_slot[0].tbl_addr = cpu_to_le32(pp->cmd_tbl_dma & 0xffffffff); | ||
554 | pp->cmd_slot[0].tbl_addr_hi = cpu_to_le32((pp->cmd_tbl_dma >> 16) >> 16); | ||
555 | |||
556 | /* | ||
557 | * Fill in command table information. First, the header, | 603 | * Fill in command table information. First, the header, |
558 | * a SATA Register - Host to Device command FIS. | 604 | * a SATA Register - Host to Device command FIS. |
559 | */ | 605 | */ |
560 | ata_tf_to_fis(&qc->tf, pp->cmd_tbl, 0); | 606 | ata_tf_to_fis(&qc->tf, pp->cmd_tbl, 0); |
561 | if (opts & AHCI_CMD_ATAPI) { | 607 | if (is_atapi) { |
562 | memset(pp->cmd_tbl + AHCI_CMD_TBL_CDB, 0, 32); | 608 | memset(pp->cmd_tbl + AHCI_CMD_TBL_CDB, 0, 32); |
563 | memcpy(pp->cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, ap->cdb_len); | 609 | memcpy(pp->cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, ap->cdb_len); |
564 | } | 610 | } |
565 | 611 | ||
566 | if (!(qc->flags & ATA_QCFLAG_DMAMAP)) | 612 | n_elem = 0; |
567 | return; | 613 | if (qc->flags & ATA_QCFLAG_DMAMAP) |
614 | n_elem = ahci_fill_sg(qc); | ||
568 | 615 | ||
569 | n_elem = ahci_fill_sg(qc); | 616 | /* |
617 | * Fill in command slot information. | ||
618 | */ | ||
619 | opts = cmd_fis_len | n_elem << 16; | ||
620 | if (qc->tf.flags & ATA_TFLAG_WRITE) | ||
621 | opts |= AHCI_CMD_WRITE; | ||
622 | if (is_atapi) | ||
623 | opts |= AHCI_CMD_ATAPI; | ||
570 | 624 | ||
571 | pp->cmd_slot[0].opts |= cpu_to_le32(n_elem << 16); | 625 | ahci_fill_cmd_slot(ap, opts); |
572 | } | 626 | } |
573 | 627 | ||
574 | static void ahci_restart_port(struct ata_port *ap, u32 irq_stat) | 628 | static void ahci_restart_port(struct ata_port *ap, u32 irq_stat) |
@@ -576,7 +630,6 @@ static void ahci_restart_port(struct ata_port *ap, u32 irq_stat) | |||
576 | void __iomem *mmio = ap->host_set->mmio_base; | 630 | void __iomem *mmio = ap->host_set->mmio_base; |
577 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | 631 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); |
578 | u32 tmp; | 632 | u32 tmp; |
579 | int work; | ||
580 | 633 | ||
581 | if ((ap->device[0].class != ATA_DEV_ATAPI) || | 634 | if ((ap->device[0].class != ATA_DEV_ATAPI) || |
582 | ((irq_stat & PORT_IRQ_TF_ERR) == 0)) | 635 | ((irq_stat & PORT_IRQ_TF_ERR) == 0)) |
@@ -592,20 +645,7 @@ static void ahci_restart_port(struct ata_port *ap, u32 irq_stat) | |||
592 | readl(port_mmio + PORT_SCR_ERR)); | 645 | readl(port_mmio + PORT_SCR_ERR)); |
593 | 646 | ||
594 | /* stop DMA */ | 647 | /* stop DMA */ |
595 | tmp = readl(port_mmio + PORT_CMD); | 648 | ahci_stop_engine(ap); |
596 | tmp &= ~PORT_CMD_START; | ||
597 | writel(tmp, port_mmio + PORT_CMD); | ||
598 | |||
599 | /* wait for engine to stop. TODO: this could be | ||
600 | * as long as 500 msec | ||
601 | */ | ||
602 | work = 1000; | ||
603 | while (work-- > 0) { | ||
604 | tmp = readl(port_mmio + PORT_CMD); | ||
605 | if ((tmp & PORT_CMD_LIST_ON) == 0) | ||
606 | break; | ||
607 | udelay(10); | ||
608 | } | ||
609 | 649 | ||
610 | /* clear SATA phy error, if any */ | 650 | /* clear SATA phy error, if any */ |
611 | tmp = readl(port_mmio + PORT_SCR_ERR); | 651 | tmp = readl(port_mmio + PORT_SCR_ERR); |
@@ -624,10 +664,7 @@ static void ahci_restart_port(struct ata_port *ap, u32 irq_stat) | |||
624 | } | 664 | } |
625 | 665 | ||
626 | /* re-start DMA */ | 666 | /* re-start DMA */ |
627 | tmp = readl(port_mmio + PORT_CMD); | 667 | ahci_start_engine(ap); |
628 | tmp |= PORT_CMD_START; | ||
629 | writel(tmp, port_mmio + PORT_CMD); | ||
630 | readl(port_mmio + PORT_CMD); /* flush */ | ||
631 | } | 668 | } |
632 | 669 | ||
633 | static void ahci_eng_timeout(struct ata_port *ap) | 670 | static void ahci_eng_timeout(struct ata_port *ap) |
@@ -642,25 +679,13 @@ static void ahci_eng_timeout(struct ata_port *ap) | |||
642 | 679 | ||
643 | spin_lock_irqsave(&host_set->lock, flags); | 680 | spin_lock_irqsave(&host_set->lock, flags); |
644 | 681 | ||
682 | ahci_restart_port(ap, readl(port_mmio + PORT_IRQ_STAT)); | ||
645 | qc = ata_qc_from_tag(ap, ap->active_tag); | 683 | qc = ata_qc_from_tag(ap, ap->active_tag); |
646 | if (!qc) { | 684 | qc->err_mask |= AC_ERR_TIMEOUT; |
647 | printk(KERN_ERR "ata%u: BUG: timeout without command\n", | ||
648 | ap->id); | ||
649 | } else { | ||
650 | ahci_restart_port(ap, readl(port_mmio + PORT_IRQ_STAT)); | ||
651 | |||
652 | /* hack alert! We cannot use the supplied completion | ||
653 | * function from inside the ->eh_strategy_handler() thread. | ||
654 | * libata is the only user of ->eh_strategy_handler() in | ||
655 | * any kernel, so the default scsi_done() assumes it is | ||
656 | * not being called from the SCSI EH. | ||
657 | */ | ||
658 | qc->scsidone = scsi_finish_command; | ||
659 | qc->err_mask |= AC_ERR_OTHER; | ||
660 | ata_qc_complete(qc); | ||
661 | } | ||
662 | 685 | ||
663 | spin_unlock_irqrestore(&host_set->lock, flags); | 686 | spin_unlock_irqrestore(&host_set->lock, flags); |
687 | |||
688 | ata_eh_qc_complete(qc); | ||
664 | } | 689 | } |
665 | 690 | ||
666 | static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc) | 691 | static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc) |
@@ -697,7 +722,7 @@ static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc) | |||
697 | ahci_restart_port(ap, status); | 722 | ahci_restart_port(ap, status); |
698 | 723 | ||
699 | if (qc) { | 724 | if (qc) { |
700 | qc->err_mask |= AC_ERR_OTHER; | 725 | qc->err_mask |= err_mask; |
701 | ata_qc_complete(qc); | 726 | ata_qc_complete(qc); |
702 | } | 727 | } |
703 | } | 728 | } |
@@ -776,7 +801,7 @@ static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs * | |||
776 | return IRQ_RETVAL(handled); | 801 | return IRQ_RETVAL(handled); |
777 | } | 802 | } |
778 | 803 | ||
779 | static int ahci_qc_issue(struct ata_queued_cmd *qc) | 804 | static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc) |
780 | { | 805 | { |
781 | struct ata_port *ap = qc->ap; | 806 | struct ata_port *ap = qc->ap; |
782 | void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; | 807 | void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; |