Merge master.kernel.org:/pub/scm/linux/kernel/git/bart/ide-2.6
[sfrench/cifs-2.6.git] / drivers / pci / quirks.c
index 40c1825c8b9382edf5f360f9c42904d16d0795b2..11217bda4b9ef1c98003bd50f16d92a90c42db39 100644 (file)
@@ -61,7 +61,8 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441,      quirk_p
     
     This appears to be BIOS not version dependent. So presumably there is a 
     chipset level fix */
-int isa_dma_bridge_buggy;              /* Exported */
+int isa_dma_bridge_buggy;
+EXPORT_SYMBOL(isa_dma_bridge_buggy);
     
 static void __devinit quirk_isa_dma_hangs(struct pci_dev *dev)
 {
@@ -83,6 +84,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC,    PCI_DEVICE_ID_NEC_CBUS_2,       quirk_isa_d
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC,     PCI_DEVICE_ID_NEC_CBUS_3,       quirk_isa_dma_hangs );
 
 int pci_pci_problems;
+EXPORT_SYMBOL(pci_pci_problems);
 
 /*
  *     Chipsets where PCI->PCI transfers vanish or hang
@@ -94,6 +96,8 @@ static void __devinit quirk_nopcipci(struct pci_dev *dev)
                pci_pci_problems |= PCIPCI_FAIL;
        }
 }
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI,      PCI_DEVICE_ID_SI_5597,          quirk_nopcipci );
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI,      PCI_DEVICE_ID_SI_496,           quirk_nopcipci );
 
 static void __devinit quirk_nopciamd(struct pci_dev *dev)
 {
@@ -105,9 +109,6 @@ static void __devinit quirk_nopciamd(struct pci_dev *dev)
                pci_pci_problems |= PCIAGP_FAIL;
        }
 }
-
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI,      PCI_DEVICE_ID_SI_5597,          quirk_nopcipci );
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI,      PCI_DEVICE_ID_SI_496,           quirk_nopcipci );
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD,     PCI_DEVICE_ID_AMD_8151_0,       quirk_nopciamd );
 
 /*
@@ -976,52 +977,51 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
                        case 0x1626: /* L3C notebook */
                                asus_hides_smbus = 1;
                        }
-               if (dev->device == PCI_DEVICE_ID_INTEL_82845G_HB)
+               else if (dev->device == PCI_DEVICE_ID_INTEL_82845G_HB)
                        switch(dev->subsystem_device) {
                        case 0x80b1: /* P4GE-V */
                        case 0x80b2: /* P4PE */
                        case 0x8093: /* P4B533-V */
                                asus_hides_smbus = 1;
                        }
-               if (dev->device == PCI_DEVICE_ID_INTEL_82850_HB)
+               else if (dev->device == PCI_DEVICE_ID_INTEL_82850_HB)
                        switch(dev->subsystem_device) {
                        case 0x8030: /* P4T533 */
                                asus_hides_smbus = 1;
                        }
-               if (dev->device == PCI_DEVICE_ID_INTEL_7205_0)
+               else if (dev->device == PCI_DEVICE_ID_INTEL_7205_0)
                        switch (dev->subsystem_device) {
                        case 0x8070: /* P4G8X Deluxe */
                                asus_hides_smbus = 1;
                        }
-               if (dev->device == PCI_DEVICE_ID_INTEL_E7501_MCH)
+               else if (dev->device == PCI_DEVICE_ID_INTEL_E7501_MCH)
                        switch (dev->subsystem_device) {
                        case 0x80c9: /* PU-DLS */
                                asus_hides_smbus = 1;
                        }
-               if (dev->device == PCI_DEVICE_ID_INTEL_82855GM_HB)
+               else if (dev->device == PCI_DEVICE_ID_INTEL_82855GM_HB)
                        switch (dev->subsystem_device) {
                        case 0x1751: /* M2N notebook */
                        case 0x1821: /* M5N notebook */
                                asus_hides_smbus = 1;
                        }
-               if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB)
+               else if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB)
                        switch (dev->subsystem_device) {
                        case 0x184b: /* W1N notebook */
                        case 0x186a: /* M6Ne notebook */
                                asus_hides_smbus = 1;
                        }
