static int siba_erom_lookup_core(bhnd_erom_t *erom, const struct bhnd_core_match *desc, struct bhnd_core_info *core) { struct siba_erom *sc; struct bhnd_core_match imatch; sc = (struct siba_erom *)erom; /* We can't determine a core's unit number during the initial scan. */ imatch = *desc; imatch.m.match.core_unit = 0; /* Locate the first matching core */ for (u_int i = 0; i < sc->io.ncores; i++) { struct siba_core_id sid; struct bhnd_core_info ci; /* Read the core info */ sid = siba_eio_read_core_id(&sc->io, i, 0); ci = sid.core_info; /* Check for initial match */ if (!bhnd_core_matches(&ci, &imatch)) continue; /* Re-scan preceding cores to determine the unit number. */ for (u_int j = 0; j < i; j++) { sid = siba_eio_read_core_id(&sc->io, i, 0); /* Bump the unit number? */ if (sid.core_info.vendor == ci.vendor && sid.core_info.device == ci.device) ci.unit++; } /* Check for full match against now-valid unit number */ if (!bhnd_core_matches(&ci, desc)) continue; /* Matching core found */ *core = ci; return (0); } /* Not found */ return (ENOENT); }
/** * Return all quirk flags for the given @p cid and @p ci. */ static uint32_t bhndb_pci_get_core_quirks(struct bhnd_chipid *cid, struct bhnd_core_info *ci) { struct bhndb_pci_core *entry; struct bhndb_pci_quirk *qtable; uint32_t quirks; quirks = 0; /* No core entry? */ if ((entry = bhndb_pci_find_core(ci)) == NULL) return (quirks); /* No quirks? */ if ((qtable = entry->quirks) == NULL) return (quirks); for (size_t i = 0; !BHNDB_PCI_IS_QUIRK_END(&qtable[i]); i++) { struct bhndb_pci_quirk *q = &qtable[i]; if (!bhnd_chip_matches(cid, &q->chip_desc)) continue; if (!bhnd_core_matches(ci, &q->core_desc)) continue; quirks |= q->quirks; } return (quirks); }
/** * Return the device table entry for @p ci, or NULL if none. */ static struct bhndb_pci_core * bhndb_pci_find_core(struct bhnd_core_info *ci) { for (size_t i = 0; !BHNDB_PCI_IS_CORE_END(&bhndb_pci_cores[i]); i++) { struct bhndb_pci_core *entry = &bhndb_pci_cores[i]; if (bhnd_core_matches(ci, &entry->match)) return (entry); } return (NULL); }