diff --git a/sys/dev/ofw/ofw_bus_subr.c b/sys/dev/ofw/ofw_bus_subr.c index 26a675937c1..8c2d64af8bb 100644 --- a/sys/dev/ofw/ofw_bus_subr.c +++ b/sys/dev/ofw/ofw_bus_subr.c @@ -285,7 +285,7 @@ ofw_bus_lookup_imap(phandle_t node, struct ofw_bus_iinfo *ii, void *reg, * maskbuf must point to a buffer of length physsz + intrsz. * The interrupt is returned in result, which must point to a buffer of length * rintrsz (which gives the expected size of the mapped interrupt). - * Returns 1 if a mapping was found, 0 otherwise. + * Returns number of cells in the interrupt if a mapping was found, 0 otherwise. */ int ofw_bus_search_intrmap(void *intr, int intrsz, void *regs, int physsz, @@ -325,19 +325,13 @@ ofw_bus_search_intrmap(void *intr, int intrsz, void *regs, int physsz, tsz = physsz + intrsz + sizeof(phandle_t) + pintrsz; KASSERT(i >= tsz, ("ofw_bus_search_intrmap: truncated map")); - /* - * XXX: Apple hardware uses a second cell to set information - * on the interrupt trigger type. This information should - * be used somewhere to program the PIC. - */ - if (bcmp(ref, mptr, physsz + intrsz) == 0) { bcopy(mptr + physsz + intrsz + sizeof(parent), - result, rintrsz); + result, MIN(rintrsz, pintrsz)); if (iparent != NULL) *iparent = parent; - return (1); + return (pintrsz/sizeof(pcell_t)); } mptr += tsz; i -= tsz; diff --git a/sys/powerpc/ofw/ofw_pci.c b/sys/powerpc/ofw/ofw_pci.c index 957a8caed2f..b80f07a6687 100644 --- a/sys/powerpc/ofw/ofw_pci.c +++ b/sys/powerpc/ofw/ofw_pci.c @@ -256,7 +256,8 @@ ofw_pci_route_interrupt(device_t bus, device_t dev, int pin) { struct ofw_pci_softc *sc; struct ofw_pci_register reg; - uint32_t pintr, mintr; + uint32_t pintr, mintr[2]; + int intrcells; phandle_t iparent; uint8_t maskbuf[sizeof(reg) + sizeof(pintr)]; @@ -269,10 +270,15 @@ ofw_pci_route_interrupt(device_t bus, device_t dev, int pin) (pci_get_slot(dev) << OFW_PCI_PHYS_HI_DEVICESHIFT) | (pci_get_function(dev) << OFW_PCI_PHYS_HI_FUNCTIONSHIFT); - if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), &sc->sc_pci_iinfo, ®, - sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr), - &iparent, maskbuf)) - return (ofw_bus_map_intr(dev, iparent, mintr)); + intrcells = ofw_bus_lookup_imap(ofw_bus_get_node(dev), + &sc->sc_pci_iinfo, ®, sizeof(reg), &pintr, sizeof(pintr), + mintr, sizeof(mintr), &iparent, maskbuf); + if (intrcells) { + pintr = ofw_bus_map_intr(dev, iparent, mintr[0]); + if (intrcells == 2) + ofw_bus_config_intr(dev, pintr, mintr[1]); + return (pintr); + } /* Maybe it's a real interrupt, not an intpin */ if (pin > 4)