diff options
Diffstat (limited to 'drivers/ata/ahci.c')
-rw-r--r-- | drivers/ata/ahci.c | 51 |
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 | ||
173 | struct ahci_cmd_hdr { | 175 | struct 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 | ||
300 | static const struct pci_device_id ahci_pci_tbl[] = { | 313 | static 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 */ |