aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/quirks.c
diff options
context:
space:
mode:
authorDaniel Drake <dsd@gentoo.org>2006-09-25 19:52:19 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-10-18 14:36:10 -0400
commit09d6029f43ebbe7307854abdae204c25d711ff94 (patch)
tree2966a065f57656720417d555a8beaf3303e192b3 /drivers/pci/quirks.c
parent9ef9977cabc1b2c1718ef6eb883caec8dcb80b4c (diff)
PCI: VIA IRQ quirk behaviour change
The most recent VIA IRQ quirk changes have broken various VIA devices for some users. We are not able to add these devices to the blacklist as they are also available in PCI-card form, and running the quirk on these devices brings us back to square one (running the VIA quirk on non-VIA boards where the quirk is not needed). This patch, based on suggestions from Sergey Vlasov, implements a scheme similar to but more restrictive than the scheme we had in 2.6.16 and earlier. It runs the quirk on all VIA hardware, but *only* if a VIA southbridge was detected on the system. To further reduce the amount of quirked devices, this patch includes a change suggested by Linus at http://lkml.org/lkml/2005/9/27/113 This ensures that devices bound to non-legacy IO-APIC interrupt lines are not quirked. We have made one change to Linus' suggestion: we do a comparison of ">15" rather than ">=15", as 15 is still in the legacy interrupt range. There is still a downside to this patch: if the user inserts a VIA PCI card into a VIA-based motherboard, in some circumstances the quirk will also run on the VIA PCI card. This corner case is hard to avoid. Signed-off-by: Daniel Drake <dsd@gentoo.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/pci/quirks.c')
-rw-r--r--drivers/pci/quirks.c43
1 files changed, 34 insertions, 9 deletions
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 23b599d6a9d5..e5425079cecd 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -648,11 +648,43 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_vi
648 * Some of the on-chip devices are actually '586 devices' so they are 648 * Some of the on-chip devices are actually '586 devices' so they are
649 * listed here. 649 * listed here.
650 */ 650 */
651
652static int via_irq_fixup_needed = -1;
653
654/*
655 * As some VIA hardware is available in PCI-card form, we need to restrict
656 * this quirk to VIA PCI hardware built onto VIA-based motherboards only.
657 * We try to locate a VIA southbridge before deciding whether the quirk
658 * should be applied.
659 */
660static const struct pci_device_id via_irq_fixup_tbl[] = {
661 {
662 .vendor = PCI_VENDOR_ID_VIA,
663 .device = PCI_ANY_ID,
664 .subvendor = PCI_ANY_ID,
665 .subdevice = PCI_ANY_ID,
666 .class = PCI_CLASS_BRIDGE_ISA << 8,
667 .class_mask = 0xffff00,
668 },
669 { 0, },
670};
671
651static void quirk_via_irq(struct pci_dev *dev) 672static void quirk_via_irq(struct pci_dev *dev)
652{ 673{
653 u8 irq, new_irq; 674 u8 irq, new_irq;
654 675
655 new_irq = dev->irq & 0xf; 676 if (via_irq_fixup_needed == -1)
677 via_irq_fixup_needed = pci_dev_present(via_irq_fixup_tbl);
678
679 if (!via_irq_fixup_needed)
680 return;
681
682 new_irq = dev->irq;
683
684 /* Don't quirk interrupts outside the legacy IRQ range */
685 if (!new_irq || new_irq > 15)
686 return;
687
656 pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); 688 pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
657 if (new_irq != irq) { 689 if (new_irq != irq) {
658 printk(KERN_INFO "PCI: VIA IRQ fixup for %s, from %d to %d\n", 690 printk(KERN_INFO "PCI: VIA IRQ fixup for %s, from %d to %d\n",
@@ -661,14 +693,7 @@ static void quirk_via_irq(struct pci_dev *dev)
661 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq); 693 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq);
662 } 694 }
663} 695}
664DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_0, quirk_via_irq); 696DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irq);
665DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, quirk_via_irq);
666DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, quirk_via_irq);
667DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_irq);
668DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235_USB_2, quirk_via_irq);
669DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_irq);
670DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_irq);
671DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, quirk_via_irq);
672 697
673/* 698/*
674 * VIA VT82C598 has its device ID settable and many BIOSes 699 * VIA VT82C598 has its device ID settable and many BIOSes