-               if (dev->device == PCI_DEVICE_ID_INTEL_82865_HB)
+               else if (dev->device == PCI_DEVICE_ID_INTEL_82865_HB)
                        switch (dev->subsystem_device) {
                        case 0x80f2: /* P4P800-X */
                                asus_hides_smbus = 1;
                        }
-               if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) {
+               else if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB)
                        switch (dev->subsystem_device) {
                        case 0x1882: /* M6V notebook */
                        case 0x1977: /* A6VA notebook */
                                asus_hides_smbus = 1;
                        }
-               }
        } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_HP)) {
                if (dev->device ==  PCI_DEVICE_ID_INTEL_82855PM_HB)
                        switch(dev->subsystem_device) {
@@ -1029,25 +1029,24 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
                        case 0x0890: /* HP Compaq nc6000 */
                                asus_hides_smbus = 1;
                        }
-               if (dev->device == PCI_DEVICE_ID_INTEL_82865_HB)
+               else if (dev->device == PCI_DEVICE_ID_INTEL_82865_HB)
                        switch (dev->subsystem_device) {
                        case 0x12bc: /* HP D330L */
                        case 0x12bd: /* HP D530 */
                                asus_hides_smbus = 1;
                        }
-               if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) {
+               else if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB)
                        switch (dev->subsystem_device) {
                        case 0x099c: /* HP Compaq nx6110 */
                                asus_hides_smbus = 1;
                        }
-               }
        } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_TOSHIBA)) {
                if (dev->device == PCI_DEVICE_ID_INTEL_82855GM_HB)
                        switch(dev->subsystem_device) {
                        case 0x0001: /* Toshiba Satellite A40 */
                                asus_hides_smbus = 1;
                        }
-               if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB)
+               else if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB)
                        switch(dev->subsystem_device) {
                        case 0x0001: /* Toshiba Tecra M2 */
                                asus_hides_smbus = 1;
@@ -1136,6 +1135,14 @@ static void quirk_sis_96x_smbus(struct pci_dev *dev)
                pci_write_config_byte(dev, 0x77, val & ~0x10);
        }
 }
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_961,           quirk_sis_96x_smbus );
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_962,           quirk_sis_96x_smbus );
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_963,           quirk_sis_96x_smbus );
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_LPC,           quirk_sis_96x_smbus );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_961,           quirk_sis_96x_smbus );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_962,           quirk_sis_96x_smbus );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_963,           quirk_sis_96x_smbus );
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_LPC,           quirk_sis_96x_smbus );
 
 /*
  * ... This is further complicated by the fact that some SiS96x south
@@ -1145,8 +1152,6 @@ static void quirk_sis_96x_smbus(struct pci_dev *dev)
  *
  * We can also enable the sis96x bit in the discovery register..
  */
-static int __devinitdata sis_96x_compatible = 0;
-
 #define SIS_DETECT_REGISTER 0x40
 
 static void quirk_sis_503(struct pci_dev *dev)
@@ -1162,9 +1167,6 @@ static void quirk_sis_503(struct pci_dev *dev)
                return;
        }
 
-       /* Make people aware that we changed the config.. */
-       printk(KERN_WARNING "Uncovering SIS%x that hid as a SIS503 (compatible=%d)\n", devid, sis_96x_compatible);
-
        /*
         * Ok, it now shows up as a 96x.. run the 96x quirk by
         * hand in case it has already been processed.
@@ -1173,20 +1175,10 @@ static void quirk_sis_503(struct pci_dev *dev)
        dev->device = devid;
        quirk_sis_96x_smbus(dev);
 }
-
-static void __init quirk_sis_96x_compatible(struct pci_dev *dev)
-{
-       sis_96x_compatible = 1;
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_645,           quirk_sis_96x_compatible );
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_646,           quirk_sis_96x_compatible );
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_648,           quirk_sis_96x_compatible );
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_650,           quirk_sis_96x_compatible );
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_651,           quirk_sis_96x_compatible );
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_735,           quirk_sis_96x_compatible );
-
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_503,           quirk_sis_503 );
 DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_503,           quirk_sis_503 );
+
+
 /*
  * On ASUS A8V and A8V Deluxe boards, the onboard AC97 audio controller
  * and MC97 modem controller are disabled when a second PCI soundcard is
@@ -1217,21 +1209,8 @@ static void asus_hides_ac97_lpc(struct pci_dev *dev)
        }
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA,    PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc );
-
-
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_961,           quirk_sis_96x_smbus );
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_962,           quirk_sis_96x_smbus );
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_963,           quirk_sis_96x_smbus );
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_LPC,           quirk_sis_96x_smbus );
-
 DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA,    PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc );
 
-
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_961,           quirk_sis_96x_smbus );
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_962,           quirk_sis_96x_smbus );
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_963,           quirk_sis_96x_smbus );
-DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI,     PCI_DEVICE_ID_SI_LPC,           quirk_sis_96x_smbus );
-
 #if defined(CONFIG_ATA) || defined(CONFIG_ATA_MODULE)
 
 /*
@@ -1276,7 +1255,6 @@ static void quirk_jmicron_dualfn(struct pci_dev *pdev)
                        break;
        }
 }
-
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, quirk_jmicron_dualfn);
 DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, quirk_jmicron_dualfn);
 
@@ -1420,6 +1398,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,    PCI_ANY_ID,         quirk_intel_ide_co
 
 
 int pcie_mch_quirk;
+EXPORT_SYMBOL(pcie_mch_quirk);
 
 static void __devinit quirk_pcie_mch(struct pci_dev *pdev)
 {
@@ -1664,6 +1643,7 @@ void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
        }
        pci_do_fixups(dev, start, end);
 }
+EXPORT_SYMBOL(pci_fixup_device);
 
 /* Enable 1k I/O space granularity on the Intel P64H2 */
 static void __devinit quirk_p64h2_1k_io(struct pci_dev *dev)
