diff options
author | Tejun Heo <htejun@gmail.com> | 2008-06-09 11:13:04 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-06-13 02:46:17 -0400 |
commit | e297d99e103f951a71fcb1534f1ff3480dd3a851 (patch) | |
tree | 7e8b044efeb0f1ea048acba881a00e8326a4a0ab /drivers/ata | |
parent | 5dd34572ad9a3be430632dd42e4af2ea370b397b (diff) |
ahci: workarounds for mcp65
MCP65 ahci can do NCQ but doesn't set the CAP bit and rev A0 and A1
can't do MSI but have MSI capability. Implement AHCI_HFLAG_YES_NCQ
and apply appropriate workarounds.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Cc: Peer Chen <pchen@nvidia.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/ahci.c | 40 |
1 files changed, 31 insertions, 9 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 544b7d6c617c..1c62b8e39645 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -89,6 +89,7 @@ enum { | |||
89 | board_ahci_sb600 = 3, | 89 | board_ahci_sb600 = 3, |
90 | board_ahci_mv = 4, | 90 | board_ahci_mv = 4, |
91 | board_ahci_sb700 = 5, | 91 | board_ahci_sb700 = 5, |
92 | board_ahci_mcp65 = 6, | ||
92 | 93 | ||
93 | /* global controller registers */ | 94 | /* global controller registers */ |
94 | HOST_CAP = 0x00, /* host capabilities */ | 95 | HOST_CAP = 0x00, /* host capabilities */ |
@@ -190,6 +191,7 @@ enum { | |||
190 | AHCI_HFLAG_NO_PMP = (1 << 6), /* no PMP */ | 191 | AHCI_HFLAG_NO_PMP = (1 << 6), /* no PMP */ |
191 | AHCI_HFLAG_NO_HOTPLUG = (1 << 7), /* ignore PxSERR.DIAG.N */ | 192 | AHCI_HFLAG_NO_HOTPLUG = (1 << 7), /* ignore PxSERR.DIAG.N */ |
192 | AHCI_HFLAG_SECT255 = (1 << 8), /* max 255 sectors */ | 193 | AHCI_HFLAG_SECT255 = (1 << 8), /* max 255 sectors */ |
194 | AHCI_HFLAG_YES_NCQ = (1 << 9), /* force NCQ cap on */ | ||
193 | 195 | ||
194 | /* ap->flags bits */ | 196 | /* ap->flags bits */ |
195 | 197 | ||
@@ -384,6 +386,14 @@ static const struct ata_port_info ahci_port_info[] = { | |||
384 | .udma_mask = ATA_UDMA6, | 386 | .udma_mask = ATA_UDMA6, |
385 | .port_ops = &ahci_ops, | 387 | .port_ops = &ahci_ops, |
386 | }, | 388 | }, |
389 | /* board_ahci_mcp65 */ | ||
390 | { | ||
391 | AHCI_HFLAGS (AHCI_HFLAG_YES_NCQ), | ||
392 | .flags = AHCI_FLAG_COMMON, | ||
393 | .pio_mask = 0x1f, /* pio0-4 */ | ||
394 | .udma_mask = ATA_UDMA6, | ||
395 | .port_ops = &ahci_ops, | ||
396 | }, | ||
387 | }; | 397 | }; |
388 | 398 | ||
389 | static const struct pci_device_id ahci_pci_tbl[] = { | 399 | static const struct pci_device_id ahci_pci_tbl[] = { |
@@ -438,14 +448,14 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
438 | { PCI_VDEVICE(VIA, 0x6287), board_ahci_vt8251 }, /* VIA VT8251 */ | 448 | { PCI_VDEVICE(VIA, 0x6287), board_ahci_vt8251 }, /* VIA VT8251 */ |
439 | 449 | ||
440 | /* NVIDIA */ | 450 | /* NVIDIA */ |
441 | { PCI_VDEVICE(NVIDIA, 0x044c), board_ahci }, /* MCP65 */ | 451 | { PCI_VDEVICE(NVIDIA, 0x044c), board_ahci_mcp65 }, /* MCP65 */ |
442 | { PCI_VDEVICE(NVIDIA, 0x044d), board_ahci }, /* MCP65 */ | 452 | { PCI_VDEVICE(NVIDIA, 0x044d), board_ahci_mcp65 }, /* MCP65 */ |
443 | { PCI_VDEVICE(NVIDIA, 0x044e), board_ahci }, /* MCP65 */ | 453 | { PCI_VDEVICE(NVIDIA, 0x044e), board_ahci_mcp65 }, /* MCP65 */ |
444 | { PCI_VDEVICE(NVIDIA, 0x044f), board_ahci }, /* MCP65 */ | 454 | { PCI_VDEVICE(NVIDIA, 0x044f), board_ahci_mcp65 }, /* MCP65 */ |
445 | { PCI_VDEVICE(NVIDIA, 0x045c), board_ahci }, /* MCP65 */ | 455 | { PCI_VDEVICE(NVIDIA, 0x045c), board_ahci_mcp65 }, /* MCP65 */ |
446 | { PCI_VDEVICE(NVIDIA, 0x045d), board_ahci }, /* MCP65 */ | 456 | { PCI_VDEVICE(NVIDIA, 0x045d), board_ahci_mcp65 }, /* MCP65 */ |
447 | { PCI_VDEVICE(NVIDIA, 0x045e), board_ahci }, /* MCP65 */ | 457 | { PCI_VDEVICE(NVIDIA, 0x045e), board_ahci_mcp65 }, /* MCP65 */ |
448 | { PCI_VDEVICE(NVIDIA, 0x045f), board_ahci }, /* MCP65 */ | 458 | { PCI_VDEVICE(NVIDIA, 0x045f), board_ahci_mcp65 }, /* MCP65 */ |
449 | { PCI_VDEVICE(NVIDIA, 0x0550), board_ahci }, /* MCP67 */ | 459 | { PCI_VDEVICE(NVIDIA, 0x0550), board_ahci }, /* MCP67 */ |
450 | { PCI_VDEVICE(NVIDIA, 0x0551), board_ahci }, /* MCP67 */ | 460 | { PCI_VDEVICE(NVIDIA, 0x0551), board_ahci }, /* MCP67 */ |
451 | { PCI_VDEVICE(NVIDIA, 0x0552), board_ahci }, /* MCP67 */ | 461 | { PCI_VDEVICE(NVIDIA, 0x0552), board_ahci }, /* MCP67 */ |
@@ -624,6 +634,12 @@ static void ahci_save_initial_config(struct pci_dev *pdev, | |||
624 | cap &= ~HOST_CAP_NCQ; | 634 | cap &= ~HOST_CAP_NCQ; |
625 | } | 635 | } |
626 | 636 | ||
637 | if (!(cap & HOST_CAP_NCQ) && (hpriv->flags & AHCI_HFLAG_YES_NCQ)) { | ||
638 | dev_printk(KERN_INFO, &pdev->dev, | ||
639 | "controller can do NCQ, turning on CAP_NCQ\n"); | ||
640 | cap |= HOST_CAP_NCQ; | ||
641 | } | ||
642 | |||
627 | if ((cap & HOST_CAP_PMP) && (hpriv->flags & AHCI_HFLAG_NO_PMP)) { | 643 | if ((cap & HOST_CAP_PMP) && (hpriv->flags & AHCI_HFLAG_NO_PMP)) { |
628 | dev_printk(KERN_INFO, &pdev->dev, | 644 | dev_printk(KERN_INFO, &pdev->dev, |
629 | "controller can't do PMP, turning off CAP_PMP\n"); | 645 | "controller can't do PMP, turning off CAP_PMP\n"); |
@@ -2118,7 +2134,8 @@ static void ahci_p5wdh_workaround(struct ata_host *host) | |||
2118 | static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 2134 | static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
2119 | { | 2135 | { |
2120 | static int printed_version; | 2136 | static int printed_version; |
2121 | struct ata_port_info pi = ahci_port_info[ent->driver_data]; | 2137 | unsigned int board_id = ent->driver_data; |
2138 | struct ata_port_info pi = ahci_port_info[board_id]; | ||
2122 | const struct ata_port_info *ppi[] = { &pi, NULL }; | 2139 | const struct ata_port_info *ppi[] = { &pi, NULL }; |
2123 | struct device *dev = &pdev->dev; | 2140 | struct device *dev = &pdev->dev; |
2124 | struct ahci_host_priv *hpriv; | 2141 | struct ahci_host_priv *hpriv; |
@@ -2167,6 +2184,11 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2167 | return -ENOMEM; | 2184 | return -ENOMEM; |
2168 | hpriv->flags |= (unsigned long)pi.private_data; | 2185 | hpriv->flags |= (unsigned long)pi.private_data; |
2169 | 2186 | ||
2187 | /* MCP65 revision A1 and A2 can't do MSI */ | ||
2188 | if (board_id == board_ahci_mcp65 && | ||
2189 | (pdev->revision == 0xa1 || pdev->revision == 0xa2)) | ||
2190 | hpriv->flags |= AHCI_HFLAG_NO_MSI; | ||
2191 | |||
2170 | if ((hpriv->flags & AHCI_HFLAG_NO_MSI) || pci_enable_msi(pdev)) | 2192 | if ((hpriv->flags & AHCI_HFLAG_NO_MSI) || pci_enable_msi(pdev)) |
2171 | pci_intx(pdev, 1); | 2193 | pci_intx(pdev, 1); |
2172 | 2194 | ||