]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/pci/quirks.c
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
[linux-2.6-omap-h63xx.git] / drivers / pci / quirks.c
index 0a953d43b9a207961a6d41dbb1872d105f978982..e9a333d985526c5a5af22c1e6cc79c3e2dccad10 100644 (file)
@@ -867,13 +867,13 @@ static void quirk_disable_pxb(struct pci_dev *pdev)
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   PCI_DEVICE_ID_INTEL_82454NX,    quirk_disable_pxb);
 DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_82454NX,    quirk_disable_pxb);
 
-
-static void __devinit quirk_sb600_sata(struct pci_dev *pdev)
+static void __devinit quirk_amd_ide_mode(struct pci_dev *pdev)
 {
-       /* set sb600 sata to ahci mode */
-       if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
-               u8 tmp;
+       /* set sb600/sb700/sb800 sata to ahci mode */
+       u8 tmp;
 
+       pci_read_config_byte(pdev, PCI_CLASS_DEVICE, &tmp);
+       if (tmp == 0x01) {
                pci_read_config_byte(pdev, 0x40, &tmp);
                pci_write_config_byte(pdev, 0x40, tmp|1);
                pci_write_config_byte(pdev, 0x9, 1);
@@ -881,10 +881,13 @@ static void __devinit quirk_sb600_sata(struct pci_dev *pdev)
                pci_write_config_byte(pdev, 0x40, tmp);
 
                pdev->class = PCI_CLASS_STORAGE_SATA_AHCI;
+               dev_info(&pdev->dev, "set SATA to AHCI mode\n");
        }
 }
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_sb600_sata);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_sb600_sata);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_amd_ide_mode);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_amd_ide_mode);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_amd_ide_mode);
 
 /*
  *     Serverworks CSB5 IDE does not fully support native mode
@@ -1649,9 +1652,8 @@ static void __devinit quirk_via_cx700_pci_parking_caching(struct pci_dev *dev)
                        pci_write_config_byte(dev, 0x75, 0x1);
                        pci_write_config_byte(dev, 0x77, 0x0);
 
-                       printk(KERN_INFO
-                               "PCI: VIA CX700 PCI parking/caching fixup on %s\n",
-                               pci_name(dev));
+                       dev_info(&dev->dev,
+                               "Disabling VIA CX700 PCI parking/caching\n");
                }
        }
 }
@@ -1723,10 +1725,34 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT2
                        quirk_msi_ht_cap);
 
 
-/*
- *  Force enable MSI mapping capability on HT bridges
+/* The nVidia CK804 chipset may have 2 HT MSI mappings.
+ * MSI are supported if the MSI capability set in any of these mappings.
  */
-static void __devinit quirk_msi_ht_cap_enable(struct pci_dev *dev)
+static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev)
+{
+       struct pci_dev *pdev;
+
+       if (!dev->subordinate)
+               return;
+
+       /* check HT MSI cap on this chipset and the root one.
+        * a single one having MSI is enough to be sure that MSI are supported.
+        */
+       pdev = pci_get_slot(dev->bus, 0);
+       if (!pdev)
+               return;
+       if (!msi_ht_cap_enabled(dev) && !msi_ht_cap_enabled(pdev)) {
+               dev_warn(&dev->dev, "MSI quirk detected; "
+                       "subordinate MSI disabled\n");
+               dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI;
+       }
+       pci_dev_put(pdev);
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
+                       quirk_nvidia_ck804_msi_ht_cap);
+
+/* Force enable MSI mapping capability on HT bridges */
+static void __devinit ht_enable_msi_mapping(struct pci_dev *dev)
 {
        int pos, ttl = 48;
 
@@ -1734,9 +1760,9 @@ static void __devinit quirk_msi_ht_cap_enable(struct pci_dev *dev)
        while (pos && ttl--) {
                u8 flags;
 
-               if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS, &flags) == 0) {
-                       printk(KERN_INFO "PCI: Enabling HT MSI Mapping on %s\n",
-                              pci_name(dev));
+               if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS,
+                                        &flags) == 0) {
+                       dev_info(&dev->dev, "Enabling HT MSI Mapping\n");
 
                        pci_write_config_byte(dev, pos + HT_MSI_FLAGS,
                                              flags | HT_MSI_FLAGS_ENABLE);
@@ -1747,33 +1773,47 @@ static void __devinit quirk_msi_ht_cap_enable(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS,
                         PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB,
-                        quirk_msi_ht_cap_enable);
+                        ht_enable_msi_mapping);
 
-/* The nVidia CK804 chipset may have 2 HT MSI mappings.
- * MSI are supported if the MSI capability set in any of these mappings.
- */
-static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev)
+static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev)
 {
-       struct pci_dev *pdev;
+       struct pci_dev *host_bridge;
+       int pos, ttl = 48;
 
-       if (!dev->subordinate)
+       /*
+        * HT MSI mapping should be disabled on devices that are below
+        * a non-Hypertransport host bridge. Locate the host bridge...
+        */
+       host_bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0));
+       if (host_bridge == NULL) {
+               dev_warn(&dev->dev,
+                        "nv_msi_ht_cap_quirk didn't locate host bridge\n");
                return;
+       }
 
-       /* check HT MSI cap on this chipset and the root one.
-        * a single one having MSI is enough to be sure that MSI are supported.
-        */
-       pdev = pci_get_slot(dev->bus, 0);
-       if (!pdev)
+       pos = pci_find_ht_capability(host_bridge, HT_CAPTYPE_SLAVE);
+       if (pos != 0) {
+               /* Host bridge is to HT */
+               ht_enable_msi_mapping(dev);
                return;
-       if (!msi_ht_cap_enabled(dev) && !msi_ht_cap_enabled(pdev)) {
-               dev_warn(&dev->dev, "MSI quirk detected; "
-                       "subordinate MSI disabled\n");
-               dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI;
        }
-       pci_dev_put(pdev);
+
+       /* Host bridge is not to HT, disable HT MSI mapping on this device */
+       pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING);
+       while (pos && ttl--) {
+               u8 flags;
+
+               if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS,
+                                        &flags) == 0) {
+                       dev_info(&dev->dev, "Disabling HT MSI mapping");
+                       pci_write_config_byte(dev, pos + HT_MSI_FLAGS,
+                                             flags & ~HT_MSI_FLAGS_ENABLE);
+               }
+               pos = pci_find_next_ht_capability(dev, pos,
+                                                 HT_CAPTYPE_MSI_MAPPING);
+       }
 }
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
-                       quirk_nvidia_ck804_msi_ht_cap);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk);
 
 static void __devinit quirk_msi_intx_disable_bug(struct pci_dev *dev)
 {