@@ -1691,6 +1671,31 @@ static void __devinit quirk_p64h2_1k_io(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  0x1460,         quirk_p64h2_1k_io);
 
+/* Fix the IOBL_ADR for 1k I/O space granularity on the Intel P64H2
+ * The IOBL_ADR gets re-written to 4k boundaries in pci_setup_bridge()
+ * in drivers/pci/setup-bus.c
+ */
+static void __devinit quirk_p64h2_1k_io_fix_iobl(struct pci_dev *dev)
+{
+       u16 en1k, iobl_adr, iobl_adr_1k;
+       struct resource *res = dev->resource + PCI_BRIDGE_RESOURCES;
+
+       pci_read_config_word(dev, 0x40, &en1k);
+
+       if (en1k & 0x200) {
+               pci_read_config_word(dev, PCI_IO_BASE, &iobl_adr);
+
+               iobl_adr_1k = iobl_adr | (res->start >> 8) | (res->end & 0xfc00);
+
+               if (iobl_adr != iobl_adr_1k) {
+                       printk(KERN_INFO "PCI: Fixing P64H2 IOBL_ADR from 0x%x to 0x%x for 1 KB Granularity\n",
+                               iobl_adr,iobl_adr_1k);
+                       pci_write_config_word(dev, PCI_IO_BASE, iobl_adr_1k);
+               }
+       }
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   0x1460,         quirk_p64h2_1k_io_fix_iobl);
+
 /* Under some circumstances, AER is not linked with extended capabilities.
  * Force it to be linked by setting the corresponding control bit in the
  * config space.
@@ -1713,9 +1718,6 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_NVIDIA,  PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
                        quirk_nvidia_ck804_pcie_aer_ext_cap);
 
 #ifdef CONFIG_PCI_MSI
-/* To disable MSI globally */
-int pci_msi_quirk;
-
 /* The Serverworks PCI-X chipset does not support MSI. We cannot easily rely
  * on setting PCI_BUS_FLAGS_NO_MSI in its bus flags because there are actually
  * some other busses controlled by the chipset even if Linux is not aware of it.
@@ -1724,8 +1726,8 @@ int pci_msi_quirk;
  */
 static void __init quirk_svw_msi(struct pci_dev *dev)
 {
-       pci_msi_quirk = 1;
-       printk(KERN_WARNING "PCI: MSI quirk detected. pci_msi_quirk set.\n");
+       pci_no_msi();
+       printk(KERN_WARNING "PCI: MSI quirk detected. MSI deactivated.\n");
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE, quirk_svw_msi);
 
@@ -1806,8 +1808,3 @@ static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev)
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
                        quirk_nvidia_ck804_msi_ht_cap);
 #endif /* CONFIG_PCI_MSI */
-
-EXPORT_SYMBOL(pcie_mch_quirk);
-#ifdef CONFIG_HOTPLUG
-EXPORT_SYMBOL(pci_fixup_device);
-#endif