diff options
Diffstat (limited to 'drivers/scsi/ahci.c')
-rw-r--r-- | drivers/scsi/ahci.c | 346 |
1 files changed, 210 insertions, 136 deletions
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index d23f00230a76..45fd71d80128 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c | |||
@@ -56,12 +56,15 @@ enum { | |||
56 | AHCI_MAX_SG = 168, /* hardware max is 64K */ | 56 | AHCI_MAX_SG = 168, /* hardware max is 64K */ |
57 | AHCI_DMA_BOUNDARY = 0xffffffff, | 57 | AHCI_DMA_BOUNDARY = 0xffffffff, |
58 | AHCI_USE_CLUSTERING = 0, | 58 | AHCI_USE_CLUSTERING = 0, |
59 | AHCI_CMD_SLOT_SZ = 32 * 32, | 59 | AHCI_MAX_CMDS = 32, |
60 | AHCI_CMD_SZ = 32, | ||
61 | AHCI_CMD_SLOT_SZ = AHCI_MAX_CMDS * AHCI_CMD_SZ, | ||
60 | AHCI_RX_FIS_SZ = 256, | 62 | AHCI_RX_FIS_SZ = 256, |
61 | AHCI_CMD_TBL_HDR = 0x80, | ||
62 | AHCI_CMD_TBL_CDB = 0x40, | 63 | AHCI_CMD_TBL_CDB = 0x40, |
63 | AHCI_CMD_TBL_SZ = AHCI_CMD_TBL_HDR + (AHCI_MAX_SG * 16), | 64 | AHCI_CMD_TBL_HDR_SZ = 0x80, |
64 | AHCI_PORT_PRIV_DMA_SZ = AHCI_CMD_SLOT_SZ + AHCI_CMD_TBL_SZ + | 65 | AHCI_CMD_TBL_SZ = AHCI_CMD_TBL_HDR_SZ + (AHCI_MAX_SG * 16), |
66 | AHCI_CMD_TBL_AR_SZ = AHCI_CMD_TBL_SZ * AHCI_MAX_CMDS, | ||
67 | AHCI_PORT_PRIV_DMA_SZ = AHCI_CMD_SLOT_SZ + AHCI_CMD_TBL_AR_SZ + | ||
65 | AHCI_RX_FIS_SZ, | 68 | AHCI_RX_FIS_SZ, |
66 | AHCI_IRQ_ON_SG = (1 << 31), | 69 | AHCI_IRQ_ON_SG = (1 << 31), |
67 | AHCI_CMD_ATAPI = (1 << 5), | 70 | AHCI_CMD_ATAPI = (1 << 5), |
@@ -71,6 +74,7 @@ enum { | |||
71 | AHCI_CMD_CLR_BUSY = (1 << 10), | 74 | AHCI_CMD_CLR_BUSY = (1 << 10), |
72 | 75 | ||
73 | RX_FIS_D2H_REG = 0x40, /* offset of D2H Register FIS data */ | 76 | RX_FIS_D2H_REG = 0x40, /* offset of D2H Register FIS data */ |
77 | RX_FIS_UNK = 0x60, /* offset of Unknown FIS data */ | ||
74 | 78 | ||
75 | board_ahci = 0, | 79 | board_ahci = 0, |
76 | board_ahci_vt8251 = 1, | 80 | board_ahci_vt8251 = 1, |
@@ -88,8 +92,9 @@ enum { | |||
88 | HOST_AHCI_EN = (1 << 31), /* AHCI enabled */ | 92 | HOST_AHCI_EN = (1 << 31), /* AHCI enabled */ |
89 | 93 | ||
90 | /* HOST_CAP bits */ | 94 | /* HOST_CAP bits */ |
91 | HOST_CAP_64 = (1 << 31), /* PCI DAC (64-bit DMA) support */ | ||
92 | HOST_CAP_CLO = (1 << 24), /* Command List Override support */ | 95 | HOST_CAP_CLO = (1 << 24), /* Command List Override support */ |
96 | HOST_CAP_NCQ = (1 << 30), /* Native Command Queueing */ | ||
97 | HOST_CAP_64 = (1 << 31), /* PCI DAC (64-bit DMA) support */ | ||
93 | 98 | ||
94 | /* registers for each SATA port */ | 99 | /* registers for each SATA port */ |
95 | PORT_LST_ADDR = 0x00, /* command list DMA addr */ | 100 | PORT_LST_ADDR = 0x00, /* command list DMA addr */ |
@@ -128,15 +133,16 @@ enum { | |||
128 | PORT_IRQ_PIOS_FIS = (1 << 1), /* PIO Setup FIS rx'd */ | 133 | PORT_IRQ_PIOS_FIS = (1 << 1), /* PIO Setup FIS rx'd */ |
129 | PORT_IRQ_D2H_REG_FIS = (1 << 0), /* D2H Register FIS rx'd */ | 134 | PORT_IRQ_D2H_REG_FIS = (1 << 0), /* D2H Register FIS rx'd */ |
130 | 135 | ||
131 | PORT_IRQ_FATAL = PORT_IRQ_TF_ERR | | 136 | PORT_IRQ_FREEZE = PORT_IRQ_HBUS_ERR | |
132 | PORT_IRQ_HBUS_ERR | | 137 | PORT_IRQ_IF_ERR | |
133 | PORT_IRQ_HBUS_DATA_ERR | | 138 | PORT_IRQ_CONNECT | |
134 | PORT_IRQ_IF_ERR, | 139 | PORT_IRQ_UNK_FIS, |
135 | DEF_PORT_IRQ = PORT_IRQ_FATAL | PORT_IRQ_PHYRDY | | 140 | PORT_IRQ_ERROR = PORT_IRQ_FREEZE | |
136 | PORT_IRQ_CONNECT | PORT_IRQ_SG_DONE | | 141 | PORT_IRQ_TF_ERR | |
137 | PORT_IRQ_UNK_FIS | PORT_IRQ_SDB_FIS | | 142 | PORT_IRQ_HBUS_DATA_ERR, |
138 | PORT_IRQ_DMAS_FIS | PORT_IRQ_PIOS_FIS | | 143 | DEF_PORT_IRQ = PORT_IRQ_ERROR | PORT_IRQ_SG_DONE | |
139 | PORT_IRQ_D2H_REG_FIS, | 144 | PORT_IRQ_SDB_FIS | PORT_IRQ_DMAS_FIS | |
145 | PORT_IRQ_PIOS_FIS | PORT_IRQ_D2H_REG_FIS, | ||
140 | 146 | ||
141 | /* PORT_CMD bits */ | 147 | /* PORT_CMD bits */ |
142 | PORT_CMD_ATAPI = (1 << 24), /* Device is ATAPI */ | 148 | PORT_CMD_ATAPI = (1 << 24), /* Device is ATAPI */ |
@@ -185,7 +191,6 @@ struct ahci_port_priv { | |||
185 | dma_addr_t cmd_slot_dma; | 191 | dma_addr_t cmd_slot_dma; |
186 | void *cmd_tbl; | 192 | void *cmd_tbl; |
187 | dma_addr_t cmd_tbl_dma; | 193 | dma_addr_t cmd_tbl_dma; |
188 | struct ahci_sg *cmd_tbl_sg; | ||
189 | void *rx_fis; | 194 | void *rx_fis; |
190 | dma_addr_t rx_fis_dma; | 195 | dma_addr_t rx_fis_dma; |
191 | }; | 196 | }; |
@@ -197,13 +202,15 @@ static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc); | |||
197 | static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *regs); | 202 | static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *regs); |
198 | static int ahci_probe_reset(struct ata_port *ap, unsigned int *classes); | 203 | static int ahci_probe_reset(struct ata_port *ap, unsigned int *classes); |
199 | static void ahci_irq_clear(struct ata_port *ap); | 204 | static void ahci_irq_clear(struct ata_port *ap); |
200 | static void ahci_eng_timeout(struct ata_port *ap); | ||
201 | static int ahci_port_start(struct ata_port *ap); | 205 | static int ahci_port_start(struct ata_port *ap); |
202 | static void ahci_port_stop(struct ata_port *ap); | 206 | static void ahci_port_stop(struct ata_port *ap); |
203 | static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf); | 207 | static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf); |
204 | static void ahci_qc_prep(struct ata_queued_cmd *qc); | 208 | static void ahci_qc_prep(struct ata_queued_cmd *qc); |
205 | static u8 ahci_check_status(struct ata_port *ap); | 209 | static u8 ahci_check_status(struct ata_port *ap); |
206 | static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc); | 210 | static void ahci_freeze(struct ata_port *ap); |
211 | static void ahci_thaw(struct ata_port *ap); | ||
212 | static void ahci_error_handler(struct ata_port *ap); | ||
213 | static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); | ||
207 | static void ahci_remove_one (struct pci_dev *pdev); | 214 | static void ahci_remove_one (struct pci_dev *pdev); |
208 | 215 | ||
209 | static struct scsi_host_template ahci_sht = { | 216 | static struct scsi_host_template ahci_sht = { |
@@ -211,7 +218,8 @@ static struct scsi_host_template ahci_sht = { | |||
211 | .name = DRV_NAME, | 218 | .name = DRV_NAME, |
212 | .ioctl = ata_scsi_ioctl, | 219 | .ioctl = ata_scsi_ioctl, |
213 | .queuecommand = ata_scsi_queuecmd, | 220 | .queuecommand = ata_scsi_queuecmd, |
214 | .can_queue = ATA_DEF_QUEUE, | 221 | .change_queue_depth = ata_scsi_change_queue_depth, |
222 | .can_queue = AHCI_MAX_CMDS - 1, | ||
215 | .this_id = ATA_SHT_THIS_ID, | 223 | .this_id = ATA_SHT_THIS_ID, |
216 | .sg_tablesize = AHCI_MAX_SG, | 224 | .sg_tablesize = AHCI_MAX_SG, |
217 | .cmd_per_lun = ATA_SHT_CMD_PER_LUN, | 225 | .cmd_per_lun = ATA_SHT_CMD_PER_LUN, |
@@ -237,14 +245,18 @@ static const struct ata_port_operations ahci_ops = { | |||
237 | .qc_prep = ahci_qc_prep, | 245 | .qc_prep = ahci_qc_prep, |
238 | .qc_issue = ahci_qc_issue, | 246 | .qc_issue = ahci_qc_issue, |
239 | 247 | ||
240 | .eng_timeout = ahci_eng_timeout, | ||
241 | |||
242 | .irq_handler = ahci_interrupt, | 248 | .irq_handler = ahci_interrupt, |
243 | .irq_clear = ahci_irq_clear, | 249 | .irq_clear = ahci_irq_clear, |
244 | 250 | ||
245 | .scr_read = ahci_scr_read, | 251 | .scr_read = ahci_scr_read, |
246 | .scr_write = ahci_scr_write, | 252 | .scr_write = ahci_scr_write, |
247 | 253 | ||
254 | .freeze = ahci_freeze, | ||
255 | .thaw = ahci_thaw, | ||
256 | |||
257 | .error_handler = ahci_error_handler, | ||
258 | .post_internal_cmd = ahci_post_internal_cmd, | ||
259 | |||
248 | .port_start = ahci_port_start, | 260 | .port_start = ahci_port_start, |
249 | .port_stop = ahci_port_stop, | 261 | .port_stop = ahci_port_stop, |
250 | }; | 262 | }; |
@@ -390,8 +402,6 @@ static int ahci_port_start(struct ata_port *ap) | |||
390 | pp->cmd_tbl = mem; | 402 | pp->cmd_tbl = mem; |
391 | pp->cmd_tbl_dma = mem_dma; | 403 | pp->cmd_tbl_dma = mem_dma; |
392 | 404 | ||
393 | pp->cmd_tbl_sg = mem + AHCI_CMD_TBL_HDR; | ||
394 | |||
395 | ap->private_data = pp; | 405 | ap->private_data = pp; |
396 | 406 | ||
397 | if (hpriv->cap & HOST_CAP_64) | 407 | if (hpriv->cap & HOST_CAP_64) |
@@ -524,12 +534,17 @@ static unsigned int ahci_dev_classify(struct ata_port *ap) | |||
524 | return ata_dev_classify(&tf); | 534 | return ata_dev_classify(&tf); |
525 | } | 535 | } |
526 | 536 | ||
527 | static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, u32 opts) | 537 | static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, |
538 | u32 opts) | ||
528 | { | 539 | { |
529 | pp->cmd_slot[0].opts = cpu_to_le32(opts); | 540 | dma_addr_t cmd_tbl_dma; |
530 | pp->cmd_slot[0].status = 0; | 541 | |
531 | pp->cmd_slot[0].tbl_addr = cpu_to_le32(pp->cmd_tbl_dma & 0xffffffff); | 542 | cmd_tbl_dma = pp->cmd_tbl_dma + tag * AHCI_CMD_TBL_SZ; |
532 | pp->cmd_slot[0].tbl_addr_hi = cpu_to_le32((pp->cmd_tbl_dma >> 16) >> 16); | 543 | |
544 | pp->cmd_slot[tag].opts = cpu_to_le32(opts); | ||
545 | pp->cmd_slot[tag].status = 0; | ||
546 | pp->cmd_slot[tag].tbl_addr = cpu_to_le32(cmd_tbl_dma & 0xffffffff); | ||
547 | pp->cmd_slot[tag].tbl_addr_hi = cpu_to_le32((cmd_tbl_dma >> 16) >> 16); | ||
533 | } | 548 | } |
534 | 549 | ||
535 | static int ahci_clo(struct ata_port *ap) | 550 | static int ahci_clo(struct ata_port *ap) |
@@ -567,7 +582,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class) | |||
567 | 582 | ||
568 | DPRINTK("ENTER\n"); | 583 | DPRINTK("ENTER\n"); |
569 | 584 | ||
570 | if (!sata_dev_present(ap)) { | 585 | if (ata_port_offline(ap)) { |
571 | DPRINTK("PHY reports no device\n"); | 586 | DPRINTK("PHY reports no device\n"); |
572 | *class = ATA_DEV_NONE; | 587 | *class = ATA_DEV_NONE; |
573 | return 0; | 588 | return 0; |
@@ -597,11 +612,12 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class) | |||
597 | /* restart engine */ | 612 | /* restart engine */ |
598 | ahci_start_engine(ap); | 613 | ahci_start_engine(ap); |
599 | 614 | ||
600 | ata_tf_init(ap, &tf, 0); | 615 | ata_tf_init(ap->device, &tf); |
601 | fis = pp->cmd_tbl; | 616 | fis = pp->cmd_tbl; |
602 | 617 | ||
603 | /* issue the first D2H Register FIS */ | 618 | /* issue the first D2H Register FIS */ |
604 | ahci_fill_cmd_slot(pp, cmd_fis_len | AHCI_CMD_RESET | AHCI_CMD_CLR_BUSY); | 619 | ahci_fill_cmd_slot(pp, 0, |
620 | cmd_fis_len | AHCI_CMD_RESET | AHCI_CMD_CLR_BUSY); | ||
605 | 621 | ||
606 | tf.ctl |= ATA_SRST; | 622 | tf.ctl |= ATA_SRST; |
607 | ata_tf_to_fis(&tf, fis, 0); | 623 | ata_tf_to_fis(&tf, fis, 0); |
@@ -620,7 +636,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class) | |||
620 | msleep(1); | 636 | msleep(1); |
621 | 637 | ||
622 | /* issue the second D2H Register FIS */ | 638 | /* issue the second D2H Register FIS */ |
623 | ahci_fill_cmd_slot(pp, cmd_fis_len); | 639 | ahci_fill_cmd_slot(pp, 0, cmd_fis_len); |
624 | 640 | ||
625 | tf.ctl &= ~ATA_SRST; | 641 | tf.ctl &= ~ATA_SRST; |
626 | ata_tf_to_fis(&tf, fis, 0); | 642 | ata_tf_to_fis(&tf, fis, 0); |
@@ -640,7 +656,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class) | |||
640 | msleep(150); | 656 | msleep(150); |
641 | 657 | ||
642 | *class = ATA_DEV_NONE; | 658 | *class = ATA_DEV_NONE; |
643 | if (sata_dev_present(ap)) { | 659 | if (ata_port_online(ap)) { |
644 | if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) { | 660 | if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) { |
645 | rc = -EIO; | 661 | rc = -EIO; |
646 | reason = "device not ready"; | 662 | reason = "device not ready"; |
@@ -655,8 +671,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class) | |||
655 | fail_restart: | 671 | fail_restart: |
656 | ahci_start_engine(ap); | 672 | ahci_start_engine(ap); |
657 | fail: | 673 | fail: |
658 | printk(KERN_ERR "ata%u: softreset failed (%s)\n", | 674 | ata_port_printk(ap, KERN_ERR, "softreset failed (%s)\n", reason); |
659 | ap->id, reason); | ||
660 | return rc; | 675 | return rc; |
661 | } | 676 | } |
662 | 677 | ||
@@ -670,7 +685,7 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class) | |||
670 | rc = sata_std_hardreset(ap, class); | 685 | rc = sata_std_hardreset(ap, class); |
671 | ahci_start_engine(ap); | 686 | ahci_start_engine(ap); |
672 | 687 | ||
673 | if (rc == 0) | 688 | if (rc == 0 && ata_port_online(ap)) |
674 | *class = ahci_dev_classify(ap); | 689 | *class = ahci_dev_classify(ap); |
675 | if (*class == ATA_DEV_UNKNOWN) | 690 | if (*class == ATA_DEV_UNKNOWN) |
676 | *class = ATA_DEV_NONE; | 691 | *class = ATA_DEV_NONE; |
@@ -726,9 +741,8 @@ static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf) | |||
726 | ata_tf_from_fis(d2h_fis, tf); | 741 | ata_tf_from_fis(d2h_fis, tf); |
727 | } | 742 | } |
728 | 743 | ||
729 | static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc) | 744 | static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl) |
730 | { | 745 | { |
731 | struct ahci_port_priv *pp = qc->ap->private_data; | ||
732 | struct scatterlist *sg; | 746 | struct scatterlist *sg; |
733 | struct ahci_sg *ahci_sg; | 747 | struct ahci_sg *ahci_sg; |
734 | unsigned int n_sg = 0; | 748 | unsigned int n_sg = 0; |
@@ -738,7 +752,7 @@ static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc) | |||
738 | /* | 752 | /* |
739 | * Next, the S/G list. | 753 | * Next, the S/G list. |
740 | */ | 754 | */ |
741 | ahci_sg = pp->cmd_tbl_sg; | 755 | ahci_sg = cmd_tbl + AHCI_CMD_TBL_HDR_SZ; |
742 | ata_for_each_sg(sg, qc) { | 756 | ata_for_each_sg(sg, qc) { |
743 | dma_addr_t addr = sg_dma_address(sg); | 757 | dma_addr_t addr = sg_dma_address(sg); |
744 | u32 sg_len = sg_dma_len(sg); | 758 | u32 sg_len = sg_dma_len(sg); |
@@ -759,6 +773,7 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc) | |||
759 | struct ata_port *ap = qc->ap; | 773 | struct ata_port *ap = qc->ap; |
760 | struct ahci_port_priv *pp = ap->private_data; | 774 | struct ahci_port_priv *pp = ap->private_data; |
761 | int is_atapi = is_atapi_taskfile(&qc->tf); | 775 | int is_atapi = is_atapi_taskfile(&qc->tf); |
776 | void *cmd_tbl; | ||
762 | u32 opts; | 777 | u32 opts; |
763 | const u32 cmd_fis_len = 5; /* five dwords */ | 778 | const u32 cmd_fis_len = 5; /* five dwords */ |
764 | unsigned int n_elem; | 779 | unsigned int n_elem; |
@@ -767,16 +782,17 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc) | |||
767 | * Fill in command table information. First, the header, | 782 | * Fill in command table information. First, the header, |
768 | * a SATA Register - Host to Device command FIS. | 783 | * a SATA Register - Host to Device command FIS. |
769 | */ | 784 | */ |
770 | ata_tf_to_fis(&qc->tf, pp->cmd_tbl, 0); | 785 | cmd_tbl = pp->cmd_tbl + qc->tag * AHCI_CMD_TBL_SZ; |
786 | |||
787 | ata_tf_to_fis(&qc->tf, cmd_tbl, 0); | ||
771 | if (is_atapi) { | 788 | if (is_atapi) { |
772 | memset(pp->cmd_tbl + AHCI_CMD_TBL_CDB, 0, 32); | 789 | memset(cmd_tbl + AHCI_CMD_TBL_CDB, 0, 32); |
773 | memcpy(pp->cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, | 790 | memcpy(cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, qc->dev->cdb_len); |
774 | qc->dev->cdb_len); | ||
775 | } | 791 | } |
776 | 792 | ||
777 | n_elem = 0; | 793 | n_elem = 0; |
778 | if (qc->flags & ATA_QCFLAG_DMAMAP) | 794 | if (qc->flags & ATA_QCFLAG_DMAMAP) |
779 | n_elem = ahci_fill_sg(qc); | 795 | n_elem = ahci_fill_sg(qc, cmd_tbl); |
780 | 796 | ||
781 | /* | 797 | /* |
782 | * Fill in command slot information. | 798 | * Fill in command slot information. |
@@ -787,112 +803,123 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc) | |||
787 | if (is_atapi) | 803 | if (is_atapi) |
788 | opts |= AHCI_CMD_ATAPI | AHCI_CMD_PREFETCH; | 804 | opts |= AHCI_CMD_ATAPI | AHCI_CMD_PREFETCH; |
789 | 805 | ||
790 | ahci_fill_cmd_slot(pp, opts); | 806 | ahci_fill_cmd_slot(pp, qc->tag, opts); |
791 | } | 807 | } |
792 | 808 | ||
793 | static void ahci_restart_port(struct ata_port *ap, u32 irq_stat) | 809 | static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) |
794 | { | 810 | { |
795 | void __iomem *mmio = ap->host_set->mmio_base; | 811 | struct ahci_port_priv *pp = ap->private_data; |
796 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | 812 | struct ata_eh_info *ehi = &ap->eh_info; |
797 | u32 tmp; | 813 | unsigned int err_mask = 0, action = 0; |
814 | struct ata_queued_cmd *qc; | ||
815 | u32 serror; | ||
798 | 816 | ||
799 | if ((ap->device[0].class != ATA_DEV_ATAPI) || | 817 | ata_ehi_clear_desc(ehi); |
800 | ((irq_stat & PORT_IRQ_TF_ERR) == 0)) | ||
801 | printk(KERN_WARNING "ata%u: port reset, " | ||
802 | "p_is %x is %x pis %x cmd %x tf %x ss %x se %x\n", | ||
803 | ap->id, | ||
804 | irq_stat, | ||
805 | readl(mmio + HOST_IRQ_STAT), | ||
806 | readl(port_mmio + PORT_IRQ_STAT), | ||
807 | readl(port_mmio + PORT_CMD), | ||
808 | readl(port_mmio + PORT_TFDATA), | ||
809 | readl(port_mmio + PORT_SCR_STAT), | ||
810 | readl(port_mmio + PORT_SCR_ERR)); | ||
811 | |||
812 | /* stop DMA */ | ||
813 | ahci_stop_engine(ap); | ||
814 | 818 | ||
815 | /* clear SATA phy error, if any */ | 819 | /* AHCI needs SError cleared; otherwise, it might lock up */ |
816 | tmp = readl(port_mmio + PORT_SCR_ERR); | 820 | serror = ahci_scr_read(ap, SCR_ERROR); |
817 | writel(tmp, port_mmio + PORT_SCR_ERR); | 821 | ahci_scr_write(ap, SCR_ERROR, serror); |
818 | 822 | ||
819 | /* if DRQ/BSY is set, device needs to be reset. | 823 | /* analyze @irq_stat */ |
820 | * if so, issue COMRESET | 824 | ata_ehi_push_desc(ehi, "irq_stat 0x%08x", irq_stat); |
821 | */ | 825 | |
822 | tmp = readl(port_mmio + PORT_TFDATA); | 826 | if (irq_stat & PORT_IRQ_TF_ERR) |
823 | if (tmp & (ATA_BUSY | ATA_DRQ)) { | 827 | err_mask |= AC_ERR_DEV; |
824 | writel(0x301, port_mmio + PORT_SCR_CTL); | 828 | |
825 | readl(port_mmio + PORT_SCR_CTL); /* flush */ | 829 | if (irq_stat & (PORT_IRQ_HBUS_ERR | PORT_IRQ_HBUS_DATA_ERR)) { |
826 | udelay(10); | 830 | err_mask |= AC_ERR_HOST_BUS; |
827 | writel(0x300, port_mmio + PORT_SCR_CTL); | 831 | action |= ATA_EH_SOFTRESET; |
828 | readl(port_mmio + PORT_SCR_CTL); /* flush */ | ||
829 | } | 832 | } |
830 | 833 | ||
831 | /* re-start DMA */ | 834 | if (irq_stat & PORT_IRQ_IF_ERR) { |
832 | ahci_start_engine(ap); | 835 | err_mask |= AC_ERR_ATA_BUS; |
833 | } | 836 | action |= ATA_EH_SOFTRESET; |
837 | ata_ehi_push_desc(ehi, ", interface fatal error"); | ||
838 | } | ||
834 | 839 | ||
835 | static void ahci_eng_timeout(struct ata_port *ap) | 840 | if (irq_stat & (PORT_IRQ_CONNECT | PORT_IRQ_PHYRDY)) { |
836 | { | 841 | err_mask |= AC_ERR_ATA_BUS; |
837 | struct ata_host_set *host_set = ap->host_set; | 842 | action |= ATA_EH_SOFTRESET; |
838 | void __iomem *mmio = host_set->mmio_base; | 843 | ata_ehi_push_desc(ehi, ", %s", irq_stat & PORT_IRQ_CONNECT ? |
839 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | 844 | "connection status changed" : "PHY RDY changed"); |
840 | struct ata_queued_cmd *qc; | 845 | } |
841 | unsigned long flags; | ||
842 | 846 | ||
843 | printk(KERN_WARNING "ata%u: handling error/timeout\n", ap->id); | 847 | if (irq_stat & PORT_IRQ_UNK_FIS) { |
848 | u32 *unk = (u32 *)(pp->rx_fis + RX_FIS_UNK); | ||
844 | 849 | ||
845 | spin_lock_irqsave(&host_set->lock, flags); | 850 | err_mask |= AC_ERR_HSM; |
851 | action |= ATA_EH_SOFTRESET; | ||
852 | ata_ehi_push_desc(ehi, ", unknown FIS %08x %08x %08x %08x", | ||
853 | unk[0], unk[1], unk[2], unk[3]); | ||
854 | } | ||
846 | 855 | ||
847 | ahci_restart_port(ap, readl(port_mmio + PORT_IRQ_STAT)); | 856 | /* okay, let's hand over to EH */ |
848 | qc = ata_qc_from_tag(ap, ap->active_tag); | 857 | ehi->serror |= serror; |
849 | qc->err_mask |= AC_ERR_TIMEOUT; | 858 | ehi->action |= action; |
850 | 859 | ||
851 | spin_unlock_irqrestore(&host_set->lock, flags); | 860 | qc = ata_qc_from_tag(ap, ap->active_tag); |
861 | if (qc) | ||
862 | qc->err_mask |= err_mask; | ||
863 | else | ||
864 | ehi->err_mask |= err_mask; | ||
852 | 865 | ||
853 | ata_eh_qc_complete(qc); | 866 | if (irq_stat & PORT_IRQ_FREEZE) |
867 | ata_port_freeze(ap); | ||
868 | else | ||
869 | ata_port_abort(ap); | ||
854 | } | 870 | } |
855 | 871 | ||
856 | static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc) | 872 | static void ahci_host_intr(struct ata_port *ap) |
857 | { | 873 | { |
858 | void __iomem *mmio = ap->host_set->mmio_base; | 874 | void __iomem *mmio = ap->host_set->mmio_base; |
859 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | 875 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); |
860 | u32 status, serr, ci; | 876 | struct ata_eh_info *ehi = &ap->eh_info; |
861 | 877 | u32 status, qc_active; | |
862 | serr = readl(port_mmio + PORT_SCR_ERR); | 878 | int rc; |
863 | writel(serr, port_mmio + PORT_SCR_ERR); | ||
864 | 879 | ||
865 | status = readl(port_mmio + PORT_IRQ_STAT); | 880 | status = readl(port_mmio + PORT_IRQ_STAT); |
866 | writel(status, port_mmio + PORT_IRQ_STAT); | 881 | writel(status, port_mmio + PORT_IRQ_STAT); |
867 | 882 | ||
868 | ci = readl(port_mmio + PORT_CMD_ISSUE); | 883 | if (unlikely(status & PORT_IRQ_ERROR)) { |
869 | if (likely((ci & 0x1) == 0)) { | 884 | ahci_error_intr(ap, status); |
870 | if (qc) { | 885 | return; |
871 | WARN_ON(qc->err_mask); | ||
872 | ata_qc_complete(qc); | ||
873 | qc = NULL; | ||
874 | } | ||
875 | } | 886 | } |
876 | 887 | ||
877 | if (status & PORT_IRQ_FATAL) { | 888 | if (ap->sactive) |
878 | unsigned int err_mask; | 889 | qc_active = readl(port_mmio + PORT_SCR_ACT); |
879 | if (status & PORT_IRQ_TF_ERR) | 890 | else |
880 | err_mask = AC_ERR_DEV; | 891 | qc_active = readl(port_mmio + PORT_CMD_ISSUE); |
881 | else if (status & PORT_IRQ_IF_ERR) | 892 | |
882 | err_mask = AC_ERR_ATA_BUS; | 893 | rc = ata_qc_complete_multiple(ap, qc_active, NULL); |
883 | else | 894 | if (rc > 0) |
884 | err_mask = AC_ERR_HOST_BUS; | 895 | return; |
885 | 896 | if (rc < 0) { | |
886 | /* command processing has stopped due to error; restart */ | 897 | ehi->err_mask |= AC_ERR_HSM; |
887 | ahci_restart_port(ap, status); | 898 | ehi->action |= ATA_EH_SOFTRESET; |
888 | 899 | ata_port_freeze(ap); | |
889 | if (qc) { | 900 | return; |
890 | qc->err_mask |= err_mask; | 901 | } |
891 | ata_qc_complete(qc); | 902 | |
892 | } | 903 | /* hmmm... a spurious interupt */ |
904 | |||
905 | /* some devices send D2H reg with I bit set during NCQ command phase */ | ||
906 | if (ap->sactive && status & PORT_IRQ_D2H_REG_FIS) | ||
907 | return; | ||
908 | |||
909 | /* ignore interim PIO setup fis interrupts */ | ||
910 | if (ata_tag_valid(ap->active_tag)) { | ||
911 | struct ata_queued_cmd *qc = | ||
912 | ata_qc_from_tag(ap, ap->active_tag); | ||
913 | |||
914 | if (qc && qc->tf.protocol == ATA_PROT_PIO && | ||
915 | (status & PORT_IRQ_PIOS_FIS)) | ||
916 | return; | ||
893 | } | 917 | } |
894 | 918 | ||
895 | return 1; | 919 | if (ata_ratelimit()) |
920 | ata_port_printk(ap, KERN_INFO, "spurious interrupt " | ||
921 | "(irq_stat 0x%x active_tag %d sactive 0x%x)\n", | ||
922 | status, ap->active_tag, ap->sactive); | ||
896 | } | 923 | } |
897 | 924 | ||
898 | static void ahci_irq_clear(struct ata_port *ap) | 925 | static void ahci_irq_clear(struct ata_port *ap) |
@@ -900,7 +927,7 @@ static void ahci_irq_clear(struct ata_port *ap) | |||
900 | /* TODO */ | 927 | /* TODO */ |
901 | } | 928 | } |
902 | 929 | ||
903 | static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *regs) | 930 | static irqreturn_t ahci_interrupt(int irq, void *dev_instance, struct pt_regs *regs) |
904 | { | 931 | { |
905 | struct ata_host_set *host_set = dev_instance; | 932 | struct ata_host_set *host_set = dev_instance; |
906 | struct ahci_host_priv *hpriv; | 933 | struct ahci_host_priv *hpriv; |
@@ -929,14 +956,7 @@ static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs * | |||
929 | 956 | ||
930 | ap = host_set->ports[i]; | 957 | ap = host_set->ports[i]; |
931 | if (ap) { | 958 | if (ap) { |
932 | struct ata_queued_cmd *qc; | 959 | ahci_host_intr(ap); |
933 | qc = ata_qc_from_tag(ap, ap->active_tag); | ||
934 | if (!ahci_host_intr(ap, qc)) | ||
935 | if (ata_ratelimit()) | ||
936 | dev_printk(KERN_WARNING, host_set->dev, | ||
937 | "unhandled interrupt on port %u\n", | ||
938 | i); | ||
939 | |||
940 | VPRINTK("port %u\n", i); | 960 | VPRINTK("port %u\n", i); |
941 | } else { | 961 | } else { |
942 | VPRINTK("port %u (no irq)\n", i); | 962 | VPRINTK("port %u (no irq)\n", i); |
@@ -953,7 +973,7 @@ static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs * | |||
953 | handled = 1; | 973 | handled = 1; |
954 | } | 974 | } |
955 | 975 | ||
956 | spin_unlock(&host_set->lock); | 976 | spin_unlock(&host_set->lock); |
957 | 977 | ||
958 | VPRINTK("EXIT\n"); | 978 | VPRINTK("EXIT\n"); |
959 | 979 | ||
@@ -965,12 +985,64 @@ static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc) | |||
965 | struct ata_port *ap = qc->ap; | 985 | struct ata_port *ap = qc->ap; |
966 | void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; | 986 | void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; |
967 | 987 | ||
968 | writel(1, port_mmio + PORT_CMD_ISSUE); | 988 | if (qc->tf.protocol == ATA_PROT_NCQ) |
989 | writel(1 << qc->tag, port_mmio + PORT_SCR_ACT); | ||
990 | writel(1 << qc->tag, port_mmio + PORT_CMD_ISSUE); | ||
969 | readl(port_mmio + PORT_CMD_ISSUE); /* flush */ | 991 | readl(port_mmio + PORT_CMD_ISSUE); /* flush */ |
970 | 992 | ||
971 | return 0; | 993 | return 0; |
972 | } | 994 | } |
973 | 995 | ||
996 | static void ahci_freeze(struct ata_port *ap) | ||
997 | { | ||
998 | void __iomem *mmio = ap->host_set->mmio_base; | ||
999 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | ||
1000 | |||
1001 | /* turn IRQ off */ | ||
1002 | writel(0, port_mmio + PORT_IRQ_MASK); | ||
1003 | } | ||
1004 | |||
1005 | static void ahci_thaw(struct ata_port *ap) | ||
1006 | { | ||
1007 | void __iomem *mmio = ap->host_set->mmio_base; | ||
1008 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | ||
1009 | u32 tmp; | ||
1010 | |||
1011 | /* clear IRQ */ | ||
1012 | tmp = readl(port_mmio + PORT_IRQ_STAT); | ||
1013 | writel(tmp, port_mmio + PORT_IRQ_STAT); | ||
1014 | writel(1 << ap->id, mmio + HOST_IRQ_STAT); | ||
1015 | |||
1016 | /* turn IRQ back on */ | ||
1017 | writel(DEF_PORT_IRQ, port_mmio + PORT_IRQ_MASK); | ||
1018 | } | ||
1019 | |||
1020 | static void ahci_error_handler(struct ata_port *ap) | ||
1021 | { | ||
1022 | if (!(ap->flags & ATA_FLAG_FROZEN)) { | ||
1023 | /* restart engine */ | ||
1024 | ahci_stop_engine(ap); | ||
1025 | ahci_start_engine(ap); | ||
1026 | } | ||
1027 | |||
1028 | /* perform recovery */ | ||
1029 | ata_do_eh(ap, ahci_softreset, ahci_hardreset, ahci_postreset); | ||
1030 | } | ||
1031 | |||
1032 | static void ahci_post_internal_cmd(struct ata_queued_cmd *qc) | ||
1033 | { | ||
1034 | struct ata_port *ap = qc->ap; | ||
1035 | |||
1036 | if (qc->flags & ATA_QCFLAG_FAILED) | ||
1037 | qc->err_mask |= AC_ERR_OTHER; | ||
1038 | |||
1039 | if (qc->err_mask) { | ||
1040 | /* make DMA engine forget about the failed command */ | ||
1041 | ahci_stop_engine(ap); | ||
1042 | ahci_start_engine(ap); | ||
1043 | } | ||
1044 | } | ||
1045 | |||
974 | static void ahci_setup_port(struct ata_ioports *port, unsigned long base, | 1046 | static void ahci_setup_port(struct ata_ioports *port, unsigned long base, |
975 | unsigned int port_idx) | 1047 | unsigned int port_idx) |
976 | { | 1048 | { |
@@ -1115,9 +1187,6 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent) | |||
1115 | writel(tmp, port_mmio + PORT_IRQ_STAT); | 1187 | writel(tmp, port_mmio + PORT_IRQ_STAT); |
1116 | 1188 | ||
1117 | writel(1 << i, mmio + HOST_IRQ_STAT); | 1189 | writel(1 << i, mmio + HOST_IRQ_STAT); |
1118 | |||
1119 | /* set irq mask (enables interrupts) */ | ||
1120 | writel(DEF_PORT_IRQ, port_mmio + PORT_IRQ_MASK); | ||
1121 | } | 1190 | } |
1122 | 1191 | ||
1123 | tmp = readl(mmio + HOST_CTL); | 1192 | tmp = readl(mmio + HOST_CTL); |
@@ -1215,6 +1284,8 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1215 | 1284 | ||
1216 | VPRINTK("ENTER\n"); | 1285 | VPRINTK("ENTER\n"); |
1217 | 1286 | ||
1287 | WARN_ON(ATA_MAX_QUEUE > AHCI_MAX_CMDS); | ||
1288 | |||
1218 | if (!printed_version++) | 1289 | if (!printed_version++) |
1219 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); | 1290 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); |
1220 | 1291 | ||
@@ -1282,6 +1353,9 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1282 | if (rc) | 1353 | if (rc) |
1283 | goto err_out_hpriv; | 1354 | goto err_out_hpriv; |
1284 | 1355 | ||
1356 | if (hpriv->cap & HOST_CAP_NCQ) | ||
1357 | probe_ent->host_flags |= ATA_FLAG_NCQ; | ||
1358 | |||
1285 | ahci_print_info(probe_ent); | 1359 | ahci_print_info(probe_ent); |
1286 | 1360 | ||
1287 | /* FIXME: check ata_device_add return value */ | 1361 | /* FIXME: check ata_device_add return value */ |