Author: adrian Date: Fri May 20 00:49:10 2016 New Revision: 300251 URL: https://svnweb.freebsd.org/changeset/base/300251
Log: [bhnd] Add bhnd bridge support for bus_adjust_resource(). Adds support for adjusting active bus resource allocations, limiting the range to the constraints of the register window within which the resource is mapped. This is the final set of bhnd changes required to support delegating ChipCommon's register space to child devices. Submitted by: Landon Fuller <land...@landonf.org> Differential Revision: https://reviews.freebsd.org/D6470 Modified: head/sys/dev/bhnd/bhndb/bhndb.c head/sys/dev/bhnd/bhndb/bhndb_private.h head/sys/dev/bhnd/bhndb/bhndb_subr.c Modified: head/sys/dev/bhnd/bhndb/bhndb.c ============================================================================== --- head/sys/dev/bhnd/bhndb/bhndb.c Fri May 20 00:45:16 2016 (r300250) +++ head/sys/dev/bhnd/bhndb/bhndb.c Fri May 20 00:49:10 2016 (r300251) @@ -1144,11 +1144,16 @@ bhndb_adjust_resource(device_t dev, devi { struct bhndb_softc *sc; struct rman *rm; + rman_res_t mstart, mend; int error; sc = device_get_softc(dev); error = 0; + /* Verify basic constraints */ + if (end <= start) + return (EINVAL); + /* Fetch resource manager */ rm = bhndb_get_rman(sc, child, type); if (rm == NULL) @@ -1157,16 +1162,29 @@ bhndb_adjust_resource(device_t dev, devi if (!rman_is_region_manager(r, rm)) return (ENXIO); - /* If active, adjustment is limited by the assigned window. */ BHNDB_LOCK(sc); - // TODO: Currently unsupported - error = ENODEV; + /* If not active, allow any range permitted by the resource manager */ + if (!(rman_get_flags(r) & RF_ACTIVE)) + goto done; + + /* Otherwise, the range is limited to the existing register window + * mapping */ + error = bhndb_find_resource_limits(sc->bus_res, r, &mstart, &mend); + if (error) + goto done; - BHNDB_UNLOCK(sc); + if (start < mstart || end > mend) { + error = EINVAL; + goto done; + } + + /* Fall through */ +done: if (!error) error = rman_adjust_resource(r, start, end); + BHNDB_UNLOCK(sc); return (error); } @@ -1536,7 +1554,8 @@ bhndb_activate_bhnd_resource(device_t de if (bhndb_get_addrspace(sc, child) == BHNDB_ADDRSPACE_BRIDGED) { bhndb_priority_t r_prio; - region = bhndb_find_resource_region(sc->bus_res, r_start, r_size); + region = bhndb_find_resource_region(sc->bus_res, r_start, + r_size); if (region != NULL) r_prio = region->priority; else Modified: head/sys/dev/bhnd/bhndb/bhndb_private.h ============================================================================== --- head/sys/dev/bhnd/bhndb/bhndb_private.h Fri May 20 00:45:16 2016 (r300250) +++ head/sys/dev/bhnd/bhndb/bhndb_private.h Fri May 20 00:49:10 2016 (r300251) @@ -71,6 +71,11 @@ int bhndb_add_resource_region( bhndb_priority_t priority, const struct bhndb_regwin *static_regwin); +int bhndb_find_resource_limits( + struct bhndb_resources *br, + struct resource *r, rman_res_t *start, + rman_res_t *end); + struct bhndb_region *bhndb_find_resource_region( struct bhndb_resources *br, bhnd_addr_t addr, bhnd_size_t size); @@ -133,7 +138,7 @@ const struct bhndb_hw_priority *bhndb_hw * Dynamic register window allocation reference. */ struct bhndb_dw_rentry { - struct resource *dw_res; /**< child resource */ + struct resource *dw_res; /**< child resource */ LIST_ENTRY(bhndb_dw_rentry) dw_link; }; Modified: head/sys/dev/bhnd/bhndb/bhndb_subr.c ============================================================================== --- head/sys/dev/bhnd/bhndb/bhndb_subr.c Fri May 20 00:45:16 2016 (r300250) +++ head/sys/dev/bhnd/bhndb/bhndb_subr.c Fri May 20 00:49:10 2016 (r300251) @@ -563,8 +563,52 @@ bhndb_add_resource_region(struct bhndb_r return (0); } + +/** + * Find the maximum start and end limits of the register window mapping + * resource @p r. + * + * If the memory range is not mapped by an existing dynamic or static register + * window, ENOENT will be returned. + * + * @param br The resource state to search. + * @param r The resource to search for in @p br. + * @param addr The requested starting address. + * @param size The requested size. + * + * @retval bhndb_region A region that fully contains the requested range. + * @retval NULL If no mapping region can be found. + */ +int +bhndb_find_resource_limits(struct bhndb_resources *br, struct resource *r, + rman_res_t *start, rman_res_t *end) +{ + struct bhndb_dw_alloc *dynamic; + struct bhndb_region *sregion; + + /* Check for an enclosing dynamic register window */ + if ((dynamic = bhndb_dw_find_resource(br, r))) { + *start = dynamic->target; + *end = dynamic->target + dynamic->win->win_size - 1; + return (0); + } + + /* Check for a static region */ + sregion = bhndb_find_resource_region(br, rman_get_start(r), + rman_get_size(r)); + if (sregion != NULL && sregion->static_regwin != NULL) { + *start = sregion->addr; + *end = sregion->addr + sregion->size - 1; + + return (0); + } + + /* Not found */ + return (ENOENT); +} + /** - * Find a bus region that maps @p size bytes at @p addr. + * Find the bus region that maps @p size bytes at @p addr. * * @param br The resource state to search. * @param addr The requested starting address. _______________________________________________ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"