diff options
Diffstat (limited to 'drivers/pci/quirks.c')
| -rw-r--r-- | drivers/pci/quirks.c | 187 |
1 files changed, 166 insertions, 21 deletions
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 5049a47030ac..ce0985615133 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
| 23 | #include <linux/acpi.h> | 23 | #include <linux/acpi.h> |
| 24 | #include <linux/kallsyms.h> | 24 | #include <linux/kallsyms.h> |
| 25 | #include <linux/dmi.h> | ||
| 25 | #include "pci.h" | 26 | #include "pci.h" |
| 26 | 27 | ||
| 27 | int isa_dma_bridge_buggy; | 28 | int isa_dma_bridge_buggy; |
| @@ -605,27 +606,6 @@ static void __init quirk_ioapic_rmw(struct pci_dev *dev) | |||
| 605 | sis_apic_bug = 1; | 606 | sis_apic_bug = 1; |
| 606 | } | 607 | } |
| 607 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_ANY_ID, quirk_ioapic_rmw); | 608 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_ANY_ID, quirk_ioapic_rmw); |
| 608 | |||
| 609 | #define AMD8131_revA0 0x01 | ||
| 610 | #define AMD8131_revB0 0x11 | ||
| 611 | #define AMD8131_MISC 0x40 | ||
| 612 | #define AMD8131_NIOAMODE_BIT 0 | ||
| 613 | static void quirk_amd_8131_ioapic(struct pci_dev *dev) | ||
| 614 | { | ||
| 615 | unsigned char tmp; | ||
| 616 | |||
| 617 | if (nr_ioapics == 0) | ||
| 618 | return; | ||
| 619 | |||
| 620 | if (dev->revision == AMD8131_revA0 || dev->revision == AMD8131_revB0) { | ||
| 621 | dev_info(&dev->dev, "Fixing up AMD8131 IOAPIC mode\n"); | ||
| 622 | pci_read_config_byte( dev, AMD8131_MISC, &tmp); | ||
| 623 | tmp &= ~(1 << AMD8131_NIOAMODE_BIT); | ||
| 624 | pci_write_config_byte( dev, AMD8131_MISC, tmp); | ||
| 625 | } | ||
| 626 | } | ||
| 627 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic); | ||
| 628 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic); | ||
| 629 | #endif /* CONFIG_X86_IO_APIC */ | 609 | #endif /* CONFIG_X86_IO_APIC */ |
| 630 | 610 | ||
| 631 | /* | 611 | /* |
| @@ -1422,6 +1402,155 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2609, quirk_intel_pcie_pm); | |||
| 1422 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x260a, quirk_intel_pcie_pm); | 1402 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x260a, quirk_intel_pcie_pm); |
| 1423 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x260b, quirk_intel_pcie_pm); | 1403 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x260b, quirk_intel_pcie_pm); |
| 1424 | 1404 | ||
| 1405 | #ifdef CONFIG_X86_IO_APIC | ||
| 1406 | /* | ||
| 1407 | * Boot interrupts on some chipsets cannot be turned off. For these chipsets, | ||
| 1408 | * remap the original interrupt in the linux kernel to the boot interrupt, so | ||
| 1409 | * that a PCI device's interrupt handler is installed on the boot interrupt | ||
| 1410 | * line instead. | ||
| 1411 | */ | ||
| 1412 | static void quirk_reroute_to_boot_interrupts_intel(struct pci_dev *dev) | ||
| 1413 | { | ||
| 1414 | if (noioapicquirk || noioapicreroute) | ||
| 1415 | return; | ||
| 1416 | |||
| 1417 | dev->irq_reroute_variant = INTEL_IRQ_REROUTE_VARIANT; | ||
| 1418 | |||
| 1419 | printk(KERN_INFO "PCI quirk: reroute interrupts for 0x%04x:0x%04x\n", | ||
| 1420 | dev->vendor, dev->device); | ||
| 1421 | return; | ||
| 1422 | } | ||
| 1423 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80333_0, quirk_reroute_to_boot_interrupts_intel); | ||
| 1424 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80333_1, quirk_reroute_to_boot_interrupts_intel); | ||
| 1425 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_0, quirk_reroute_to_boot_interrupts_intel); | ||
| 1426 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXH_0, quirk_reroute_to_boot_interrupts_intel); | ||
| 1427 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXH_1, quirk_reroute_to_boot_interrupts_intel); | ||
| 1428 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXHV, quirk_reroute_to_boot_interrupts_intel); | ||
| 1429 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80332_0, quirk_reroute_to_boot_interrupts_intel); | ||
| 1430 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80332_1, quirk_reroute_to_boot_interrupts_intel); | ||
| 1431 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80333_0, quirk_reroute_to_boot_interrupts_intel); | ||
| 1432 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80333_1, quirk_reroute_to_boot_interrupts_intel); | ||
| 1433 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_0, quirk_reroute_to_boot_interrupts_intel); | ||
| 1434 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXH_0, quirk_reroute_to_boot_interrupts_intel); | ||
| 1435 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXH_1, quirk_reroute_to_boot_interrupts_intel); | ||
| 1436 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXHV, quirk_reroute_to_boot_interrupts_intel); | ||
| 1437 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80332_0, quirk_reroute_to_boot_interrupts_intel); | ||
| 1438 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80332_1, quirk_reroute_to_boot_interrupts_intel); | ||
| 1439 | |||
| 1440 | /* | ||
| 1441 | * On some chipsets we can disable the generation of legacy INTx boot | ||
| 1442 | * interrupts. | ||
| 1443 | */ | ||
| 1444 | |||
| 1445 | /* | ||
| 1446 | * IO-APIC1 on 6300ESB generates boot interrupts, see intel order no | ||
| 1447 | * 300641-004US, section 5.7.3. | ||
| 1448 | */ | ||
| 1449 | #define INTEL_6300_IOAPIC_ABAR 0x40 | ||
| 1450 | #define INTEL_6300_DISABLE_BOOT_IRQ (1<<14) | ||
| 1451 | |||
| 1452 | static void quirk_disable_intel_boot_interrupt(struct pci_dev *dev) | ||
| 1453 | { | ||
| 1454 | u16 pci_config_word; | ||
| 1455 | |||
| 1456 | if (noioapicquirk) | ||
| 1457 | return; | ||
| 1458 | |||
| 1459 | pci_read_config_word(dev, INTEL_6300_IOAPIC_ABAR, &pci_config_word); | ||
| 1460 | pci_config_word |= INTEL_6300_DISABLE_BOOT_IRQ; | ||
| 1461 | pci_write_config_word(dev, INTEL_6300_IOAPIC_ABAR, pci_config_word); | ||
| 1462 | |||
| 1463 | printk(KERN_INFO "disabled boot interrupt on device 0x%04x:0x%04x\n", | ||
| 1464 | dev->vendor, dev->device); | ||
| 1465 | } | ||
| 1466 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_10, quirk_disable_intel_boot_interrupt); | ||
| 1467 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_10, quirk_disable_intel_boot_interrupt); | ||
| 1468 | |||
| 1469 | /* | ||
| 1470 | * disable boot interrupts on HT-1000 | ||
| 1471 | */ | ||
| 1472 | #define BC_HT1000_FEATURE_REG 0x64 | ||
| 1473 | #define BC_HT1000_PIC_REGS_ENABLE (1<<0) | ||
| 1474 | #define BC_HT1000_MAP_IDX 0xC00 | ||
| 1475 | #define BC_HT1000_MAP_DATA 0xC01 | ||
| 1476 | |||
| 1477 | static void quirk_disable_broadcom_boot_interrupt(struct pci_dev *dev) | ||
| 1478 | { | ||
| 1479 | u32 pci_config_dword; | ||
| 1480 | u8 irq; | ||
| 1481 | |||
| 1482 | if (noioapicquirk) | ||
| 1483 | return; | ||
| 1484 | |||
| 1485 | pci_read_config_dword(dev, BC_HT1000_FEATURE_REG, &pci_config_dword); | ||
| 1486 | pci_write_config_dword(dev, BC_HT1000_FEATURE_REG, pci_config_dword | | ||
| 1487 | BC_HT1000_PIC_REGS_ENABLE); | ||
| 1488 | |||
| 1489 | for (irq = 0x10; irq < 0x10 + 32; irq++) { | ||
| 1490 | outb(irq, BC_HT1000_MAP_IDX); | ||
| 1491 | outb(0x00, BC_HT1000_MAP_DATA); | ||
| 1492 | } | ||
| 1493 | |||
| 1494 | pci_write_config_dword(dev, BC_HT1000_FEATURE_REG, pci_config_dword); | ||
| 1495 | |||
| 1496 | printk(KERN_INFO "disabled boot interrupts on PCI device" | ||
| 1497 | "0x%04x:0x%04x\n", dev->vendor, dev->device); | ||
| 1498 | } | ||
| 1499 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000SB, quirk_disable_broadcom_boot_interrupt); | ||
| 1500 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000SB, quirk_disable_broadcom_boot_interrupt); | ||
| 1501 | |||
| 1502 | /* | ||
| 1503 | * disable boot interrupts on AMD and ATI chipsets | ||
| 1504 | */ | ||
| 1505 | /* | ||
| 1506 | * NOIOAMODE needs to be disabled to disable "boot interrupts". For AMD 8131 | ||
| 1507 | * rev. A0 and B0, NOIOAMODE needs to be disabled anyway to fix IO-APIC mode | ||
| 1508 | * (due to an erratum). | ||
| 1509 | */ | ||
| 1510 | #define AMD_813X_MISC 0x40 | ||
| 1511 | #define AMD_813X_NOIOAMODE (1<<0) | ||
| 1512 | |||
| 1513 | static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev) | ||
| 1514 | { | ||
| 1515 | u32 pci_config_dword; | ||
| 1516 | |||
| 1517 | if (noioapicquirk) | ||
| 1518 | return; | ||
| 1519 | |||
| 1520 | pci_read_config_dword(dev, AMD_813X_MISC, &pci_config_dword); | ||
| 1521 | pci_config_dword &= ~AMD_813X_NOIOAMODE; | ||
| 1522 | pci_write_config_dword(dev, AMD_813X_MISC, pci_config_dword); | ||
| 1523 | |||
| 1524 | printk(KERN_INFO "disabled boot interrupts on PCI device " | ||
| 1525 | "0x%04x:0x%04x\n", dev->vendor, dev->device); | ||
| 1526 | } | ||
| 1527 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_amd_813x_boot_interrupt); | ||
| 1528 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8132_BRIDGE, quirk_disable_amd_813x_boot_interrupt); | ||
| 1529 | |||
| 1530 | #define AMD_8111_PCI_IRQ_ROUTING 0x56 | ||
| 1531 | |||
| 1532 | static void quirk_disable_amd_8111_boot_interrupt(struct pci_dev *dev) | ||
| 1533 | { | ||
| 1534 | u16 pci_config_word; | ||
| 1535 | |||
| 1536 | if (noioapicquirk) | ||
| 1537 | return; | ||
| 1538 | |||
| 1539 | pci_read_config_word(dev, AMD_8111_PCI_IRQ_ROUTING, &pci_config_word); | ||
| 1540 | if (!pci_config_word) { | ||
| 1541 | printk(KERN_INFO "boot interrupts on PCI device 0x%04x:0x%04x " | ||
| 1542 | "already disabled\n", | ||
| 1543 | dev->vendor, dev->device); | ||
| 1544 | return; | ||
| 1545 | } | ||
| 1546 | pci_write_config_word(dev, AMD_8111_PCI_IRQ_ROUTING, 0); | ||
| 1547 | printk(KERN_INFO "disabled boot interrupts on PCI device " | ||
| 1548 | "0x%04x:0x%04x\n", dev->vendor, dev->device); | ||
| 1549 | } | ||
| 1550 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_SMBUS, quirk_disable_amd_8111_boot_interrupt); | ||
| 1551 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_SMBUS, quirk_disable_amd_8111_boot_interrupt); | ||
| 1552 | #endif /* CONFIG_X86_IO_APIC */ | ||
| 1553 | |||
| 1425 | /* | 1554 | /* |
| 1426 | * Toshiba TC86C001 IDE controller reports the standard 8-byte BAR0 size | 1555 | * Toshiba TC86C001 IDE controller reports the standard 8-byte BAR0 size |
| 1427 | * but the PIO transfers won't work if BAR0 falls at the odd 8 bytes. | 1556 | * but the PIO transfers won't work if BAR0 falls at the odd 8 bytes. |
| @@ -1828,6 +1957,22 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, | |||
| 1828 | PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB, | 1957 | PCI_DEVICE_ID_SERVERWORKS_HT1000_PXB, |
| 1829 | ht_enable_msi_mapping); | 1958 | ht_enable_msi_mapping); |
| 1830 | 1959 | ||
| 1960 | /* The P5N32-SLI Premium motherboard from Asus has a problem with msi | ||
| 1961 | * for the MCP55 NIC. It is not yet determined whether the msi problem | ||
| 1962 | * also affects other devices. As for now, turn off msi for this device. | ||
| 1963 | */ | ||
| 1964 | static void __devinit nvenet_msi_disable(struct pci_dev *dev) | ||
| 1965 | { | ||
| 1966 | if (dmi_name_in_vendors("P5N32-SLI PREMIUM")) { | ||
| 1967 | dev_info(&dev->dev, | ||
| 1968 | "Disabling msi for MCP55 NIC on P5N32-SLI Premium\n"); | ||
| 1969 | dev->no_msi = 1; | ||
| 1970 | } | ||
| 1971 | } | ||
| 1972 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, | ||
| 1973 | PCI_DEVICE_ID_NVIDIA_NVENET_15, | ||
| 1974 | nvenet_msi_disable); | ||
| 1975 | |||
| 1831 | static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev) | 1976 | static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev) |
| 1832 | { | 1977 | { |
| 1833 | struct pci_dev *host_bridge; | 1978 | struct pci_dev *host_bridge; |
