aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/ahci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/ahci.c')
-rw-r--r--drivers/ata/ahci.c51
1 files changed, 43 insertions, 8 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 25929123ffff..bddb14e91d3c 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -78,6 +78,7 @@ enum {
78 78
79 board_ahci = 0, 79 board_ahci = 0,
80 board_ahci_vt8251 = 1, 80 board_ahci_vt8251 = 1,
81 board_ahci_ign_iferr = 2,
81 82
82 /* global controller registers */ 83 /* global controller registers */
83 HOST_CAP = 0x00, /* host capabilities */ 84 HOST_CAP = 0x00, /* host capabilities */
@@ -168,6 +169,7 @@ enum {
168 /* ap->flags bits */ 169 /* ap->flags bits */
169 AHCI_FLAG_RESET_NEEDS_CLO = (1 << 24), 170 AHCI_FLAG_RESET_NEEDS_CLO = (1 << 24),
170 AHCI_FLAG_NO_NCQ = (1 << 25), 171 AHCI_FLAG_NO_NCQ = (1 << 25),
172 AHCI_FLAG_IGN_IRQ_IF_ERR = (1 << 26), /* ignore IRQ_IF_ERR */
171}; 173};
172 174
173struct ahci_cmd_hdr { 175struct ahci_cmd_hdr {
@@ -295,6 +297,17 @@ static const struct ata_port_info ahci_port_info[] = {
295 .udma_mask = 0x7f, /* udma0-6 ; FIXME */ 297 .udma_mask = 0x7f, /* udma0-6 ; FIXME */
296 .port_ops = &ahci_ops, 298 .port_ops = &ahci_ops,
297 }, 299 },
300 /* board_ahci_ign_iferr */
301 {
302 .sht = &ahci_sht,
303 .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
304 ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
305 ATA_FLAG_SKIP_D2H_BSY |
306 AHCI_FLAG_IGN_IRQ_IF_ERR,
307 .pio_mask = 0x1f, /* pio0-4 */
308 .udma_mask = 0x7f, /* udma0-6 ; FIXME */
309 .port_ops = &ahci_ops,
310 },
298}; 311};
299 312
300static const struct pci_device_id ahci_pci_tbl[] = { 313static const struct pci_device_id ahci_pci_tbl[] = {
@@ -314,13 +327,24 @@ static const struct pci_device_id ahci_pci_tbl[] = {
314 { PCI_VDEVICE(INTEL, 0x2824), board_ahci }, /* ICH8 */ 327 { PCI_VDEVICE(INTEL, 0x2824), board_ahci }, /* ICH8 */
315 { PCI_VDEVICE(INTEL, 0x2829), board_ahci }, /* ICH8M */ 328 { PCI_VDEVICE(INTEL, 0x2829), board_ahci }, /* ICH8M */
316 { PCI_VDEVICE(INTEL, 0x282a), board_ahci }, /* ICH8M */ 329 { PCI_VDEVICE(INTEL, 0x282a), board_ahci }, /* ICH8M */
330 { PCI_VDEVICE(INTEL, 0x2922), board_ahci }, /* ICH9 */
331 { PCI_VDEVICE(INTEL, 0x2923), board_ahci }, /* ICH9 */
332 { PCI_VDEVICE(INTEL, 0x2924), board_ahci }, /* ICH9 */
333 { PCI_VDEVICE(INTEL, 0x2925), board_ahci }, /* ICH9 */
334 { PCI_VDEVICE(INTEL, 0x2927), board_ahci }, /* ICH9 */
335 { PCI_VDEVICE(INTEL, 0x2929), board_ahci }, /* ICH9M */
336 { PCI_VDEVICE(INTEL, 0x292a), board_ahci }, /* ICH9M */
337 { PCI_VDEVICE(INTEL, 0x292b), board_ahci }, /* ICH9M */
338 { PCI_VDEVICE(INTEL, 0x292f), board_ahci }, /* ICH9M */
339 { PCI_VDEVICE(INTEL, 0x294d), board_ahci }, /* ICH9 */
340 { PCI_VDEVICE(INTEL, 0x294e), board_ahci }, /* ICH9M */
317 341
318 /* JMicron */ 342 /* JMicron */
319 { PCI_VDEVICE(JMICRON, 0x2360), board_ahci }, /* JMicron JMB360 */ 343 { PCI_VDEVICE(JMICRON, 0x2360), board_ahci_ign_iferr }, /* JMB360 */
320 { PCI_VDEVICE(JMICRON, 0x2361), board_ahci }, /* JMicron JMB361 */ 344 { PCI_VDEVICE(JMICRON, 0x2361), board_ahci_ign_iferr }, /* JMB361 */
321 { PCI_VDEVICE(JMICRON, 0x2363), board_ahci }, /* JMicron JMB363 */ 345 { PCI_VDEVICE(JMICRON, 0x2363), board_ahci_ign_iferr }, /* JMB363 */
322 { PCI_VDEVICE(JMICRON, 0x2365), board_ahci }, /* JMicron JMB365 */ 346 { PCI_VDEVICE(JMICRON, 0x2365), board_ahci_ign_iferr }, /* JMB365 */
323 { PCI_VDEVICE(JMICRON, 0x2366), board_ahci }, /* JMicron JMB366 */ 347 { PCI_VDEVICE(JMICRON, 0x2366), board_ahci_ign_iferr }, /* JMB366 */
324 348
325 /* ATI */ 349 /* ATI */
326 { PCI_VDEVICE(ATI, 0x4380), board_ahci }, /* ATI SB600 non-raid */ 350 { PCI_VDEVICE(ATI, 0x4380), board_ahci }, /* ATI SB600 non-raid */
@@ -334,6 +358,14 @@ static const struct pci_device_id ahci_pci_tbl[] = {
334 { PCI_VDEVICE(NVIDIA, 0x044d), board_ahci }, /* MCP65 */ 358 { PCI_VDEVICE(NVIDIA, 0x044d), board_ahci }, /* MCP65 */
335 { PCI_VDEVICE(NVIDIA, 0x044e), board_ahci }, /* MCP65 */ 359 { PCI_VDEVICE(NVIDIA, 0x044e), board_ahci }, /* MCP65 */
336 { PCI_VDEVICE(NVIDIA, 0x044f), board_ahci }, /* MCP65 */ 360 { PCI_VDEVICE(NVIDIA, 0x044f), board_ahci }, /* MCP65 */
361 { PCI_VDEVICE(NVIDIA, 0x0554), board_ahci }, /* MCP67 */
362 { PCI_VDEVICE(NVIDIA, 0x0555), board_ahci }, /* MCP67 */
363 { PCI_VDEVICE(NVIDIA, 0x0556), board_ahci }, /* MCP67 */
364 { PCI_VDEVICE(NVIDIA, 0x0557), board_ahci }, /* MCP67 */
365 { PCI_VDEVICE(NVIDIA, 0x0558), board_ahci }, /* MCP67 */
366 { PCI_VDEVICE(NVIDIA, 0x0559), board_ahci }, /* MCP67 */
367 { PCI_VDEVICE(NVIDIA, 0x055a), board_ahci }, /* MCP67 */
368 { PCI_VDEVICE(NVIDIA, 0x055b), board_ahci }, /* MCP67 */
337 369
338 /* SiS */ 370 /* SiS */
339 { PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */ 371 { PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */
@@ -736,8 +768,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class)
736 } 768 }
737 769
738 /* check BUSY/DRQ, perform Command List Override if necessary */ 770 /* check BUSY/DRQ, perform Command List Override if necessary */
739 ahci_tf_read(ap, &tf); 771 if (ahci_check_status(ap) & (ATA_BUSY | ATA_DRQ)) {
740 if (tf.command & (ATA_BUSY | ATA_DRQ)) {
741 rc = ahci_clo(ap); 772 rc = ahci_clo(ap);
742 773
743 if (rc == -EOPNOTSUPP) { 774 if (rc == -EOPNOTSUPP) {
@@ -962,6 +993,10 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
962 /* analyze @irq_stat */ 993 /* analyze @irq_stat */
963 ata_ehi_push_desc(ehi, "irq_stat 0x%08x", irq_stat); 994 ata_ehi_push_desc(ehi, "irq_stat 0x%08x", irq_stat);
964 995
996 /* some controllers set IRQ_IF_ERR on device errors, ignore it */
997 if (ap->flags & AHCI_FLAG_IGN_IRQ_IF_ERR)
998 irq_stat &= ~PORT_IRQ_IF_ERR;
999
965 if (irq_stat & PORT_IRQ_TF_ERR) 1000 if (irq_stat & PORT_IRQ_TF_ERR)
966 err_mask |= AC_ERR_DEV; 1001 err_mask |= AC_ERR_DEV;
967 1002
@@ -1041,7 +1076,7 @@ static void ahci_host_intr(struct ata_port *ap)
1041 /* hmmm... a spurious interupt */ 1076 /* hmmm... a spurious interupt */
1042 1077
1043 /* some devices send D2H reg with I bit set during NCQ command phase */ 1078 /* some devices send D2H reg with I bit set during NCQ command phase */
1044 if (ap->sactive && status & PORT_IRQ_D2H_REG_FIS) 1079 if (ap->sactive && (status & PORT_IRQ_D2H_REG_FIS))
1045 return; 1080 return;
1046 1081
1047 /* ignore interim PIO setup fis interrupts */ 1082 /* ignore interim PIO setup fis interrupts */