void * isa_intr_establish(isa_chipset_tag_t ic, int irq, int type, int level, int (*ih_fun)(void *), void *ih_arg) { struct pic *pic; int pin; #if NIOAPIC > 0 int mpih; struct ioapic_softc *ioapic; #endif pin = irq; pic = &i8259_pic; #if NIOAPIC > 0 if (mp_busses != NULL) { if (intr_find_mpmapping(mp_isa_bus, irq, &mpih) == 0 || intr_find_mpmapping(mp_eisa_bus, irq, &mpih) == 0) { if (!APIC_IRQ_ISLEGACY(mpih)) { pin = APIC_IRQ_PIN(mpih); ioapic = ioapic_find(APIC_IRQ_APIC(mpih)); if (ioapic == NULL) { printf("isa_intr_establish: " "unknown apic %d\n", APIC_IRQ_APIC(mpih)); return NULL; } pic = &ioapic->sc_pic; } } else printf("isa_intr_establish: no MP mapping found\n"); } #endif return intr_establish(irq, pic, pin, type, level, ih_fun, ih_arg, false); }
int pci_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *ihp) { pci_intr_pin_t pin = pa->pa_intrpin; pci_intr_line_t line = pa->pa_intrline; pci_chipset_tag_t ipc, pc = pa->pa_pc; #if NIOAPIC > 0 || NACPICA > 0 pci_intr_pin_t rawpin = pa->pa_rawintrpin; int bus, dev, func; #endif for (ipc = pc; ipc != NULL; ipc = ipc->pc_super) { if ((ipc->pc_present & PCI_OVERRIDE_INTR_MAP) == 0) continue; return (*ipc->pc_ov->ov_intr_map)(ipc->pc_ctx, pa, ihp); } if (pin == 0) { /* No IRQ used. */ goto bad; } *ihp = 0; if (pin > PCI_INTERRUPT_PIN_MAX) { aprint_normal("pci_intr_map: bad interrupt pin %d\n", pin); goto bad; } #if NIOAPIC > 0 || NACPICA > 0 KASSERT(rawpin >= PCI_INTERRUPT_PIN_A); KASSERT(rawpin <= PCI_INTERRUPT_PIN_D); pci_decompose_tag(pc, pa->pa_tag, &bus, &dev, &func); if (mp_busses != NULL) { /* * Note: PCI_INTERRUPT_PIN_A == 1 where intr_find_mpmapping * wants pci bus_pin encoding which uses INT_A == 0. */ if (intr_find_mpmapping(bus, (dev << 2) | (rawpin - PCI_INTERRUPT_PIN_A), ihp) == 0) { if (APIC_IRQ_LEGACY_IRQ(*ihp) == 0) *ihp |= line; return 0; } /* * No explicit PCI mapping found. This is not fatal, * we'll try the ISA (or possibly EISA) mappings next. */ } #endif /* * Section 6.2.4, `Miscellaneous Functions', says that 255 means * `unknown' or `no connection' on a PC. We assume that a device with * `no connection' either doesn't have an interrupt (in which case the * pin number should be 0, and would have been noticed above), or * wasn't configured by the BIOS (in which case we punt, since there's * no real way we can know how the interrupt lines are mapped in the * hardware). * * XXX * Since IRQ 0 is only used by the clock, and we can't actually be sure * that the BIOS did its job, we also recognize that as meaning that * the BIOS has not configured the device. */ if (line == 0 || line == X86_PCI_INTERRUPT_LINE_NO_CONNECTION) { aprint_normal("pci_intr_map: no mapping for pin %c (line=%02x)\n", '@' + pin, line); goto bad; } else { if (line >= NUM_LEGACY_IRQS) { aprint_normal("pci_intr_map: bad interrupt line %d\n", line); goto bad; } if (line == 2) { aprint_normal("pci_intr_map: changed line 2 to line 9\n"); line = 9; } } #if NIOAPIC > 0 || NACPICA > 0 if (mp_busses != NULL) { if (intr_find_mpmapping(mp_isa_bus, line, ihp) == 0) { if ((*ihp & 0xff) == 0) *ihp |= line; return 0; } #if NEISA > 0 if (intr_find_mpmapping(mp_eisa_bus, line, ihp) == 0) { if ((*ihp & 0xff) == 0) *ihp |= line; return 0; } #endif aprint_normal("pci_intr_map: bus %d dev %d func %d pin %d; line %d\n", bus, dev, func, pin, line); aprint_normal("pci_intr_map: no MP mapping found\n"); } #endif *ihp = line; return 0; bad: *ihp = -1; return 1; }
int pci_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *ihp) { int pin; int line; #if NIOAPIC > 0 int rawpin = pa->pa_rawintrpin; pci_chipset_tag_t pc = pa->pa_pc; int bus, dev, func; #endif pin = pa->pa_intrpin; line = pa->pa_intrline; #if 0 /* XXXX why is it always 0 ? */ if (pin == 0) { /* No IRQ used */ goto bad; } #endif if (pin > PCI_INTERRUPT_PIN_MAX) { printf("pci_intr_map: bad interrupt pin %d\n", pin); goto bad; } ihp->pirq = 0; #if NIOAPIC > 0 pci_decompose_tag(pc, pa->pa_tag, &bus, &dev, &func); if (mp_busses != NULL) { if (intr_find_mpmapping(bus, (dev<<2)|(rawpin-1), ihp) == 0) { if (ihp->pirq & APIC_INT_VIA_APIC) { /* make sure a new IRQ will be allocated */ ihp->pirq &= ~0xff; } else { ihp->pirq |= line; } goto end; } /* * No explicit PCI mapping found. This is not fatal, * we'll try the ISA (or possibly EISA) mappings next. */ } #endif if (line == 0 || line == X86_PCI_INTERRUPT_LINE_NO_CONNECTION) { printf("pci_intr_map: no mapping for pin %c (line=%02x)\n", '@' + pin, line); goto bad; } #ifdef DOM0OPS if (line >= NUM_LEGACY_IRQS) { printf("pci_intr_map: bad interrupt line %d\n", line); goto bad; } #endif if (line == 2) { printf("pci_intr_map: changed line 2 to line 9\n"); line = 9; } #if NIOAPIC > 0 if (mp_busses != NULL) { if (intr_find_mpmapping(mp_isa_bus, line, ihp) == 0) { if ((ihp->pirq & 0xff) == 0) ihp->pirq |= line; goto end; } printf("pci_intr_map: bus %d dev %d func %d pin %d; line %d\n", bus, dev, func, pin, line); printf("pci_intr_map: no MP mapping found\n"); } #endif /* NIOAPIC */ ihp->pirq = line; #if NIOAPIC > 0 end: #endif ihp->evtch = xen_intr_map(&ihp->pirq, IST_LEVEL); if (ihp->evtch == -1) goto bad; return 0; bad: ihp->pirq = -1; ihp->evtch = -1; return 1; }
int pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp) { int pin = pa->pa_intrpin; int line = pa->pa_intrline; #if NIOAPIC > 0 int rawpin = pa->pa_rawintrpin; pci_chipset_tag_t pc = pa->pa_pc; int bus, dev, func; int mppin; #endif if (pin == 0) { /* No IRQ used. */ goto bad; } if (pin > PCI_INTERRUPT_PIN_MAX) { printf("pci_intr_map: bad interrupt pin %d\n", pin); goto bad; } #if NIOAPIC > 0 pci_decompose_tag(pc, pa->pa_tag, &bus, &dev, &func); if (mp_busses != NULL) { mppin = (dev << 2)|(rawpin - 1); if (intr_find_mpmapping(bus, mppin, ihp) == 0) { *ihp |= line; return 0; } if (pa->pa_bridgetag) { int bridgebus, bridgedev; pci_decompose_tag(pc, *pa->pa_bridgetag, &bridgebus, &bridgedev, NULL); mppin = (bridgedev << 2)|((rawpin + dev - 1) & 0x3); if (intr_find_mpmapping(bridgebus, mppin, ihp) == 0) { *ihp |= line; return 0; } } /* * No explicit PCI mapping found. This is not fatal, * we'll try the ISA (or possibly EISA) mappings next. */ } #endif /* * Section 6.2.4, `Miscellaneous Functions', says that 255 means * `unknown' or `no connection' on a PC. We assume that a device with * `no connection' either doesn't have an interrupt (in which case the * pin number should be 0, and would have been noticed above), or * wasn't configured by the BIOS (in which case we punt, since there's * no real way we can know how the interrupt lines are mapped in the * hardware). * * XXX * Since IRQ 0 is only used by the clock, and we can't actually be sure * that the BIOS did its job, we also recognize that as meaning that * the BIOS has not configured the device. */ if (line == 0 || line == X86_PCI_INTERRUPT_LINE_NO_CONNECTION) { printf("pci_intr_map: no mapping for pin %c (line=%02x)\n", '@' + pin, line); goto bad; } else { if (line >= NUM_LEGACY_IRQS) { printf("pci_intr_map: bad interrupt line %d\n", line); goto bad; } if (line == 2) { printf("pci_intr_map: changed line 2 to line 9\n"); line = 9; } } #if NIOAPIC > 0 if (mp_busses != NULL) { if (mp_isa_bus != NULL && intr_find_mpmapping(mp_isa_bus->mb_idx, line, ihp) == 0) { *ihp |= line; return 0; } #if NEISA > 0 if (mp_eisa_bus != NULL && intr_find_mpmapping(mp_eisa_bus->mb_idx, line, ihp) == 0) { *ihp |= line; return 0; } #endif printf("pci_intr_map: bus %d dev %d func %d pin %d; line %d\n", bus, dev, func, pin, line); printf("pci_intr_map: no MP mapping found\n"); } #endif *ihp = line; return 0; bad: *ihp = -1; return 1; }