diff --git a/sys/dev/bhnd/bhndb/bhnd_bhndb.c b/sys/dev/bhnd/bhndb/bhnd_bhndb.c index 1834f2700e7e..8a9f650bd151 100644 --- a/sys/dev/bhnd/bhndb/bhnd_bhndb.c +++ b/sys/dev/bhnd/bhndb/bhnd_bhndb.c @@ -66,6 +66,17 @@ bhnd_bhndb_get_attach_type(device_t dev, device_t child) return (BHND_ATTACH_ADAPTER); } + +static bool +bhnd_bhndb_is_hw_disabled(device_t dev, device_t child) +{ + struct bhnd_core_info core = bhnd_get_core_info(child); + + /* Delegate to parent bridge */ + return (BHNDB_IS_CORE_DISABLED(device_get_parent(dev), dev, &core)); +} + + static device_t bhnd_bhndb_find_hostb_device(device_t dev) { @@ -112,6 +123,7 @@ bhnd_bhndb_pwrctl_ungate_clock(device_t dev, device_t child, static device_method_t bhnd_bhndb_methods[] = { /* BHND interface */ DEVMETHOD(bhnd_bus_get_attach_type, bhnd_bhndb_get_attach_type), + DEVMETHOD(bhnd_bus_is_hw_disabled, bhnd_bhndb_is_hw_disabled), DEVMETHOD(bhnd_bus_find_hostb_device, bhnd_bhndb_find_hostb_device), DEVMETHOD(bhnd_bus_read_board_info, bhnd_bhndb_read_board_info), diff --git a/sys/dev/bhnd/bhndb/bhndb.c b/sys/dev/bhnd/bhndb/bhndb.c index 77f98c0028a9..8ce6b839b611 100644 --- a/sys/dev/bhnd/bhndb/bhndb.c +++ b/sys/dev/bhnd/bhndb/bhndb.c @@ -85,8 +85,9 @@ static int bhndb_init_full_config(struct bhndb_softc *sc, static struct bhnd_core_info *bhndb_get_bridge_core(struct bhndb_softc *sc); -static bool bhndb_hw_matches(struct bhnd_core_info *cores, - u_int ncores, const struct bhndb_hw *hw); +static bool bhndb_hw_matches(struct bhndb_softc *sc, + struct bhnd_core_info *cores, u_int ncores, + const struct bhndb_hw *hw); static int bhndb_init_region_cfg(struct bhndb_softc *sc, bhnd_erom_t *erom, @@ -212,14 +213,15 @@ bhndb_get_bridge_core(struct bhndb_softc *sc) /** * Return true if @p cores matches the @p hw specification. - * + * + * @param sc BHNDB device state. * @param cores A device table to match against. * @param ncores The number of cores in @p cores. * @param hw The hardware description to be matched against. */ static bool -bhndb_hw_matches(struct bhnd_core_info *cores, u_int ncores, - const struct bhndb_hw *hw) +bhndb_hw_matches(struct bhndb_softc *sc, struct bhnd_core_info *cores, + u_int ncores, const struct bhndb_hw *hw) { for (u_int i = 0; i < hw->num_hw_reqs; i++) { const struct bhnd_core_match *match; @@ -229,7 +231,12 @@ bhndb_hw_matches(struct bhnd_core_info *cores, u_int ncores, found = false; for (u_int d = 0; d < ncores; d++) { - if (!bhnd_core_matches(&cores[d], match)) + struct bhnd_core_info *core = &cores[d]; + + if (BHNDB_IS_CORE_DISABLED(sc->dev, sc->bus_dev, core)) + continue; + + if (!bhnd_core_matches(core, match)) continue; found = true; @@ -353,7 +360,7 @@ bhndb_init_region_cfg(struct bhndb_softc *sc, bhnd_erom_t *erom, */ /* ... do not require bridge resources */ - if (BHNDB_BUS_IS_CORE_DISABLED(sc->parent_dev, sc->dev, core)) + if (BHNDB_IS_CORE_DISABLED(sc->dev, sc->bus_dev, core)) continue; /* ... do not have a priority table entry */ @@ -475,7 +482,7 @@ bhndb_find_hwspec(struct bhndb_softc *sc, struct bhnd_core_info *cores, /* Search for the first matching hardware config. */ hw_table = BHNDB_BUS_GET_HARDWARE_TABLE(sc->parent_dev, sc->dev); for (next = hw_table; next->hw_reqs != NULL; next++) { - if (!bhndb_hw_matches(cores, ncores, next)) + if (!bhndb_hw_matches(sc, cores, ncores, next)) continue; /* Found */ @@ -1166,30 +1173,27 @@ bhndb_get_chipid(device_t dev, device_t child) return (&sc->chipid); } - /** - * Default implementation of BHND_BUS_IS_HW_DISABLED(). + * Default implementation of BHNDB_IS_CORE_DISABLED(). */ static bool -bhndb_is_hw_disabled(device_t dev, device_t child) +bhndb_is_core_disabled(device_t dev, device_t child, + struct bhnd_core_info *core) { struct bhndb_softc *sc; struct bhnd_core_info *bridge_core; - struct bhnd_core_info core; sc = device_get_softc(dev); - core = bhnd_get_core_info(child); - /* Try to defer to the bhndb bus parent */ - if (BHNDB_BUS_IS_CORE_DISABLED(sc->parent_dev, dev, &core)) + if (BHNDB_BUS_IS_CORE_DISABLED(sc->parent_dev, dev, core)) return (true); /* Otherwise, we treat bridge-capable cores as unpopulated if they're * not the configured host bridge */ bridge_core = bhndb_get_bridge_core(sc); - if (BHND_DEVCLASS_SUPPORTS_HOSTB(bhnd_core_class(&core))) - return (!bhnd_cores_equal(&core, bridge_core)); + if (BHND_DEVCLASS_SUPPORTS_HOSTB(bhnd_core_class(core))) + return (!bhnd_cores_equal(core, bridge_core)); /* Assume the core is populated */ return (false); @@ -2153,12 +2157,12 @@ static device_method_t bhndb_methods[] = { /* BHNDB interface */ DEVMETHOD(bhndb_get_chipid, bhndb_get_chipid), + DEVMETHOD(bhndb_is_core_disabled, bhndb_is_core_disabled), DEVMETHOD(bhndb_get_hostb_core, bhndb_get_hostb_core), DEVMETHOD(bhndb_suspend_resource, bhndb_suspend_resource), DEVMETHOD(bhndb_resume_resource, bhndb_resume_resource), /* BHND interface */ - DEVMETHOD(bhnd_bus_is_hw_disabled, bhndb_is_hw_disabled), DEVMETHOD(bhnd_bus_get_chipid, bhndb_get_chipid), DEVMETHOD(bhnd_bus_activate_resource, bhndb_activate_bhnd_resource), DEVMETHOD(bhnd_bus_deactivate_resource, bhndb_deactivate_bhnd_resource), diff --git a/sys/dev/bhnd/bhndb/bhndb_if.m b/sys/dev/bhnd/bhndb/bhndb_if.m index 093bfc626143..3f9ebd237b2c 100644 --- a/sys/dev/bhnd/bhndb/bhndb_if.m +++ b/sys/dev/bhnd/bhndb/bhndb_if.m @@ -61,7 +61,14 @@ CODE { { panic("bhndb_populate_board_info unimplemented"); } - + + static int + bhndb_null_is_core_disabled(device_t dev, device_t child, + struct bhnd_core_info *core) + { + panic("bhndb_is_core_disabled unimplemented"); + } + static int bhndb_null_get_hostb_core(device_t dev, device_t child, struct bhnd_core_info *core) @@ -117,6 +124,24 @@ METHOD int populate_board_info { struct bhnd_board_info *info; } DEFAULT bhndb_null_populate_board_info; +/** + * Return true if the hardware required by @p core is unpopulated or + * otherwise unusable. + * + * In some cases, the core's pins may be left floating, or the hardware + * may otherwise be non-functional; this method allows the parent device + * to explicitly specify whether @p core should be disabled. + * + * @param dev The parent device of @p child. + * @param child The attached bhnd device. + * @param core A core discovered on @p child. + */ +METHOD bool is_core_disabled { + device_t dev; + device_t child; + struct bhnd_core_info *core; +} DEFAULT bhndb_null_is_core_disabled; + /** * Get the host bridge core info for the attached bhnd bus. *