ahci: workarounds for mcp65
PATCH 1/1 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 <[email protected]>
Cc Peer Chen <[email protected]>
--- drivers/ata/ahci.c | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-)
drivers/ata/ahci.c +31 -9
@@ -89,6 +89,7 @@ enum { board_ahci_sb600 =3 , board_ahci_mv =4 , board_ahci_sb700 =5 , + board_ahci_mcp65 =6 ,/* global controller registers */ HOST_CAP = 0x00, /* host capabilities */
@@ -190,6 +191,7 @@ enum {AHCI_HFLAG_NO_PMP = (1 <<6 ),/* no PMP */ AHCI_HFLAG_NO_HOTPLUG = (1 <<7 ),/* ignore PxSERR.DIAG.N */ AHCI_HFLAG_SECT255 = (1 <<8 ),/* max 255 sectors */ + AHCI_HFLAG_YES_NCQ = (1 << 9), /* force NCQ cap on *//* ap->flags bits */
@@ -384,6 +386,14 @@ static const struct ata_port_info ahci_port_info[] = { .udma_mask = ATA_UDMA6, .port_ops = &ahci_ops, }, +/* board_ahci_mcp65 */ + { + AHCI_HFLAGS (AHCI_HFLAG_YES_NCQ), + .flags = AHCI_FLAG_COMMON, + .pio_mask = 0x1f, /* pio0-4 */ + .udma_mask = ATA_UDMA6, + .port_ops = &ahci_ops, + }, }; static const struct pci_device_id ahci_pci_tbl[] = {
@@ -438,14 +448,14 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(VIA, 0x6287), board_ahci_vt8251 }, /* VIA VT8251 *//* NVIDIA */ - { PCI_VDEVICE(NVIDIA, 0x044c), board_ahci }, /* MCP65 */ - { PCI_VDEVICE(NVIDIA, 0x044d), board_ahci }, /* MCP65 */ - { PCI_VDEVICE(NVIDIA, 0x044e), board_ahci }, /* MCP65 */ - { PCI_VDEVICE(NVIDIA, 0x044f), board_ahci }, /* MCP65 */ - { PCI_VDEVICE(NVIDIA, 0x045c), board_ahci }, /* MCP65 */ - { PCI_VDEVICE(NVIDIA, 0x045d), board_ahci }, /* MCP65 */ - { PCI_VDEVICE(NVIDIA, 0x045e), board_ahci }, /* MCP65 */ - { PCI_VDEVICE(NVIDIA, 0x045f), board_ahci }, /* MCP65 */ + { PCI_VDEVICE(NVIDIA, 0x044c), board_ahci_mcp65 }, /* MCP65 */ + { PCI_VDEVICE(NVIDIA, 0x044d), board_ahci_mcp65 }, /* MCP65 */ + { PCI_VDEVICE(NVIDIA, 0x044e), board_ahci_mcp65 }, /* MCP65 */ + { PCI_VDEVICE(NVIDIA, 0x044f), board_ahci_mcp65 }, /* MCP65 */ + { PCI_VDEVICE(NVIDIA, 0x045c), board_ahci_mcp65 }, /* MCP65 */ + { PCI_VDEVICE(NVIDIA, 0x045d), board_ahci_mcp65 }, /* MCP65 */ + { PCI_VDEVICE(NVIDIA, 0x045e), board_ahci_mcp65 }, /* MCP65 */ + { PCI_VDEVICE(NVIDIA, 0x045f), board_ahci_mcp65 }, /* MCP65 */ { PCI_VDEVICE(NVIDIA, 0x0550), board_ahci }, /* MCP67 */ { PCI_VDEVICE(NVIDIA, 0x0551), board_ahci }, /* MCP67 */ { PCI_VDEVICE(NVIDIA, 0x0552), board_ahci }, /* MCP67 */
@@ -624,6 +634,12 @@ static void ahci_save_initial_config(struct pci_dev *pdev, cap &= ~HOST_CAP_NCQ ; } +if (!(cap &HOST_CAP_NCQ ) && (hpriv->flags &AHCI_HFLAG_YES_NCQ )) { +dev_printk (KERN_INFO , &pdev->dev, +"controller can do NCQ, turning on CAP_NCQ\n" ); + cap |=HOST_CAP_NCQ ; + } +if ((cap &HOST_CAP_PMP ) && (hpriv->flags &AHCI_HFLAG_NO_PMP )) {dev_printk (KERN_INFO , &pdev->dev,"controller can't do PMP, turning off CAP_PMP\n" );
@@ -2118,7 +2134,8 @@ static void ahci_p5wdh_workaround(struct ata_host *host)static int ahci_init_one (struct pci_dev *pdev,const struct pci_device_id *ent) {static int printed_version; -struct ata_port_info pi = ahci_port_info[ent->driver_data]; +unsigned int board_id = ent->driver_data; +struct ata_port_info pi = ahci_port_info[board_id];const struct ata_port_info *ppi[] = { &pi,NULL };struct device *dev = &pdev->dev;struct ahci_host_priv *hpriv;
@@ -2167,6 +2184,11 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)return -ENOMEM ; hpriv->flags |= (unsigned long )pi.private_data; +/* MCP65 revision A1 and A2 can't do MSI */ +if (board_id == board_ahci_mcp65 && + (pdev->revision ==0xa1 || pdev->revision ==0xa2 )) + hpriv->flags |=AHCI_HFLAG_NO_MSI ; +if ((hpriv->flags &AHCI_HFLAG_NO_MSI ) ||pci_enable_msi (pdev))pci_intx (pdev,1 );
Hi,
so far there is nothing to complain. NCQ seems to work. syncing portage, installing stuff, cp'ing around stuff. No errors in dmesg, data is intact.
So I would like to thank everybody involved for your time you spent on my problems.
Thank you very much. You made me a very happy citizen :)
Glück auf,
Volker
Jeff Garzik
AppliedQuoted 9 lines · Tejun Heo
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_NCQand apply appropriate workarounds.Signed-off-by Tejun Heo <[email protected]>Cc Peer Chen <[email protected]>--- drivers/ata/ahci.c | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-)
applied