Index: mp_machdep.c =================================================================== RCS file: /usr/cvs/src/sys/i386/i386/mp_machdep.c,v retrieving revision 1.115.2.23 diff -u -r1.115.2.23 mp_machdep.c --- mp_machdep.c 13 May 2005 00:10:55 -0000 1.115.2.23 +++ mp_machdep.c 15 Jun 2005 15:51:55 -0000 @@ -1663,8 +1663,8 @@ #define SRCBUSID(I) (io_apic_ints[(I)].src_bus_id) #define SRCBUSDEVICE(I) ((io_apic_ints[(I)].src_bus_irq >> 2) & 0x1f) #define SRCBUSLINE(I) (io_apic_ints[(I)].src_bus_irq & 0x03) -int -pci_apic_irq(int pciBus, int pciDevice, int pciInt) +static int +pci_apic_irq_raw(int pciBus, int pciDevice, int pciInt) { int intr; @@ -1686,6 +1686,72 @@ return -1; /* NOT found */ } +static int +pci_apic_bus_present(int bus) +{ + int intr; + + for (intr = 0; intr < nintrs; ++intr) + if ((INTTYPE(intr) == 0) && (SRCBUSID(intr) == bus)) + return (1); + return (0); +} + +int +pci_apic_irq(int bus, int device, int pin) +{ + device_t dev, bus_dev, pcib; + int irq; + + pcib = NULL; +loop: + /* See if there is an exact match first. */ + printf("APIC_IO: trying to route %d:%d INT%c\n", bus, device, + pin + 'A' - 1); + irq = pci_apic_irq_raw(bus, device, pin); + if (irq != -1) + return (irq); + + /* If this bus has other entries but not this one, punt. */ + if (pci_apic_bus_present(bus)) + return (-1); + + /* Safety net, don't try to walk past bus 0. */ + if (bus == 0) + return (-1); + + /* + * Try to find ourself. Every device has a function of 0 and we are + * really just trying to find our parent, so assume a function of 0 + * to find either ourself or one of our siblings. If we are recursing + * up the chain, we need to find the previous bridge's parent bus + * instead. + */ + if (pcib == NULL) { + dev = pci_find_bsf(bus, device, 0); + if (dev == NULL) + return (-1); + } else + dev = pcib; + bus_dev = device_get_parent(dev); + if (bus_dev == NULL) + return (-1); + pcib = device_get_parent(bus_dev); + if (pcib == NULL) + return (-1); + + /* + * Do the swizzle thing. + * + * XXX: no error checking for the bus number here + * (valid, does it exist, etc.). + */ + bus = pcib_get_bus(pcib); + pin = (pci_get_slot(pcib) + (pin - 1)) % 4 + 1; + device = pci_get_slot(pcib); + goto loop; +} + int next_apic_irq(int irq) {