FreeBSD/sys/dev/bhnd/bhndb/bhndb.c
/**
 * Activate a resource using any viable static or dynamic register window.
 * 
 * @param sc The bhndb driver state.
 * @param child The child holding ownership of @p r.
 * @param type The type of the resource to be activated.
 * @param rid The resource ID of @p r.
 * @param r The resource to be activated
 * @param[out] indirect On error and if not NULL, will be set to 'true' if
 * the caller should instead use an indirect resource mapping.
 * 
 * @retval 0 success
 * @retval non-zero activation failed.
 */
Activate a resource using any viable static or dynamic register window.

@param sc The bhndb driver state.
@param child The child holding ownership of @p r.
@param type The type of the resource to be activated.
@param rid The resource ID of @p r.
@param r The resource to be activated
@param[out] indirect On error and if not NULL, will be set to 'true' if
the caller should instead use an indirect resource mapping.

@retval 0 success
@retval non-zero activation failed.
Activate a resource using any viable static or dynamic register window . @param sc The bhndb driver state . @param child The child holding ownership of @p r . @param type The type of the resource to be activated . @param rid The resource ID of @p r . @param r The resource to be activated @param [ out ] indirect On error and if not NULL will be set to ' true ' if the caller should instead use an indirect resource mapping . @retval 0 success @retval non - zero activation failed .
static int
bhndb_try_activate_resource(struct bhndb_softc *sc, device_t child, int type,
    int rid, struct resource *r, bool *indirect)
{
	struct bhndb_region	*region;
	struct bhndb_dw_alloc	*dwa;
	bhndb_priority_t	 dw_priority;
	rman_res_t		 r_start, r_size;
	rman_res_t		 parent_offset;
	int			 error;
	BHNDB_LOCK_ASSERT(sc, MA_NOTOWNED);
	if (type != SYS_RES_MEMORY)
		return (ENXIO);
	if (indirect)
		*indirect = false;
	r_start = rman_get_start(r);
	r_size = rman_get_size(r);
	if (bhndb_get_addrspace(sc, child) == BHNDB_ADDRSPACE_NATIVE) {
		struct resource *parent;
		parent = bhndb_find_resource_range(sc->bus_res, r_start,
		    r_size);
		if (parent == NULL) {
			device_printf(sc->dev, "host resource not found "
			     "for 0x%llx-0x%llx\n",
			     (unsigned long long) r_start,
			     (unsigned long long) r_start + r_size - 1);
			return (ENOENT);
		}
		error = bhndb_init_child_resource(r, parent,
		    r_start - rman_get_start(parent), r_size);
		if (error)
			return (error);
		return (rman_activate_resource(r));
	}
	dw_priority = BHNDB_PRIORITY_LOW;
	region = bhndb_find_resource_region(sc->bus_res, r_start, r_size);
	if (region != NULL)
		dw_priority = region->priority;
	if (region && region->static_regwin) {
		error = bhndb_activate_static_region(sc, region, child, type,
		    rid, r);
		if (error)
			device_printf(sc->dev, "static window allocation "
			     "for 0x%llx-0x%llx failed\n",
			     (unsigned long long) r_start,
			     (unsigned long long) r_start + r_size - 1);
		return (error);
	}
	if (dw_priority < sc->bus_res->min_prio) {
		if (indirect)
			*indirect = true;
		return (ENOMEM);
	}
	BHNDB_LOCK(sc); {
		dwa = bhndb_retain_dynamic_window(sc, r);
	} BHNDB_UNLOCK(sc);
	if (dwa == NULL) {
		if (indirect)
			*indirect = true;
		return (ENOMEM);
	}
	parent_offset = dwa->win->win_offset;
	parent_offset += r_start - dwa->target;
	error = bhndb_init_child_resource(r, dwa->parent_res, parent_offset,
	    dwa->win->win_size);
	if (error)
		goto failed;
	if ((error = rman_activate_resource(r)))
		goto failed;
	return (0);
failed:
	BHNDB_LOCK(sc);
	bhndb_dw_release(sc->bus_res, dwa, r);
	BHNDB_UNLOCK(sc);
	return (error);
}
static int bhndb_try_activate_resource ( struct bhndb_softc * sc , device_t child , int type , int rid , struct resource * r , bool * indirect ) { struct bhndb_region * region ; struct bhndb_dw_alloc * dwa ; bhndb_priority_t dw_priority ; rman_res_t r_start , r_size ; rman_res_t parent_offset ; int error ; BHNDB_LOCK_ASSERT ( sc , MA_NOTOWNED ) ; if ( type != SYS_RES_MEMORY ) return ( ENXIO ) ; if ( indirect ) * indirect = false ; r_start = rman_get_start ( r ) ; r_size = rman_get_size ( r ) ; if ( bhndb_get_addrspace ( sc , child ) == BHNDB_ADDRSPACE_NATIVE ) { struct resource * parent ; parent = bhndb_find_resource_range ( sc -> bus_res , r_start , r_size ) ; if ( parent == NULL ) { device_printf ( sc -> dev , " " " \n " , ( unsigned long long ) r_start , ( unsigned long long ) r_start + r_size - 1 ) ; return ( ENOENT ) ; } error = bhndb_init_child_resource ( r , parent , r_start - rman_get_start ( parent ) , r_size ) ; if ( error ) return ( error ) ; return ( rman_activate_resource ( r ) ) ; } dw_priority = BHNDB_PRIORITY_LOW ; region = bhndb_find_resource_region ( sc -> bus_res , r_start , r_size ) ; if ( region != NULL ) dw_priority = region -> priority ; if ( region && region -> static_regwin ) { error = bhndb_activate_static_region ( sc , region , child , type , rid , r ) ; if ( error ) device_printf ( sc -> dev , " " " \n " , ( unsigned long long ) r_start , ( unsigned long long ) r_start + r_size - 1 ) ; return ( error ) ; } if ( dw_priority < sc -> bus_res -> min_prio ) { if ( indirect ) * indirect = true ; return ( ENOMEM ) ; } BHNDB_LOCK ( sc ) ; { dwa = bhndb_retain_dynamic_window ( sc , r ) ; } BHNDB_UNLOCK ( sc ) ; if ( dwa == NULL ) { if ( indirect ) * indirect = true ; return ( ENOMEM ) ; } parent_offset = dwa -> win -> win_offset ; parent_offset += r_start - dwa -> target ; error = bhndb_init_child_resource ( r , dwa -> parent_res , parent_offset , dwa -> win -> win_size ) ; if ( error ) goto failed ; if ( ( error = rman_activate_resource ( r ) ) ) goto failed ; return ( 0 ) ; failed : BHNDB_LOCK ( sc ) ; bhndb_dw_release ( sc -> bus_res , dwa , r ) ; BHNDB_UNLOCK ( sc ) ; return ( error ) ; }
Activate a resource using any viable static or dynamic register window.
Activate a resource using any viable static or dynamic register window .
// TODO - IRQs /* Activate native addrspace resources using the host address space */ /* Find the bridge resource referenced by the child */ /* Initialize child resource with the real bus values */ /* Try to activate child resource */ /* Default to low priority */ /* Look for a bus region matching the resource's address range */ /* Prefer static mappings over consuming a dynamic windows. */ /* A dynamic window will be required; is this resource high enough
	 * priority to be reserved a dynamic window? */ /* Find and retain a usable window */ /* Configure resource with its real bus values. */ /* Mark active */ /* Release our region allocation. */