FreeBSD/sys/dev/bhnd/bhndb/bhndb.c
/**
 * Find the bridge resource to be used for I/O requests.
 * 
 * @param sc Bridge driver state.
 * @param addr The I/O target address.
 * @param size The size of the I/O operation to be performed at @p addr. 
 * @param[out] offset The offset within the returned resource at which
 * to perform the I/O request.
 */
Find the bridge resource to be used for I/O requests.

@param sc Bridge driver state.
@param addr The I/O target address.
@param size The size of the I/O operation to be performed at @p addr.
@param[out] offset The offset within the returned resource at which
to perform the I/O request.
Find the bridge resource to be used for I / O requests . @param sc Bridge driver state . @param addr The I / O target address . @param size The size of the I / O operation to be performed at @p addr . @param [ out ] offset The offset within the returned resource at which to perform the I / O request .
static inline struct bhndb_dw_alloc *
bhndb_io_resource(struct bhndb_softc *sc, bus_addr_t addr, bus_size_t size,
    bus_size_t *offset)
{
	struct bhndb_resources	*br;
	struct bhndb_dw_alloc	*dwa;
	int			 error;
	BHNDB_LOCK_ASSERT(sc, MA_OWNED);
	br = sc->bus_res;
	dwa = bhndb_dw_next_free(br);
	if (dwa == NULL) {
		dwa = bhndb_io_resource_slow(sc, addr, size, offset);
		if (dwa == NULL) {
			panic("register windows exhausted attempting to map "
			    "0x%llx-0x%llx\n", 
			    (unsigned long long) addr,
			    (unsigned long long) addr+size-1);
		}
		return (dwa);
	}
	if (addr < dwa->target || 
	   (dwa->target + dwa->win->win_size) - addr < size)
	{
		error = bhndb_dw_set_addr(sc->dev, sc->bus_res, dwa, addr,
		    size);
		if (error) {
		    panic("failed to set register window target mapping "
			    "0x%llx-0x%llx\n", 
			    (unsigned long long) addr,
			    (unsigned long long) addr+size-1);
		}
	}
	*offset = (addr - dwa->target) + dwa->win->win_offset;
	return (dwa);
}
static inline struct bhndb_dw_alloc * bhndb_io_resource ( struct bhndb_softc * sc , bus_addr_t addr , bus_size_t size , bus_size_t * offset ) { struct bhndb_resources * br ; struct bhndb_dw_alloc * dwa ; int error ; BHNDB_LOCK_ASSERT ( sc , MA_OWNED ) ; br = sc -> bus_res ; dwa = bhndb_dw_next_free ( br ) ; if ( dwa == NULL ) { dwa = bhndb_io_resource_slow ( sc , addr , size , offset ) ; if ( dwa == NULL ) { panic ( " " " \n " , ( unsigned long long ) addr , ( unsigned long long ) addr + size - 1 ) ; } return ( dwa ) ; } if ( addr < dwa -> target || ( dwa -> target + dwa -> win -> win_size ) - addr < size ) { error = bhndb_dw_set_addr ( sc -> dev , sc -> bus_res , dwa , addr , size ) ; if ( error ) { panic ( " " " \n " , ( unsigned long long ) addr , ( unsigned long long ) addr + size - 1 ) ; } } * offset = ( addr - dwa -> target ) + dwa -> win -> win_offset ; return ( dwa ) ; }
Find the bridge resource to be used for I/O requests.
Find the bridge resource to be used for I / O requests .
/* Try to fetch a free window */ /*
	 * If no dynamic windows are available, look for an existing
	 * region that maps the target range. 
	 * 
	 * If none are found, this is a child driver bug -- our window
	 * over-commit should only fail in the case where a child driver leaks
	 * resources, or perform operations out-of-order.
	 * 
	 * Broadcom HND chipsets are designed to not require register window
	 * swapping during execution; as long as the child devices are
	 * attached/detached correctly, using the hardware's required order
	 * of operations, there should always be a window available for the
	 * current operation.
	 */ /* Adjust the window if the I/O request won't fit in the current
	 * target range. */ /* Calculate the offset and return */