/* siba-specific implementation of BHNDB_ROUTE_INTERRUPTS() */ static int bhndb_pci_route_siba_interrupts(struct bhndb_pci_softc *sc, device_t child) { uint32_t sbintvec; u_int ivec; int error; KASSERT(sc->pci_quirks & BHNDB_PCI_QUIRK_SIBA_INTVEC, ("route_siba_interrupts not supported by this hardware")); /* Fetch the sbflag# for the child */ if ((error = bhnd_get_intr_ivec(child, 0, &ivec))) return (error); if (ivec > (sizeof(sbintvec)*8) - 1 /* aka '31' */) { /* This should never be an issue in practice */ device_printf(sc->dev, "cannot route interrupts to high " "sbflag# %u\n", ivec); return (ENXIO); } BHNDB_PCI_LOCK(sc); sbintvec = bhndb_pci_read_core(sc, SB0_REG_ABS(SIBA_CFG0_INTVEC), 4); sbintvec |= (1 << ivec); bhndb_pci_write_core(sc, SB0_REG_ABS(SIBA_CFG0_INTVEC), sbintvec, 4); BHNDB_PCI_UNLOCK(sc); return (0); }
/** * Read and parse identification registers for the given @p core_index. * * @param io EROM I/O context. * @param core_idx The core index. * @param unit The caller-specified unit number to be included in the return * value. */ static struct siba_core_id siba_eio_read_core_id(struct siba_erom_io *io, u_int core_idx, int unit) { uint32_t idhigh, idlow; idhigh = siba_eio_read_4(io, core_idx, SB0_REG_ABS(SIBA_CFG0_IDHIGH)); idlow = siba_eio_read_4(io, core_idx, SB0_REG_ABS(SIBA_CFG0_IDLOW)); return (siba_parse_core_id(idhigh, idlow, core_idx, unit)); }