From e575dde35923ef7c1d8d571509227ca93b77611c Mon Sep 17 00:00:00 2001 From: gallatin Date: Sun, 27 May 2001 22:22:03 +0000 Subject: finally fix intr routing on alphas such as the as500 after months of breakage: - call PCIB_ROUTE_INTERRUPT() regardless of how valid the intline looks. Some alphas leave garbage in the intline and leave the intr mapping to OS platform support routines that map slots/buses to intlines - Down in the alpha pci code, first try platform.pci_intr_route() and if it doesn't exist or returns garbage, just read the intline out of config space. tested on AS500 (garbage in intline) and UP1000 (PC-like, intline is valid) Note that a nice little hack like the APIC_IO section of pci_cfgregread() is not workable. This is because the calling interface for alpha_pci_route_interrupt() requires us to figure out the bus/slot/etc from a device_t. At pci_read_device() time, we don't have a device_t for the bus/slot/func in question. --- sys/alpha/pci/pcibus.c | 9 +++++++-- sys/dev/pci/pci.c | 6 +++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/sys/alpha/pci/pcibus.c b/sys/alpha/pci/pcibus.c index 71a3eb1..58363fa 100644 --- a/sys/alpha/pci/pcibus.c +++ b/sys/alpha/pci/pcibus.c @@ -40,6 +40,7 @@ #include #include +#include #include #include #include @@ -80,6 +81,8 @@ SYSCTL_LONG(_hw_chipset, OID_AUTO, hae_mask, CTLFLAG_RD, &chipset_hae_mask, 0, int alpha_pci_route_interrupt(device_t bus, device_t dev, int pin) { + int intline = 255; + /* * Validate requested pin number. */ @@ -87,8 +90,10 @@ alpha_pci_route_interrupt(device_t bus, device_t dev, int pin) return(255); if (platform.pci_intr_route) - return(platform.pci_intr_route(bus, dev, pin)); - return(255); + intline = platform.pci_intr_route(bus, dev, pin); + if (intline == 255) + intline = pci_read_config(dev, PCIR_INTLINE, 1); + return intline; } #ifdef DEV_ISA diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index 3da4d29..c4b2951 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -1207,7 +1207,11 @@ pci_alloc_resource(device_t dev, device_t child, int type, int *rid, * If device doesn't have an interrupt routed, and is deserving of * an interrupt, try to assign it one. */ - if ((type == SYS_RES_IRQ) && (cfg->intline == 255) && (cfg->intpin != 0)) { + if ((type == SYS_RES_IRQ) +#ifndef __alpha__ + && (cfg->intline == 255) && (cfg->intpin != 0) +#endif + ) { cfg->intline = PCIB_ROUTE_INTERRUPT(device_get_parent(dev), child, cfg->intpin); if (cfg->intline != 255) { -- cgit v1.1