PCI: do not route nonexistent PIRQs on ALI M1533/1543 IRQ router Some BIOS versions have link numbers 5..8 in PIRQ routing tables for ALI M1533, but the chip is configured for 4 PIRQ inputs. Attempts to configure these nonexistent PIRQs result in screaming IRQs. This patch disables PIRQ routing for links 5..8 if the chip is not configured for 8 PIRQ inputs. Signed-off-by: Sergey Vlasov --- arch/i386/pci/irq.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 files changed, 38 insertions(+), 0 deletions(-) 2a4412ddbbfb3a231af17dfffbb7b09abf79a2e0 diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c index 3ca59ca..aa768fa 100644 --- a/arch/i386/pci/irq.c +++ b/arch/i386/pci/irq.c @@ -216,6 +216,38 @@ static int pirq_ali_set(struct pci_dev * } /* + * ALI M1533/1543 can support either 4 or 8 PIRQ inputs. Trying to + * route PIRQs 5..8 when using 4 PIRQ inputs results in screaming IRQs. + * Of course, some BIOS versions have bogus PIRQ table entries. + */ +static int pirq_ali_m1533_is_valid(struct pci_dev *router, int pirq) +{ + if ((pirq >= 5) && (pirq <= 8)) { + u8 reg45; + pci_read_config_byte(router, 0x45, ®45); + if (!(reg45 & 0x80)) + return 0; + } + return 1; +} + +static int pirq_ali_m1533_get(struct pci_dev *router, struct pci_dev *dev, + int pirq) +{ + if (!pirq_ali_m1533_is_valid(router, pirq)) + return 0; + return pirq_ali_get(router, dev, pirq); +} + +static int pirq_ali_m1533_set(struct pci_dev *router, struct pci_dev *dev, + int pirq, int irq) +{ + if (!pirq_ali_m1533_is_valid(router, pirq)) + return 0; + return pirq_ali_set(router, dev, pirq, irq); +} + +/* * The Intel PIIX4 pirq rules are fairly simple: "pirq" is * just a pointer to the config space. */ @@ -681,6 +713,12 @@ static __init int ali_router_probe(struc switch(device) { case PCI_DEVICE_ID_AL_M1533: + printk(KERN_DEBUG "PCI: Using ALI M1533 IRQ Router\n"); + r->name = "ALI M1533"; + r->get = pirq_ali_m1533_get; + r->set = pirq_ali_m1533_set; + return 1; + case PCI_DEVICE_ID_AL_M1563: printk(KERN_DEBUG "PCI: Using ALI IRQ Router\n"); r->name = "ALI";