diff options
Diffstat (limited to 'drivers/scsi/ahci.c')
-rw-r--r-- | drivers/scsi/ahci.c | 477 |
1 files changed, 287 insertions, 190 deletions
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index b4f8fb1d628b..e261b37c2e48 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 { |
@@ -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,8 +74,10 @@ 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, |
80 | board_ahci_vt8251 = 1, | ||
76 | 81 | ||
77 | /* global controller registers */ | 82 | /* global controller registers */ |
78 | HOST_CAP = 0x00, /* host capabilities */ | 83 | HOST_CAP = 0x00, /* host capabilities */ |
@@ -87,8 +92,9 @@ enum { | |||
87 | HOST_AHCI_EN = (1 << 31), /* AHCI enabled */ | 92 | HOST_AHCI_EN = (1 << 31), /* AHCI enabled */ |
88 | 93 | ||
89 | /* HOST_CAP bits */ | 94 | /* HOST_CAP bits */ |
90 | HOST_CAP_64 = (1 << 31), /* PCI DAC (64-bit DMA) support */ | ||
91 | 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 */ | ||
92 | 98 | ||
93 | /* registers for each SATA port */ | 99 | /* registers for each SATA port */ |
94 | PORT_LST_ADDR = 0x00, /* command list DMA addr */ | 100 | PORT_LST_ADDR = 0x00, /* command list DMA addr */ |
@@ -127,15 +133,17 @@ enum { | |||
127 | PORT_IRQ_PIOS_FIS = (1 << 1), /* PIO Setup FIS rx'd */ | 133 | PORT_IRQ_PIOS_FIS = (1 << 1), /* PIO Setup FIS rx'd */ |
128 | 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 */ |
129 | 135 | ||
130 | PORT_IRQ_FATAL = PORT_IRQ_TF_ERR | | 136 | PORT_IRQ_FREEZE = PORT_IRQ_HBUS_ERR | |
131 | PORT_IRQ_HBUS_ERR | | 137 | PORT_IRQ_IF_ERR | |
132 | PORT_IRQ_HBUS_DATA_ERR | | 138 | PORT_IRQ_CONNECT | |
133 | PORT_IRQ_IF_ERR, | 139 | PORT_IRQ_PHYRDY | |
134 | DEF_PORT_IRQ = PORT_IRQ_FATAL | PORT_IRQ_PHYRDY | | 140 | PORT_IRQ_UNK_FIS, |
135 | PORT_IRQ_CONNECT | PORT_IRQ_SG_DONE | | 141 | PORT_IRQ_ERROR = PORT_IRQ_FREEZE | |
136 | PORT_IRQ_UNK_FIS | PORT_IRQ_SDB_FIS | | 142 | PORT_IRQ_TF_ERR | |
137 | PORT_IRQ_DMAS_FIS | PORT_IRQ_PIOS_FIS | | 143 | PORT_IRQ_HBUS_DATA_ERR, |
138 | PORT_IRQ_D2H_REG_FIS, | 144 | DEF_PORT_IRQ = PORT_IRQ_ERROR | PORT_IRQ_SG_DONE | |
145 | PORT_IRQ_SDB_FIS | PORT_IRQ_DMAS_FIS | | ||
146 | PORT_IRQ_PIOS_FIS | PORT_IRQ_D2H_REG_FIS, | ||
139 | 147 | ||
140 | /* PORT_CMD bits */ | 148 | /* PORT_CMD bits */ |
141 | PORT_CMD_ATAPI = (1 << 24), /* Device is ATAPI */ | 149 | PORT_CMD_ATAPI = (1 << 24), /* Device is ATAPI */ |
@@ -153,6 +161,9 @@ enum { | |||
153 | 161 | ||
154 | /* hpriv->flags bits */ | 162 | /* hpriv->flags bits */ |
155 | AHCI_FLAG_MSI = (1 << 0), | 163 | AHCI_FLAG_MSI = (1 << 0), |
164 | |||
165 | /* ap->flags bits */ | ||
166 | AHCI_FLAG_RESET_NEEDS_CLO = (1 << 24), | ||
156 | }; | 167 | }; |
157 | 168 | ||
158 | struct ahci_cmd_hdr { | 169 | struct ahci_cmd_hdr { |
@@ -181,7 +192,6 @@ struct ahci_port_priv { | |||
181 | dma_addr_t cmd_slot_dma; | 192 | dma_addr_t cmd_slot_dma; |
182 | void *cmd_tbl; | 193 | void *cmd_tbl; |
183 | dma_addr_t cmd_tbl_dma; | 194 | dma_addr_t cmd_tbl_dma; |
184 | struct ahci_sg *cmd_tbl_sg; | ||
185 | void *rx_fis; | 195 | void *rx_fis; |
186 | dma_addr_t rx_fis_dma; | 196 | dma_addr_t rx_fis_dma; |
187 | }; | 197 | }; |
@@ -191,15 +201,16 @@ static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); | |||
191 | static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); | 201 | static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); |
192 | static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc); | 202 | static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc); |
193 | static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *regs); | 203 | static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *regs); |
194 | static int ahci_probe_reset(struct ata_port *ap, unsigned int *classes); | ||
195 | static void ahci_irq_clear(struct ata_port *ap); | 204 | static void ahci_irq_clear(struct ata_port *ap); |
196 | static void ahci_eng_timeout(struct ata_port *ap); | ||
197 | static int ahci_port_start(struct ata_port *ap); | 205 | static int ahci_port_start(struct ata_port *ap); |
198 | static void ahci_port_stop(struct ata_port *ap); | 206 | static void ahci_port_stop(struct ata_port *ap); |
199 | 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); |
200 | static void ahci_qc_prep(struct ata_queued_cmd *qc); | 208 | static void ahci_qc_prep(struct ata_queued_cmd *qc); |
201 | static u8 ahci_check_status(struct ata_port *ap); | 209 | static u8 ahci_check_status(struct ata_port *ap); |
202 | 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); | ||
203 | static void ahci_remove_one (struct pci_dev *pdev); | 214 | static void ahci_remove_one (struct pci_dev *pdev); |
204 | 215 | ||
205 | static struct scsi_host_template ahci_sht = { | 216 | static struct scsi_host_template ahci_sht = { |
@@ -207,7 +218,8 @@ static struct scsi_host_template ahci_sht = { | |||
207 | .name = DRV_NAME, | 218 | .name = DRV_NAME, |
208 | .ioctl = ata_scsi_ioctl, | 219 | .ioctl = ata_scsi_ioctl, |
209 | .queuecommand = ata_scsi_queuecmd, | 220 | .queuecommand = ata_scsi_queuecmd, |
210 | .can_queue = ATA_DEF_QUEUE, | 221 | .change_queue_depth = ata_scsi_change_queue_depth, |
222 | .can_queue = AHCI_MAX_CMDS - 1, | ||
211 | .this_id = ATA_SHT_THIS_ID, | 223 | .this_id = ATA_SHT_THIS_ID, |
212 | .sg_tablesize = AHCI_MAX_SG, | 224 | .sg_tablesize = AHCI_MAX_SG, |
213 | .cmd_per_lun = ATA_SHT_CMD_PER_LUN, | 225 | .cmd_per_lun = ATA_SHT_CMD_PER_LUN, |
@@ -216,6 +228,7 @@ static struct scsi_host_template ahci_sht = { | |||
216 | .proc_name = DRV_NAME, | 228 | .proc_name = DRV_NAME, |
217 | .dma_boundary = AHCI_DMA_BOUNDARY, | 229 | .dma_boundary = AHCI_DMA_BOUNDARY, |
218 | .slave_configure = ata_scsi_slave_config, | 230 | .slave_configure = ata_scsi_slave_config, |
231 | .slave_destroy = ata_scsi_slave_destroy, | ||
219 | .bios_param = ata_std_bios_param, | 232 | .bios_param = ata_std_bios_param, |
220 | }; | 233 | }; |
221 | 234 | ||
@@ -228,19 +241,21 @@ static const struct ata_port_operations ahci_ops = { | |||
228 | 241 | ||
229 | .tf_read = ahci_tf_read, | 242 | .tf_read = ahci_tf_read, |
230 | 243 | ||
231 | .probe_reset = ahci_probe_reset, | ||
232 | |||
233 | .qc_prep = ahci_qc_prep, | 244 | .qc_prep = ahci_qc_prep, |
234 | .qc_issue = ahci_qc_issue, | 245 | .qc_issue = ahci_qc_issue, |
235 | 246 | ||
236 | .eng_timeout = ahci_eng_timeout, | ||
237 | |||
238 | .irq_handler = ahci_interrupt, | 247 | .irq_handler = ahci_interrupt, |
239 | .irq_clear = ahci_irq_clear, | 248 | .irq_clear = ahci_irq_clear, |
240 | 249 | ||
241 | .scr_read = ahci_scr_read, | 250 | .scr_read = ahci_scr_read, |
242 | .scr_write = ahci_scr_write, | 251 | .scr_write = ahci_scr_write, |
243 | 252 | ||
253 | .freeze = ahci_freeze, | ||
254 | .thaw = ahci_thaw, | ||
255 | |||
256 | .error_handler = ahci_error_handler, | ||
257 | .post_internal_cmd = ahci_post_internal_cmd, | ||
258 | |||
244 | .port_start = ahci_port_start, | 259 | .port_start = ahci_port_start, |
245 | .port_stop = ahci_port_stop, | 260 | .port_stop = ahci_port_stop, |
246 | }; | 261 | }; |
@@ -250,7 +265,19 @@ static const struct ata_port_info ahci_port_info[] = { | |||
250 | { | 265 | { |
251 | .sht = &ahci_sht, | 266 | .sht = &ahci_sht, |
252 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | 267 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | |
253 | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA, | 268 | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | |
269 | ATA_FLAG_SKIP_D2H_BSY, | ||
270 | .pio_mask = 0x1f, /* pio0-4 */ | ||
271 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ | ||
272 | .port_ops = &ahci_ops, | ||
273 | }, | ||
274 | /* board_ahci_vt8251 */ | ||
275 | { | ||
276 | .sht = &ahci_sht, | ||
277 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | ||
278 | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | | ||
279 | ATA_FLAG_SKIP_D2H_BSY | | ||
280 | AHCI_FLAG_RESET_NEEDS_CLO, | ||
254 | .pio_mask = 0x1f, /* pio0-4 */ | 281 | .pio_mask = 0x1f, /* pio0-4 */ |
255 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ | 282 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ |
256 | .port_ops = &ahci_ops, | 283 | .port_ops = &ahci_ops, |
@@ -296,6 +323,8 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
296 | board_ahci }, /* ATI SB600 non-raid */ | 323 | board_ahci }, /* ATI SB600 non-raid */ |
297 | { PCI_VENDOR_ID_ATI, 0x4381, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 324 | { PCI_VENDOR_ID_ATI, 0x4381, PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
298 | board_ahci }, /* ATI SB600 raid */ | 325 | board_ahci }, /* ATI SB600 raid */ |
326 | { PCI_VENDOR_ID_VIA, 0x3349, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
327 | board_ahci_vt8251 }, /* VIA VT8251 */ | ||
299 | { } /* terminate list */ | 328 | { } /* terminate list */ |
300 | }; | 329 | }; |
301 | 330 | ||
@@ -374,8 +403,6 @@ static int ahci_port_start(struct ata_port *ap) | |||
374 | pp->cmd_tbl = mem; | 403 | pp->cmd_tbl = mem; |
375 | pp->cmd_tbl_dma = mem_dma; | 404 | pp->cmd_tbl_dma = mem_dma; |
376 | 405 | ||
377 | pp->cmd_tbl_sg = mem + AHCI_CMD_TBL_HDR; | ||
378 | |||
379 | ap->private_data = pp; | 406 | ap->private_data = pp; |
380 | 407 | ||
381 | if (hpriv->cap & HOST_CAP_64) | 408 | if (hpriv->cap & HOST_CAP_64) |
@@ -508,46 +535,71 @@ static unsigned int ahci_dev_classify(struct ata_port *ap) | |||
508 | return ata_dev_classify(&tf); | 535 | return ata_dev_classify(&tf); |
509 | } | 536 | } |
510 | 537 | ||
511 | static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, u32 opts) | 538 | static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, |
539 | u32 opts) | ||
512 | { | 540 | { |
513 | pp->cmd_slot[0].opts = cpu_to_le32(opts); | 541 | dma_addr_t cmd_tbl_dma; |
514 | pp->cmd_slot[0].status = 0; | 542 | |
515 | pp->cmd_slot[0].tbl_addr = cpu_to_le32(pp->cmd_tbl_dma & 0xffffffff); | 543 | cmd_tbl_dma = pp->cmd_tbl_dma + tag * AHCI_CMD_TBL_SZ; |
516 | pp->cmd_slot[0].tbl_addr_hi = cpu_to_le32((pp->cmd_tbl_dma >> 16) >> 16); | 544 | |
545 | pp->cmd_slot[tag].opts = cpu_to_le32(opts); | ||
546 | pp->cmd_slot[tag].status = 0; | ||
547 | pp->cmd_slot[tag].tbl_addr = cpu_to_le32(cmd_tbl_dma & 0xffffffff); | ||
548 | pp->cmd_slot[tag].tbl_addr_hi = cpu_to_le32((cmd_tbl_dma >> 16) >> 16); | ||
517 | } | 549 | } |
518 | 550 | ||
519 | static int ahci_poll_register(void __iomem *reg, u32 mask, u32 val, | 551 | static int ahci_clo(struct ata_port *ap) |
520 | unsigned long interval_msec, | ||
521 | unsigned long timeout_msec) | ||
522 | { | 552 | { |
523 | unsigned long timeout; | 553 | void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; |
554 | struct ahci_host_priv *hpriv = ap->host_set->private_data; | ||
524 | u32 tmp; | 555 | u32 tmp; |
525 | 556 | ||
526 | timeout = jiffies + (timeout_msec * HZ) / 1000; | 557 | if (!(hpriv->cap & HOST_CAP_CLO)) |
527 | do { | 558 | return -EOPNOTSUPP; |
528 | tmp = readl(reg); | 559 | |
529 | if ((tmp & mask) == val) | 560 | tmp = readl(port_mmio + PORT_CMD); |
530 | return 0; | 561 | tmp |= PORT_CMD_CLO; |
531 | msleep(interval_msec); | 562 | writel(tmp, port_mmio + PORT_CMD); |
532 | } while (time_before(jiffies, timeout)); | 563 | |
564 | tmp = ata_wait_register(port_mmio + PORT_CMD, | ||
565 | PORT_CMD_CLO, PORT_CMD_CLO, 1, 500); | ||
566 | if (tmp & PORT_CMD_CLO) | ||
567 | return -EIO; | ||
533 | 568 | ||
534 | return -1; | 569 | return 0; |
535 | } | 570 | } |
536 | 571 | ||
537 | static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class) | 572 | static int ahci_prereset(struct ata_port *ap) |
573 | { | ||
574 | if ((ap->flags & AHCI_FLAG_RESET_NEEDS_CLO) && | ||
575 | (ata_busy_wait(ap, ATA_BUSY, 1000) & ATA_BUSY)) { | ||
576 | /* ATA_BUSY hasn't cleared, so send a CLO */ | ||
577 | ahci_clo(ap); | ||
578 | } | ||
579 | |||
580 | return ata_std_prereset(ap); | ||
581 | } | ||
582 | |||
583 | static int ahci_softreset(struct ata_port *ap, unsigned int *class) | ||
538 | { | 584 | { |
539 | struct ahci_host_priv *hpriv = ap->host_set->private_data; | ||
540 | struct ahci_port_priv *pp = ap->private_data; | 585 | struct ahci_port_priv *pp = ap->private_data; |
541 | void __iomem *mmio = ap->host_set->mmio_base; | 586 | void __iomem *mmio = ap->host_set->mmio_base; |
542 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | 587 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); |
543 | const u32 cmd_fis_len = 5; /* five dwords */ | 588 | const u32 cmd_fis_len = 5; /* five dwords */ |
544 | const char *reason = NULL; | 589 | const char *reason = NULL; |
545 | struct ata_taskfile tf; | 590 | struct ata_taskfile tf; |
591 | u32 tmp; | ||
546 | u8 *fis; | 592 | u8 *fis; |
547 | int rc; | 593 | int rc; |
548 | 594 | ||
549 | DPRINTK("ENTER\n"); | 595 | DPRINTK("ENTER\n"); |
550 | 596 | ||
597 | if (ata_port_offline(ap)) { | ||
598 | DPRINTK("PHY reports no device\n"); | ||
599 | *class = ATA_DEV_NONE; | ||
600 | return 0; | ||
601 | } | ||
602 | |||
551 | /* prepare for SRST (AHCI-1.1 10.4.1) */ | 603 | /* prepare for SRST (AHCI-1.1 10.4.1) */ |
552 | rc = ahci_stop_engine(ap); | 604 | rc = ahci_stop_engine(ap); |
553 | if (rc) { | 605 | if (rc) { |
@@ -558,23 +610,13 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class) | |||
558 | /* check BUSY/DRQ, perform Command List Override if necessary */ | 610 | /* check BUSY/DRQ, perform Command List Override if necessary */ |
559 | ahci_tf_read(ap, &tf); | 611 | ahci_tf_read(ap, &tf); |
560 | if (tf.command & (ATA_BUSY | ATA_DRQ)) { | 612 | if (tf.command & (ATA_BUSY | ATA_DRQ)) { |
561 | u32 tmp; | 613 | rc = ahci_clo(ap); |
562 | 614 | ||
563 | if (!(hpriv->cap & HOST_CAP_CLO)) { | 615 | if (rc == -EOPNOTSUPP) { |
564 | rc = -EIO; | 616 | reason = "port busy but CLO unavailable"; |
565 | reason = "port busy but no CLO"; | ||
566 | goto fail_restart; | 617 | goto fail_restart; |
567 | } | 618 | } else if (rc) { |
568 | 619 | reason = "port busy but CLO failed"; | |
569 | tmp = readl(port_mmio + PORT_CMD); | ||
570 | tmp |= PORT_CMD_CLO; | ||
571 | writel(tmp, port_mmio + PORT_CMD); | ||
572 | readl(port_mmio + PORT_CMD); /* flush */ | ||
573 | |||
574 | if (ahci_poll_register(port_mmio + PORT_CMD, PORT_CMD_CLO, 0x0, | ||
575 | 1, 500)) { | ||
576 | rc = -EIO; | ||
577 | reason = "CLO failed"; | ||
578 | goto fail_restart; | 620 | goto fail_restart; |
579 | } | 621 | } |
580 | } | 622 | } |
@@ -582,20 +624,21 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class) | |||
582 | /* restart engine */ | 624 | /* restart engine */ |
583 | ahci_start_engine(ap); | 625 | ahci_start_engine(ap); |
584 | 626 | ||
585 | ata_tf_init(ap, &tf, 0); | 627 | ata_tf_init(ap->device, &tf); |
586 | fis = pp->cmd_tbl; | 628 | fis = pp->cmd_tbl; |
587 | 629 | ||
588 | /* issue the first D2H Register FIS */ | 630 | /* issue the first D2H Register FIS */ |
589 | ahci_fill_cmd_slot(pp, cmd_fis_len | AHCI_CMD_RESET | AHCI_CMD_CLR_BUSY); | 631 | ahci_fill_cmd_slot(pp, 0, |
632 | cmd_fis_len | AHCI_CMD_RESET | AHCI_CMD_CLR_BUSY); | ||
590 | 633 | ||
591 | tf.ctl |= ATA_SRST; | 634 | tf.ctl |= ATA_SRST; |
592 | ata_tf_to_fis(&tf, fis, 0); | 635 | ata_tf_to_fis(&tf, fis, 0); |
593 | fis[1] &= ~(1 << 7); /* turn off Command FIS bit */ | 636 | fis[1] &= ~(1 << 7); /* turn off Command FIS bit */ |
594 | 637 | ||
595 | writel(1, port_mmio + PORT_CMD_ISSUE); | 638 | writel(1, port_mmio + PORT_CMD_ISSUE); |
596 | readl(port_mmio + PORT_CMD_ISSUE); /* flush */ | ||
597 | 639 | ||
598 | if (ahci_poll_register(port_mmio + PORT_CMD_ISSUE, 0x1, 0x0, 1, 500)) { | 640 | tmp = ata_wait_register(port_mmio + PORT_CMD_ISSUE, 0x1, 0x1, 1, 500); |
641 | if (tmp & 0x1) { | ||
599 | rc = -EIO; | 642 | rc = -EIO; |
600 | reason = "1st FIS failed"; | 643 | reason = "1st FIS failed"; |
601 | goto fail; | 644 | goto fail; |
@@ -605,7 +648,7 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class) | |||
605 | msleep(1); | 648 | msleep(1); |
606 | 649 | ||
607 | /* issue the second D2H Register FIS */ | 650 | /* issue the second D2H Register FIS */ |
608 | ahci_fill_cmd_slot(pp, cmd_fis_len); | 651 | ahci_fill_cmd_slot(pp, 0, cmd_fis_len); |
609 | 652 | ||
610 | tf.ctl &= ~ATA_SRST; | 653 | tf.ctl &= ~ATA_SRST; |
611 | ata_tf_to_fis(&tf, fis, 0); | 654 | ata_tf_to_fis(&tf, fis, 0); |
@@ -625,7 +668,7 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class) | |||
625 | msleep(150); | 668 | msleep(150); |
626 | 669 | ||
627 | *class = ATA_DEV_NONE; | 670 | *class = ATA_DEV_NONE; |
628 | if (sata_dev_present(ap)) { | 671 | if (ata_port_online(ap)) { |
629 | if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) { | 672 | if (ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT)) { |
630 | rc = -EIO; | 673 | rc = -EIO; |
631 | reason = "device not ready"; | 674 | reason = "device not ready"; |
@@ -640,25 +683,31 @@ static int ahci_softreset(struct ata_port *ap, int verbose, unsigned int *class) | |||
640 | fail_restart: | 683 | fail_restart: |
641 | ahci_start_engine(ap); | 684 | ahci_start_engine(ap); |
642 | fail: | 685 | fail: |
643 | if (verbose) | 686 | ata_port_printk(ap, KERN_ERR, "softreset failed (%s)\n", reason); |
644 | printk(KERN_ERR "ata%u: softreset failed (%s)\n", | ||
645 | ap->id, reason); | ||
646 | else | ||
647 | DPRINTK("EXIT, rc=%d reason=\"%s\"\n", rc, reason); | ||
648 | return rc; | 687 | return rc; |
649 | } | 688 | } |
650 | 689 | ||
651 | static int ahci_hardreset(struct ata_port *ap, int verbose, unsigned int *class) | 690 | static int ahci_hardreset(struct ata_port *ap, unsigned int *class) |
652 | { | 691 | { |
692 | struct ahci_port_priv *pp = ap->private_data; | ||
693 | u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; | ||
694 | struct ata_taskfile tf; | ||
653 | int rc; | 695 | int rc; |
654 | 696 | ||
655 | DPRINTK("ENTER\n"); | 697 | DPRINTK("ENTER\n"); |
656 | 698 | ||
657 | ahci_stop_engine(ap); | 699 | ahci_stop_engine(ap); |
658 | rc = sata_std_hardreset(ap, verbose, class); | 700 | |
701 | /* clear D2H reception area to properly wait for D2H FIS */ | ||
702 | ata_tf_init(ap->device, &tf); | ||
703 | tf.command = 0xff; | ||
704 | ata_tf_to_fis(&tf, d2h_fis, 0); | ||
705 | |||
706 | rc = sata_std_hardreset(ap, class); | ||
707 | |||
659 | ahci_start_engine(ap); | 708 | ahci_start_engine(ap); |
660 | 709 | ||
661 | if (rc == 0) | 710 | if (rc == 0 && ata_port_online(ap)) |
662 | *class = ahci_dev_classify(ap); | 711 | *class = ahci_dev_classify(ap); |
663 | if (*class == ATA_DEV_UNKNOWN) | 712 | if (*class == ATA_DEV_UNKNOWN) |
664 | *class = ATA_DEV_NONE; | 713 | *class = ATA_DEV_NONE; |
@@ -686,13 +735,6 @@ static void ahci_postreset(struct ata_port *ap, unsigned int *class) | |||
686 | } | 735 | } |
687 | } | 736 | } |
688 | 737 | ||
689 | static int ahci_probe_reset(struct ata_port *ap, unsigned int *classes) | ||
690 | { | ||
691 | return ata_drive_probe_reset(ap, ata_std_probeinit, | ||
692 | ahci_softreset, ahci_hardreset, | ||
693 | ahci_postreset, classes); | ||
694 | } | ||
695 | |||
696 | static u8 ahci_check_status(struct ata_port *ap) | 738 | static u8 ahci_check_status(struct ata_port *ap) |
697 | { | 739 | { |
698 | void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr; | 740 | void __iomem *mmio = (void __iomem *) ap->ioaddr.cmd_addr; |
@@ -708,9 +750,8 @@ static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf) | |||
708 | ata_tf_from_fis(d2h_fis, tf); | 750 | ata_tf_from_fis(d2h_fis, tf); |
709 | } | 751 | } |
710 | 752 | ||
711 | static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc) | 753 | static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl) |
712 | { | 754 | { |
713 | struct ahci_port_priv *pp = qc->ap->private_data; | ||
714 | struct scatterlist *sg; | 755 | struct scatterlist *sg; |
715 | struct ahci_sg *ahci_sg; | 756 | struct ahci_sg *ahci_sg; |
716 | unsigned int n_sg = 0; | 757 | unsigned int n_sg = 0; |
@@ -720,7 +761,7 @@ static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc) | |||
720 | /* | 761 | /* |
721 | * Next, the S/G list. | 762 | * Next, the S/G list. |
722 | */ | 763 | */ |
723 | ahci_sg = pp->cmd_tbl_sg; | 764 | ahci_sg = cmd_tbl + AHCI_CMD_TBL_HDR_SZ; |
724 | ata_for_each_sg(sg, qc) { | 765 | ata_for_each_sg(sg, qc) { |
725 | dma_addr_t addr = sg_dma_address(sg); | 766 | dma_addr_t addr = sg_dma_address(sg); |
726 | u32 sg_len = sg_dma_len(sg); | 767 | u32 sg_len = sg_dma_len(sg); |
@@ -741,6 +782,7 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc) | |||
741 | struct ata_port *ap = qc->ap; | 782 | struct ata_port *ap = qc->ap; |
742 | struct ahci_port_priv *pp = ap->private_data; | 783 | struct ahci_port_priv *pp = ap->private_data; |
743 | int is_atapi = is_atapi_taskfile(&qc->tf); | 784 | int is_atapi = is_atapi_taskfile(&qc->tf); |
785 | void *cmd_tbl; | ||
744 | u32 opts; | 786 | u32 opts; |
745 | const u32 cmd_fis_len = 5; /* five dwords */ | 787 | const u32 cmd_fis_len = 5; /* five dwords */ |
746 | unsigned int n_elem; | 788 | unsigned int n_elem; |
@@ -749,16 +791,17 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc) | |||
749 | * Fill in command table information. First, the header, | 791 | * Fill in command table information. First, the header, |
750 | * a SATA Register - Host to Device command FIS. | 792 | * a SATA Register - Host to Device command FIS. |
751 | */ | 793 | */ |
752 | ata_tf_to_fis(&qc->tf, pp->cmd_tbl, 0); | 794 | cmd_tbl = pp->cmd_tbl + qc->tag * AHCI_CMD_TBL_SZ; |
795 | |||
796 | ata_tf_to_fis(&qc->tf, cmd_tbl, 0); | ||
753 | if (is_atapi) { | 797 | if (is_atapi) { |
754 | memset(pp->cmd_tbl + AHCI_CMD_TBL_CDB, 0, 32); | 798 | memset(cmd_tbl + AHCI_CMD_TBL_CDB, 0, 32); |
755 | memcpy(pp->cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, | 799 | memcpy(cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, qc->dev->cdb_len); |
756 | qc->dev->cdb_len); | ||
757 | } | 800 | } |
758 | 801 | ||
759 | n_elem = 0; | 802 | n_elem = 0; |
760 | if (qc->flags & ATA_QCFLAG_DMAMAP) | 803 | if (qc->flags & ATA_QCFLAG_DMAMAP) |
761 | n_elem = ahci_fill_sg(qc); | 804 | n_elem = ahci_fill_sg(qc, cmd_tbl); |
762 | 805 | ||
763 | /* | 806 | /* |
764 | * Fill in command slot information. | 807 | * Fill in command slot information. |
@@ -769,112 +812,122 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc) | |||
769 | if (is_atapi) | 812 | if (is_atapi) |
770 | opts |= AHCI_CMD_ATAPI | AHCI_CMD_PREFETCH; | 813 | opts |= AHCI_CMD_ATAPI | AHCI_CMD_PREFETCH; |
771 | 814 | ||
772 | ahci_fill_cmd_slot(pp, opts); | 815 | ahci_fill_cmd_slot(pp, qc->tag, opts); |
773 | } | 816 | } |
774 | 817 | ||
775 | static void ahci_restart_port(struct ata_port *ap, u32 irq_stat) | 818 | static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) |
776 | { | 819 | { |
777 | void __iomem *mmio = ap->host_set->mmio_base; | 820 | struct ahci_port_priv *pp = ap->private_data; |
778 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | 821 | struct ata_eh_info *ehi = &ap->eh_info; |
779 | u32 tmp; | 822 | unsigned int err_mask = 0, action = 0; |
823 | struct ata_queued_cmd *qc; | ||
824 | u32 serror; | ||
780 | 825 | ||
781 | if ((ap->device[0].class != ATA_DEV_ATAPI) || | 826 | ata_ehi_clear_desc(ehi); |
782 | ((irq_stat & PORT_IRQ_TF_ERR) == 0)) | ||
783 | printk(KERN_WARNING "ata%u: port reset, " | ||
784 | "p_is %x is %x pis %x cmd %x tf %x ss %x se %x\n", | ||
785 | ap->id, | ||
786 | irq_stat, | ||
787 | readl(mmio + HOST_IRQ_STAT), | ||
788 | readl(port_mmio + PORT_IRQ_STAT), | ||
789 | readl(port_mmio + PORT_CMD), | ||
790 | readl(port_mmio + PORT_TFDATA), | ||
791 | readl(port_mmio + PORT_SCR_STAT), | ||
792 | readl(port_mmio + PORT_SCR_ERR)); | ||
793 | |||
794 | /* stop DMA */ | ||
795 | ahci_stop_engine(ap); | ||
796 | 827 | ||
797 | /* clear SATA phy error, if any */ | 828 | /* AHCI needs SError cleared; otherwise, it might lock up */ |
798 | tmp = readl(port_mmio + PORT_SCR_ERR); | 829 | serror = ahci_scr_read(ap, SCR_ERROR); |
799 | writel(tmp, port_mmio + PORT_SCR_ERR); | 830 | ahci_scr_write(ap, SCR_ERROR, serror); |
800 | 831 | ||
801 | /* if DRQ/BSY is set, device needs to be reset. | 832 | /* analyze @irq_stat */ |
802 | * if so, issue COMRESET | 833 | ata_ehi_push_desc(ehi, "irq_stat 0x%08x", irq_stat); |
803 | */ | 834 | |
804 | tmp = readl(port_mmio + PORT_TFDATA); | 835 | if (irq_stat & PORT_IRQ_TF_ERR) |
805 | if (tmp & (ATA_BUSY | ATA_DRQ)) { | 836 | err_mask |= AC_ERR_DEV; |
806 | writel(0x301, port_mmio + PORT_SCR_CTL); | 837 | |
807 | readl(port_mmio + PORT_SCR_CTL); /* flush */ | 838 | if (irq_stat & (PORT_IRQ_HBUS_ERR | PORT_IRQ_HBUS_DATA_ERR)) { |
808 | udelay(10); | 839 | err_mask |= AC_ERR_HOST_BUS; |
809 | writel(0x300, port_mmio + PORT_SCR_CTL); | 840 | action |= ATA_EH_SOFTRESET; |
810 | readl(port_mmio + PORT_SCR_CTL); /* flush */ | ||
811 | } | 841 | } |
812 | 842 | ||
813 | /* re-start DMA */ | 843 | if (irq_stat & PORT_IRQ_IF_ERR) { |
814 | ahci_start_engine(ap); | 844 | err_mask |= AC_ERR_ATA_BUS; |
815 | } | 845 | action |= ATA_EH_SOFTRESET; |
846 | ata_ehi_push_desc(ehi, ", interface fatal error"); | ||
847 | } | ||
816 | 848 | ||
817 | static void ahci_eng_timeout(struct ata_port *ap) | 849 | if (irq_stat & (PORT_IRQ_CONNECT | PORT_IRQ_PHYRDY)) { |
818 | { | 850 | ata_ehi_hotplugged(ehi); |
819 | struct ata_host_set *host_set = ap->host_set; | 851 | ata_ehi_push_desc(ehi, ", %s", irq_stat & PORT_IRQ_CONNECT ? |
820 | void __iomem *mmio = host_set->mmio_base; | 852 | "connection status changed" : "PHY RDY changed"); |
821 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | 853 | } |
822 | struct ata_queued_cmd *qc; | ||
823 | unsigned long flags; | ||
824 | 854 | ||
825 | printk(KERN_WARNING "ata%u: handling error/timeout\n", ap->id); | 855 | if (irq_stat & PORT_IRQ_UNK_FIS) { |
856 | u32 *unk = (u32 *)(pp->rx_fis + RX_FIS_UNK); | ||
826 | 857 | ||
827 | spin_lock_irqsave(&host_set->lock, flags); | 858 | err_mask |= AC_ERR_HSM; |
859 | action |= ATA_EH_SOFTRESET; | ||
860 | ata_ehi_push_desc(ehi, ", unknown FIS %08x %08x %08x %08x", | ||
861 | unk[0], unk[1], unk[2], unk[3]); | ||
862 | } | ||
828 | 863 | ||
829 | ahci_restart_port(ap, readl(port_mmio + PORT_IRQ_STAT)); | 864 | /* okay, let's hand over to EH */ |
830 | qc = ata_qc_from_tag(ap, ap->active_tag); | 865 | ehi->serror |= serror; |
831 | qc->err_mask |= AC_ERR_TIMEOUT; | 866 | ehi->action |= action; |
832 | 867 | ||
833 | spin_unlock_irqrestore(&host_set->lock, flags); | 868 | qc = ata_qc_from_tag(ap, ap->active_tag); |
869 | if (qc) | ||
870 | qc->err_mask |= err_mask; | ||
871 | else | ||
872 | ehi->err_mask |= err_mask; | ||
834 | 873 | ||
835 | ata_eh_qc_complete(qc); | 874 | if (irq_stat & PORT_IRQ_FREEZE) |
875 | ata_port_freeze(ap); | ||
876 | else | ||
877 | ata_port_abort(ap); | ||
836 | } | 878 | } |
837 | 879 | ||
838 | static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc) | 880 | static void ahci_host_intr(struct ata_port *ap) |
839 | { | 881 | { |
840 | void __iomem *mmio = ap->host_set->mmio_base; | 882 | void __iomem *mmio = ap->host_set->mmio_base; |
841 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | 883 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); |
842 | u32 status, serr, ci; | 884 | struct ata_eh_info *ehi = &ap->eh_info; |
843 | 885 | u32 status, qc_active; | |
844 | serr = readl(port_mmio + PORT_SCR_ERR); | 886 | int rc; |
845 | writel(serr, port_mmio + PORT_SCR_ERR); | ||
846 | 887 | ||
847 | status = readl(port_mmio + PORT_IRQ_STAT); | 888 | status = readl(port_mmio + PORT_IRQ_STAT); |
848 | writel(status, port_mmio + PORT_IRQ_STAT); | 889 | writel(status, port_mmio + PORT_IRQ_STAT); |
849 | 890 | ||
850 | ci = readl(port_mmio + PORT_CMD_ISSUE); | 891 | if (unlikely(status & PORT_IRQ_ERROR)) { |
851 | if (likely((ci & 0x1) == 0)) { | 892 | ahci_error_intr(ap, status); |
852 | if (qc) { | 893 | return; |
853 | WARN_ON(qc->err_mask); | ||
854 | ata_qc_complete(qc); | ||
855 | qc = NULL; | ||
856 | } | ||
857 | } | 894 | } |
858 | 895 | ||
859 | if (status & PORT_IRQ_FATAL) { | 896 | if (ap->sactive) |
860 | unsigned int err_mask; | 897 | qc_active = readl(port_mmio + PORT_SCR_ACT); |
861 | if (status & PORT_IRQ_TF_ERR) | 898 | else |
862 | err_mask = AC_ERR_DEV; | 899 | qc_active = readl(port_mmio + PORT_CMD_ISSUE); |
863 | else if (status & PORT_IRQ_IF_ERR) | 900 | |
864 | err_mask = AC_ERR_ATA_BUS; | 901 | rc = ata_qc_complete_multiple(ap, qc_active, NULL); |
865 | else | 902 | if (rc > 0) |
866 | err_mask = AC_ERR_HOST_BUS; | 903 | return; |
867 | 904 | if (rc < 0) { | |
868 | /* command processing has stopped due to error; restart */ | 905 | ehi->err_mask |= AC_ERR_HSM; |
869 | ahci_restart_port(ap, status); | 906 | ehi->action |= ATA_EH_SOFTRESET; |
870 | 907 | ata_port_freeze(ap); | |
871 | if (qc) { | 908 | return; |
872 | qc->err_mask |= err_mask; | 909 | } |
873 | ata_qc_complete(qc); | 910 | |
874 | } | 911 | /* hmmm... a spurious interupt */ |
912 | |||
913 | /* some devices send D2H reg with I bit set during NCQ command phase */ | ||
914 | if (ap->sactive && status & PORT_IRQ_D2H_REG_FIS) | ||
915 | return; | ||
916 | |||
917 | /* ignore interim PIO setup fis interrupts */ | ||
918 | if (ata_tag_valid(ap->active_tag)) { | ||
919 | struct ata_queued_cmd *qc = | ||
920 | ata_qc_from_tag(ap, ap->active_tag); | ||
921 | |||
922 | if (qc && qc->tf.protocol == ATA_PROT_PIO && | ||
923 | (status & PORT_IRQ_PIOS_FIS)) | ||
924 | return; | ||
875 | } | 925 | } |
876 | 926 | ||
877 | return 1; | 927 | if (ata_ratelimit()) |
928 | ata_port_printk(ap, KERN_INFO, "spurious interrupt " | ||
929 | "(irq_stat 0x%x active_tag %d sactive 0x%x)\n", | ||
930 | status, ap->active_tag, ap->sactive); | ||
878 | } | 931 | } |
879 | 932 | ||
880 | static void ahci_irq_clear(struct ata_port *ap) | 933 | static void ahci_irq_clear(struct ata_port *ap) |
@@ -882,7 +935,7 @@ static void ahci_irq_clear(struct ata_port *ap) | |||
882 | /* TODO */ | 935 | /* TODO */ |
883 | } | 936 | } |
884 | 937 | ||
885 | static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs *regs) | 938 | static irqreturn_t ahci_interrupt(int irq, void *dev_instance, struct pt_regs *regs) |
886 | { | 939 | { |
887 | struct ata_host_set *host_set = dev_instance; | 940 | struct ata_host_set *host_set = dev_instance; |
888 | struct ahci_host_priv *hpriv; | 941 | struct ahci_host_priv *hpriv; |
@@ -911,14 +964,7 @@ static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs * | |||
911 | 964 | ||
912 | ap = host_set->ports[i]; | 965 | ap = host_set->ports[i]; |
913 | if (ap) { | 966 | if (ap) { |
914 | struct ata_queued_cmd *qc; | 967 | ahci_host_intr(ap); |
915 | qc = ata_qc_from_tag(ap, ap->active_tag); | ||
916 | if (!ahci_host_intr(ap, qc)) | ||
917 | if (ata_ratelimit()) | ||
918 | dev_printk(KERN_WARNING, host_set->dev, | ||
919 | "unhandled interrupt on port %u\n", | ||
920 | i); | ||
921 | |||
922 | VPRINTK("port %u\n", i); | 968 | VPRINTK("port %u\n", i); |
923 | } else { | 969 | } else { |
924 | VPRINTK("port %u (no irq)\n", i); | 970 | VPRINTK("port %u (no irq)\n", i); |
@@ -935,7 +981,7 @@ static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs * | |||
935 | handled = 1; | 981 | handled = 1; |
936 | } | 982 | } |
937 | 983 | ||
938 | spin_unlock(&host_set->lock); | 984 | spin_unlock(&host_set->lock); |
939 | 985 | ||
940 | VPRINTK("EXIT\n"); | 986 | VPRINTK("EXIT\n"); |
941 | 987 | ||
@@ -947,12 +993,65 @@ static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc) | |||
947 | struct ata_port *ap = qc->ap; | 993 | struct ata_port *ap = qc->ap; |
948 | void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; | 994 | void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; |
949 | 995 | ||
950 | writel(1, port_mmio + PORT_CMD_ISSUE); | 996 | if (qc->tf.protocol == ATA_PROT_NCQ) |
997 | writel(1 << qc->tag, port_mmio + PORT_SCR_ACT); | ||
998 | writel(1 << qc->tag, port_mmio + PORT_CMD_ISSUE); | ||
951 | readl(port_mmio + PORT_CMD_ISSUE); /* flush */ | 999 | readl(port_mmio + PORT_CMD_ISSUE); /* flush */ |
952 | 1000 | ||
953 | return 0; | 1001 | return 0; |
954 | } | 1002 | } |
955 | 1003 | ||
1004 | static void ahci_freeze(struct ata_port *ap) | ||
1005 | { | ||
1006 | void __iomem *mmio = ap->host_set->mmio_base; | ||
1007 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | ||
1008 | |||
1009 | /* turn IRQ off */ | ||
1010 | writel(0, port_mmio + PORT_IRQ_MASK); | ||
1011 | } | ||
1012 | |||
1013 | static void ahci_thaw(struct ata_port *ap) | ||
1014 | { | ||
1015 | void __iomem *mmio = ap->host_set->mmio_base; | ||
1016 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | ||
1017 | u32 tmp; | ||
1018 | |||
1019 | /* clear IRQ */ | ||
1020 | tmp = readl(port_mmio + PORT_IRQ_STAT); | ||
1021 | writel(tmp, port_mmio + PORT_IRQ_STAT); | ||
1022 | writel(1 << ap->id, mmio + HOST_IRQ_STAT); | ||
1023 | |||
1024 | /* turn IRQ back on */ | ||
1025 | writel(DEF_PORT_IRQ, port_mmio + PORT_IRQ_MASK); | ||
1026 | } | ||
1027 | |||
1028 | static void ahci_error_handler(struct ata_port *ap) | ||
1029 | { | ||
1030 | if (!(ap->flags & ATA_FLAG_FROZEN)) { | ||
1031 | /* restart engine */ | ||
1032 | ahci_stop_engine(ap); | ||
1033 | ahci_start_engine(ap); | ||
1034 | } | ||
1035 | |||
1036 | /* perform recovery */ | ||
1037 | ata_do_eh(ap, ahci_prereset, ahci_softreset, ahci_hardreset, | ||
1038 | ahci_postreset); | ||
1039 | } | ||
1040 | |||
1041 | static void ahci_post_internal_cmd(struct ata_queued_cmd *qc) | ||
1042 | { | ||
1043 | struct ata_port *ap = qc->ap; | ||
1044 | |||
1045 | if (qc->flags & ATA_QCFLAG_FAILED) | ||
1046 | qc->err_mask |= AC_ERR_OTHER; | ||
1047 | |||
1048 | if (qc->err_mask) { | ||
1049 | /* make DMA engine forget about the failed command */ | ||
1050 | ahci_stop_engine(ap); | ||
1051 | ahci_start_engine(ap); | ||
1052 | } | ||
1053 | } | ||
1054 | |||
956 | static void ahci_setup_port(struct ata_ioports *port, unsigned long base, | 1055 | static void ahci_setup_port(struct ata_ioports *port, unsigned long base, |
957 | unsigned int port_idx) | 1056 | unsigned int port_idx) |
958 | { | 1057 | { |
@@ -1097,9 +1196,6 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent) | |||
1097 | writel(tmp, port_mmio + PORT_IRQ_STAT); | 1196 | writel(tmp, port_mmio + PORT_IRQ_STAT); |
1098 | 1197 | ||
1099 | writel(1 << i, mmio + HOST_IRQ_STAT); | 1198 | writel(1 << i, mmio + HOST_IRQ_STAT); |
1100 | |||
1101 | /* set irq mask (enables interrupts) */ | ||
1102 | writel(DEF_PORT_IRQ, port_mmio + PORT_IRQ_MASK); | ||
1103 | } | 1199 | } |
1104 | 1200 | ||
1105 | tmp = readl(mmio + HOST_CTL); | 1201 | tmp = readl(mmio + HOST_CTL); |
@@ -1197,6 +1293,8 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1197 | 1293 | ||
1198 | VPRINTK("ENTER\n"); | 1294 | VPRINTK("ENTER\n"); |
1199 | 1295 | ||
1296 | WARN_ON(ATA_MAX_QUEUE > AHCI_MAX_CMDS); | ||
1297 | |||
1200 | if (!printed_version++) | 1298 | if (!printed_version++) |
1201 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); | 1299 | dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); |
1202 | 1300 | ||
@@ -1264,6 +1362,9 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1264 | if (rc) | 1362 | if (rc) |
1265 | goto err_out_hpriv; | 1363 | goto err_out_hpriv; |
1266 | 1364 | ||
1365 | if (hpriv->cap & HOST_CAP_NCQ) | ||
1366 | probe_ent->host_flags |= ATA_FLAG_NCQ; | ||
1367 | |||
1267 | ahci_print_info(probe_ent); | 1368 | ahci_print_info(probe_ent); |
1268 | 1369 | ||
1269 | /* FIXME: check ata_device_add return value */ | 1370 | /* FIXME: check ata_device_add return value */ |
@@ -1295,21 +1396,17 @@ static void ahci_remove_one (struct pci_dev *pdev) | |||
1295 | struct device *dev = pci_dev_to_dev(pdev); | 1396 | struct device *dev = pci_dev_to_dev(pdev); |
1296 | struct ata_host_set *host_set = dev_get_drvdata(dev); | 1397 | struct ata_host_set *host_set = dev_get_drvdata(dev); |
1297 | struct ahci_host_priv *hpriv = host_set->private_data; | 1398 | struct ahci_host_priv *hpriv = host_set->private_data; |
1298 | struct ata_port *ap; | ||
1299 | unsigned int i; | 1399 | unsigned int i; |
1300 | int have_msi; | 1400 | int have_msi; |
1301 | 1401 | ||
1302 | for (i = 0; i < host_set->n_ports; i++) { | 1402 | for (i = 0; i < host_set->n_ports; i++) |
1303 | ap = host_set->ports[i]; | 1403 | ata_port_detach(host_set->ports[i]); |
1304 | |||
1305 | scsi_remove_host(ap->host); | ||
1306 | } | ||
1307 | 1404 | ||
1308 | have_msi = hpriv->flags & AHCI_FLAG_MSI; | 1405 | have_msi = hpriv->flags & AHCI_FLAG_MSI; |
1309 | free_irq(host_set->irq, host_set); | 1406 | free_irq(host_set->irq, host_set); |
1310 | 1407 | ||
1311 | for (i = 0; i < host_set->n_ports; i++) { | 1408 | for (i = 0; i < host_set->n_ports; i++) { |
1312 | ap = host_set->ports[i]; | 1409 | struct ata_port *ap = host_set->ports[i]; |
1313 | 1410 | ||
1314 | ata_scsi_release(ap->host); | 1411 | ata_scsi_release(ap->host); |
1315 | scsi_host_put(ap->host); | 1412 | scsi_host_put(ap->host); |