[bhnd] Clean up bhnd resource handling and inherited bus methods
To facilitate use by SoC implementors working with bhnd-inheriting fdt/nexus drivers: * Splits bhnd_bus method implementations into generic bus implementations (bhnd_bus_generic) and generic bhnd(4) driver implementations (bhnd_generic) * Simplifies bhnd resource handling, allowing bhnd bus implementations to support bhnd resource activation by implementing the standard BUS_* resource APIs and BHND_BUS_ACTIVATE_RESOURCE(). Submitted by: Landon Fuller <landonf@landonf.org> Differential Revision: https://reviews.freebsd.org/D5758
This commit is contained in:
parent
d094c9b381
commit
240c5e5159
@ -90,11 +90,10 @@ static int compare_descending_probe_order(const void *lhs,
|
||||
const void *rhs);
|
||||
|
||||
/**
|
||||
* Helper function for implementing DEVICE_ATTACH().
|
||||
*
|
||||
* This function can be used to implement DEVICE_ATTACH() for bhnd(4)
|
||||
* bus implementations. It calls device_probe_and_attach() for each
|
||||
* of the device's children, in order.
|
||||
* Default bhnd(4) bus driver implementation of DEVICE_ATTACH().
|
||||
*
|
||||
* This implementation calls device_probe_and_attach() for each of the device's
|
||||
* children, in bhnd probe order.
|
||||
*/
|
||||
int
|
||||
bhnd_generic_attach(device_t dev)
|
||||
@ -120,12 +119,11 @@ bhnd_generic_attach(device_t dev)
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for implementing DEVICE_DETACH().
|
||||
*
|
||||
* This function can be used to implement DEVICE_DETACH() for bhnd(4)
|
||||
* bus implementations. It calls device_detach() for each
|
||||
* of the device's children, in reverse order, terminating if
|
||||
* any call to device_detach() fails.
|
||||
* Default bhnd(4) bus driver implementation of DEVICE_DETACH().
|
||||
*
|
||||
* This implementation calls device_detach() for each of the the device's
|
||||
* children, in reverse bhnd probe order, terminating if any call to
|
||||
* device_detach() fails.
|
||||
*/
|
||||
int
|
||||
bhnd_generic_detach(device_t dev)
|
||||
@ -156,12 +154,11 @@ cleanup:
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for implementing DEVICE_SHUTDOWN().
|
||||
* Default bhnd(4) bus driver implementation of DEVICE_SHUTDOWN().
|
||||
*
|
||||
* This function can be used to implement DEVICE_SHUTDOWN() for bhnd(4)
|
||||
* bus implementations. It calls device_shutdown() for each
|
||||
* of the device's children, in reverse order, terminating if
|
||||
* any call to device_shutdown() fails.
|
||||
* This implementation calls device_shutdown() for each of the device's
|
||||
* children, in reverse bhnd probe order, terminating if any call to
|
||||
* device_shutdown() fails.
|
||||
*/
|
||||
int
|
||||
bhnd_generic_shutdown(device_t dev)
|
||||
@ -192,12 +189,11 @@ cleanup:
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for implementing DEVICE_RESUME().
|
||||
*
|
||||
* This function can be used to implement DEVICE_RESUME() for bhnd(4)
|
||||
* bus implementations. It calls BUS_RESUME_CHILD() for each
|
||||
* of the device's children, in order, terminating if
|
||||
* any call to BUS_RESUME_CHILD() fails.
|
||||
* Default bhnd(4) bus driver implementation of DEVICE_RESUME().
|
||||
*
|
||||
* This implementation calls BUS_RESUME_CHILD() for each of the device's
|
||||
* children in bhnd probe order, terminating if any call to BUS_RESUME_CHILD()
|
||||
* fails.
|
||||
*/
|
||||
int
|
||||
bhnd_generic_resume(device_t dev)
|
||||
@ -227,14 +223,13 @@ cleanup:
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for implementing DEVICE_SUSPEND().
|
||||
*
|
||||
* This function can be used to implement DEVICE_SUSPEND() for bhnd(4)
|
||||
* bus implementations. It calls BUS_SUSPEND_CHILD() for each
|
||||
* of the device's children, in reverse order. If any call to
|
||||
* BUS_SUSPEND_CHILD() fails, the suspend operation is terminated and
|
||||
* any devices that were suspended are resumed immediately by calling
|
||||
* their BUS_RESUME_CHILD() methods.
|
||||
* Default bhnd(4) bus driver implementation of DEVICE_SUSPEND().
|
||||
*
|
||||
* This implementation calls BUS_SUSPEND_CHILD() for each of the device's
|
||||
* children in reverse bhnd probe order. If any call to BUS_SUSPEND_CHILD()
|
||||
* fails, the suspend operation is terminated and any devices that were
|
||||
* suspended are resumed immediately by calling their BUS_RESUME_CHILD()
|
||||
* methods.
|
||||
*/
|
||||
int
|
||||
bhnd_generic_suspend(device_t dev)
|
||||
@ -305,8 +300,8 @@ compare_descending_probe_order(const void *lhs, const void *rhs)
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for implementing BHND_BUS_GET_PROBE_ORDER().
|
||||
*
|
||||
* Default bhnd(4) bus driver implementation of BHND_BUS_GET_PROBE_ORDER().
|
||||
*
|
||||
* This implementation determines probe ordering based on the device's class
|
||||
* and other properties, including whether the device is serving as a host
|
||||
* bridge.
|
||||
@ -360,14 +355,14 @@ bhnd_generic_get_probe_order(device_t dev, device_t child)
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for implementing BHND_BUS_IS_REGION_VALID().
|
||||
* Default bhnd(4) bus driver implementation of BHND_BUS_IS_REGION_VALID().
|
||||
*
|
||||
* This implementation assumes that port and region numbers are 0-indexed and
|
||||
* are allocated non-sparsely, using BHND_BUS_GET_PORT_COUNT() and
|
||||
* BHND_BUS_GET_REGION_COUNT() to determine if @p port and @p region fall
|
||||
* within the defined range.
|
||||
*/
|
||||
bool
|
||||
static bool
|
||||
bhnd_generic_is_region_valid(device_t dev, device_t child,
|
||||
bhnd_port_type type, u_int port, u_int region)
|
||||
{
|
||||
@ -413,14 +408,14 @@ find_nvram_child(device_t dev)
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for implementing BHND_BUS_READ_NVRAM_VAR().
|
||||
* Default bhnd(4) bus driver implementation of BHND_BUS_READ_NVRAM_VAR().
|
||||
*
|
||||
* This implementation searches @p dev for a valid NVRAM device. If no NVRAM
|
||||
* child device is found on @p dev, the request is delegated to the
|
||||
* BHND_BUS_READ_NVRAM_VAR() method on the parent
|
||||
* of @p dev.
|
||||
*/
|
||||
int
|
||||
static int
|
||||
bhnd_generic_read_nvram_var(device_t dev, device_t child, const char *name,
|
||||
void *buf, size_t *size)
|
||||
{
|
||||
@ -435,7 +430,7 @@ bhnd_generic_read_nvram_var(device_t dev, device_t child, const char *name,
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for implementing BUS_PRINT_CHILD().
|
||||
* Default bhnd(4) bus driver implementation of BUS_PRINT_CHILD().
|
||||
*
|
||||
* This implementation requests the device's struct resource_list via
|
||||
* BUS_GET_RESOURCE_LIST.
|
||||
@ -463,7 +458,7 @@ bhnd_generic_print_child(device_t dev, device_t child)
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for implementing BUS_PRINT_CHILD().
|
||||
* Default bhnd(4) bus driver implementation of BUS_PROBE_NOMATCH().
|
||||
*
|
||||
* This implementation requests the device's struct resource_list via
|
||||
* BUS_GET_RESOURCE_LIST.
|
||||
@ -525,7 +520,7 @@ bhnd_child_pnpinfo_str(device_t dev, device_t child, char *buf,
|
||||
}
|
||||
|
||||
/**
|
||||
* Default implementation of implementing BUS_PRINT_CHILD().
|
||||
* Default implementation of BUS_CHILD_LOCATION_STR().
|
||||
*/
|
||||
static int
|
||||
bhnd_child_location_str(device_t dev, device_t child, char *buf,
|
||||
@ -585,215 +580,6 @@ bhnd_generic_resume_child(device_t dev, device_t child)
|
||||
return bus_generic_resume_child(dev, child);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for implementing BHND_BUS_IS_HOSTB_DEVICE().
|
||||
*
|
||||
* If a parent device is available, this implementation delegates the
|
||||
* request to the BHND_BUS_IS_HOSTB_DEVICE() method on the parent of @p dev.
|
||||
*
|
||||
* If no parent device is available (i.e. on a the bus root), false
|
||||
* is returned.
|
||||
*/
|
||||
bool
|
||||
bhnd_generic_is_hostb_device(device_t dev, device_t child) {
|
||||
if (device_get_parent(dev) != NULL)
|
||||
return (BHND_BUS_IS_HOSTB_DEVICE(device_get_parent(dev),
|
||||
child));
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for implementing BHND_BUS_IS_HW_DISABLED().
|
||||
*
|
||||
* If a parent device is available, this implementation delegates the
|
||||
* request to the BHND_BUS_IS_HW_DISABLED() method on the parent of @p dev.
|
||||
*
|
||||
* If no parent device is available (i.e. on a the bus root), the hardware
|
||||
* is assumed to be usable and false is returned.
|
||||
*/
|
||||
bool
|
||||
bhnd_generic_is_hw_disabled(device_t dev, device_t child)
|
||||
{
|
||||
if (device_get_parent(dev) != NULL)
|
||||
return (BHND_BUS_IS_HW_DISABLED(device_get_parent(dev), child));
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for implementing BHND_BUS_GET_CHIPID().
|
||||
*
|
||||
* This implementation delegates the request to the BHND_BUS_GET_CHIPID()
|
||||
* method on the parent of @p dev.
|
||||
*/
|
||||
const struct bhnd_chipid *
|
||||
bhnd_generic_get_chipid(device_t dev, device_t child) {
|
||||
return (BHND_BUS_GET_CHIPID(device_get_parent(dev), child));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for implementing BHND_BUS_ALLOC_RESOURCE().
|
||||
*
|
||||
* This simple implementation of BHND_BUS_ALLOC_RESOURCE() determines
|
||||
* any default values via BUS_GET_RESOURCE_LIST(), and calls
|
||||
* BHND_BUS_ALLOC_RESOURCE() method of the parent of @p dev.
|
||||
*
|
||||
* If no parent device is available, the request is instead delegated to
|
||||
* BUS_ALLOC_RESOURCE().
|
||||
*/
|
||||
struct bhnd_resource *
|
||||
bhnd_generic_alloc_bhnd_resource(device_t dev, device_t child, int type,
|
||||
int *rid, rman_res_t start, rman_res_t end, rman_res_t count,
|
||||
u_int flags)
|
||||
{
|
||||
struct bhnd_resource *r;
|
||||
struct resource_list *rl;
|
||||
struct resource_list_entry *rle;
|
||||
bool isdefault;
|
||||
bool passthrough;
|
||||
|
||||
passthrough = (device_get_parent(child) != dev);
|
||||
isdefault = RMAN_IS_DEFAULT_RANGE(start, end);
|
||||
|
||||
/* the default RID must always be the first device port/region. */
|
||||
if (!passthrough && *rid == 0) {
|
||||
int rid0 = bhnd_get_port_rid(child, BHND_PORT_DEVICE, 0, 0);
|
||||
KASSERT(*rid == rid0,
|
||||
("rid 0 does not map to the first device port (%d)", rid0));
|
||||
}
|
||||
|
||||
/* Determine locally-known defaults before delegating the request. */
|
||||
if (!passthrough && isdefault) {
|
||||
/* fetch resource list from child's bus */
|
||||
rl = BUS_GET_RESOURCE_LIST(dev, child);
|
||||
if (rl == NULL)
|
||||
return (NULL); /* no resource list */
|
||||
|
||||
/* look for matching type/rid pair */
|
||||
rle = resource_list_find(BUS_GET_RESOURCE_LIST(dev, child),
|
||||
type, *rid);
|
||||
if (rle == NULL)
|
||||
return (NULL);
|
||||
|
||||
/* set default values */
|
||||
start = rle->start;
|
||||
end = rle->end;
|
||||
count = ulmax(count, rle->count);
|
||||
}
|
||||
|
||||
/* Try to delegate to our parent. */
|
||||
if (device_get_parent(dev) != NULL) {
|
||||
return (BHND_BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
|
||||
type, rid, start, end, count, flags));
|
||||
}
|
||||
|
||||
/* If this is the bus root, use a real bus-allocated resource */
|
||||
r = malloc(sizeof(struct bhnd_resource), M_BHND, M_NOWAIT);
|
||||
if (r == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Allocate the bus resource, marking it as 'direct' (not requiring
|
||||
* any bus window remapping to perform I/O) */
|
||||
r->direct = true;
|
||||
r->res = BUS_ALLOC_RESOURCE(dev, child, type, rid, start, end,
|
||||
count, flags);
|
||||
|
||||
if (r->res == NULL) {
|
||||
free(r, M_BHND);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (r);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for implementing BHND_BUS_RELEASE_RESOURCE().
|
||||
*
|
||||
* This simple implementation of BHND_BUS_RELEASE_RESOURCE() simply calls the
|
||||
* BHND_BUS_RELEASE_RESOURCE() method of the parent of @p dev.
|
||||
*
|
||||
* If no parent device is available, the request is delegated to
|
||||
* BUS_RELEASE_RESOURCE().
|
||||
*/
|
||||
int
|
||||
bhnd_generic_release_bhnd_resource(device_t dev, device_t child, int type,
|
||||
int rid, struct bhnd_resource *r)
|
||||
{
|
||||
int error;
|
||||
|
||||
/* Try to delegate to the parent. */
|
||||
if (device_get_parent(dev) != NULL)
|
||||
return (BHND_BUS_RELEASE_RESOURCE(device_get_parent(dev), child,
|
||||
type, rid, r));
|
||||
|
||||
/* Release the resource directly */
|
||||
if (!r->direct) {
|
||||
panic("bhnd indirect resource released without "
|
||||
"bhnd parent bus");
|
||||
}
|
||||
|
||||
error = BUS_RELEASE_RESOURCE(dev, child, type, rid, r->res);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
free(r, M_BHND);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for implementing BHND_BUS_ACTIVATE_RESOURCE().
|
||||
*
|
||||
* This simple implementation of BHND_BUS_ACTIVATE_RESOURCE() simply calls the
|
||||
* BHND_BUS_ACTIVATE_RESOURCE() method of the parent of @p dev.
|
||||
*
|
||||
* If no parent device is available, the request is delegated to
|
||||
* BUS_ACTIVATE_RESOURCE().
|
||||
*/
|
||||
int
|
||||
bhnd_generic_activate_bhnd_resource(device_t dev, device_t child, int type,
|
||||
int rid, struct bhnd_resource *r)
|
||||
{
|
||||
/* Try to delegate to the parent */
|
||||
if (device_get_parent(dev) != NULL)
|
||||
return (BHND_BUS_ACTIVATE_RESOURCE(device_get_parent(dev),
|
||||
child, type, rid, r));
|
||||
|
||||
/* Activate the resource directly */
|
||||
if (!r->direct) {
|
||||
panic("bhnd indirect resource released without "
|
||||
"bhnd parent bus");
|
||||
}
|
||||
|
||||
return (BUS_ACTIVATE_RESOURCE(dev, child, type, rid, r->res));
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper function for implementing BHND_BUS_DEACTIVATE_RESOURCE().
|
||||
*
|
||||
* This simple implementation of BHND_BUS_ACTIVATE_RESOURCE() simply calls the
|
||||
* BHND_BUS_ACTIVATE_RESOURCE() method of the parent of @p dev.
|
||||
*
|
||||
* If no parent device is available, the request is delegated to
|
||||
* BUS_DEACTIVATE_RESOURCE().
|
||||
*/
|
||||
int
|
||||
bhnd_generic_deactivate_bhnd_resource(device_t dev, device_t child, int type,
|
||||
int rid, struct bhnd_resource *r)
|
||||
{
|
||||
if (device_get_parent(dev) != NULL)
|
||||
return (BHND_BUS_DEACTIVATE_RESOURCE(device_get_parent(dev),
|
||||
child, type, rid, r));
|
||||
|
||||
/* De-activate the resource directly */
|
||||
if (!r->direct) {
|
||||
panic("bhnd indirect resource released without "
|
||||
"bhnd parent bus");
|
||||
}
|
||||
|
||||
return (BUS_DEACTIVATE_RESOURCE(dev, child, type, rid, r->res));
|
||||
};
|
||||
|
||||
/*
|
||||
* Delegate all indirect I/O to the parent device. When inherited by
|
||||
* non-bridged bus implementations, resources will never be marked as
|
||||
@ -885,12 +671,12 @@ static device_method_t bhnd_methods[] = {
|
||||
DEVMETHOD(bus_get_dma_tag, bus_generic_get_dma_tag),
|
||||
|
||||
/* BHND interface */
|
||||
DEVMETHOD(bhnd_bus_alloc_resource, bhnd_generic_alloc_bhnd_resource),
|
||||
DEVMETHOD(bhnd_bus_release_resource, bhnd_generic_release_bhnd_resource),
|
||||
DEVMETHOD(bhnd_bus_activate_resource, bhnd_generic_activate_bhnd_resource),
|
||||
DEVMETHOD(bhnd_bus_activate_resource, bhnd_generic_deactivate_bhnd_resource),
|
||||
DEVMETHOD(bhnd_bus_get_chipid, bhnd_generic_get_chipid),
|
||||
DEVMETHOD(bhnd_bus_get_chipid, bhnd_bus_generic_get_chipid),
|
||||
DEVMETHOD(bhnd_bus_get_probe_order, bhnd_generic_get_probe_order),
|
||||
DEVMETHOD(bhnd_bus_is_region_valid, bhnd_generic_is_region_valid),
|
||||
DEVMETHOD(bhnd_bus_is_hostb_device, bhnd_bus_generic_is_hostb_device),
|
||||
DEVMETHOD(bhnd_bus_is_hw_disabled, bhnd_bus_generic_is_hw_disabled),
|
||||
DEVMETHOD(bhnd_bus_read_nvram_var, bhnd_generic_read_nvram_var),
|
||||
DEVMETHOD(bhnd_bus_read_1, bhnd_read_1),
|
||||
DEVMETHOD(bhnd_bus_read_2, bhnd_read_2),
|
||||
DEVMETHOD(bhnd_bus_read_4, bhnd_read_4),
|
||||
|
@ -293,6 +293,36 @@ int bhnd_read_chipid(device_t dev,
|
||||
void bhnd_set_generic_core_desc(device_t dev);
|
||||
|
||||
|
||||
|
||||
|
||||
bool bhnd_bus_generic_is_hostb_device(device_t dev,
|
||||
device_t child);
|
||||
bool bhnd_bus_generic_is_hw_disabled(device_t dev,
|
||||
device_t child);
|
||||
bool bhnd_bus_generic_is_region_valid(device_t dev,
|
||||
device_t child, bhnd_port_type type,
|
||||
u_int port, u_int region);
|
||||
int bhnd_bus_generic_read_nvram_var(device_t dev,
|
||||
device_t child, const char *name,
|
||||
void *buf, size_t *size);
|
||||
const struct bhnd_chipid *bhnd_bus_generic_get_chipid(device_t dev,
|
||||
device_t child);
|
||||
struct bhnd_resource *bhnd_bus_generic_alloc_resource (device_t dev,
|
||||
device_t child, int type, int *rid,
|
||||
rman_res_t start, rman_res_t end,
|
||||
rman_res_t count, u_int flags);
|
||||
int bhnd_bus_generic_release_resource (device_t dev,
|
||||
device_t child, int type, int rid,
|
||||
struct bhnd_resource *r);
|
||||
int bhnd_bus_generic_activate_resource (device_t dev,
|
||||
device_t child, int type, int rid,
|
||||
struct bhnd_resource *r);
|
||||
int bhnd_bus_generic_deactivate_resource (device_t dev,
|
||||
device_t child, int type, int rid,
|
||||
struct bhnd_resource *r);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return true if @p dev is serving as a host bridge for its parent bhnd
|
||||
* bus.
|
||||
|
@ -52,7 +52,25 @@ CODE {
|
||||
static struct bhnd_chipid *
|
||||
bhnd_bus_null_get_chipid(device_t dev, device_t child)
|
||||
{
|
||||
panic("bhnd_get_chipid unimplemented");
|
||||
panic("bhnd_bus_get_chipid unimplemented");
|
||||
}
|
||||
|
||||
static bool
|
||||
bhnd_bus_null_is_hostb_device(device_t dev, device_t child)
|
||||
{
|
||||
panic("bhnd_bus_is_hostb_device unimplemented");
|
||||
}
|
||||
|
||||
static bool
|
||||
bhnd_bus_null_is_hw_disabled(device_t dev, device_t child)
|
||||
{
|
||||
panic("bhnd_bus_is_hw_disabled unimplemented");
|
||||
}
|
||||
|
||||
static int
|
||||
bhnd_bus_null_get_probe_order(device_t dev, device_t child)
|
||||
{
|
||||
panic("bhnd_bus_get_probe_order unimplemented");
|
||||
}
|
||||
|
||||
static int
|
||||
@ -68,7 +86,7 @@ CODE {
|
||||
{
|
||||
return (ENOENT);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
bhnd_bus_null_get_region_addr(device_t dev, device_t child,
|
||||
bhnd_port_type type, u_int port, u_int region, bhnd_addr_t *addr,
|
||||
@ -83,6 +101,7 @@ CODE {
|
||||
{
|
||||
return (ENOENT);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -98,7 +117,7 @@ CODE {
|
||||
METHOD bool is_hostb_device {
|
||||
device_t dev;
|
||||
device_t child;
|
||||
} DEFAULT bhnd_generic_is_hostb_device;
|
||||
} DEFAULT bhnd_bus_null_is_hostb_device;
|
||||
|
||||
/**
|
||||
* Return true if the hardware components required by @p child are unpopulated
|
||||
@ -115,7 +134,7 @@ METHOD bool is_hostb_device {
|
||||
METHOD bool is_hw_disabled {
|
||||
device_t dev;
|
||||
device_t child;
|
||||
} DEFAULT bhnd_generic_is_hw_disabled;
|
||||
} DEFAULT bhnd_bus_null_is_hw_disabled;
|
||||
|
||||
/**
|
||||
* Return the probe (and attach) order for @p child.
|
||||
@ -147,7 +166,7 @@ METHOD bool is_hw_disabled {
|
||||
METHOD int get_probe_order {
|
||||
device_t dev;
|
||||
device_t child;
|
||||
} DEFAULT bhnd_generic_get_probe_order;
|
||||
} DEFAULT bhnd_bus_null_get_probe_order;
|
||||
|
||||
/**
|
||||
* Return the BHND chip identification for the parent bus.
|
||||
@ -205,7 +224,7 @@ METHOD struct bhnd_resource * alloc_resource {
|
||||
rman_res_t end;
|
||||
rman_res_t count;
|
||||
u_int flags;
|
||||
} DEFAULT bhnd_generic_alloc_bhnd_resource;
|
||||
} DEFAULT bhnd_bus_generic_alloc_resource;
|
||||
|
||||
/**
|
||||
* Release a bhnd resource.
|
||||
@ -219,7 +238,7 @@ METHOD int release_resource {
|
||||
int type;
|
||||
int rid;
|
||||
struct bhnd_resource *res;
|
||||
} DEFAULT bhnd_generic_release_bhnd_resource;
|
||||
} DEFAULT bhnd_bus_generic_release_resource;
|
||||
|
||||
/**
|
||||
* Activate a bhnd resource.
|
||||
@ -233,7 +252,7 @@ METHOD int activate_resource {
|
||||
int type;
|
||||
int rid;
|
||||
struct bhnd_resource *r;
|
||||
} DEFAULT bhnd_generic_activate_bhnd_resource;
|
||||
} DEFAULT bhnd_bus_generic_activate_resource;
|
||||
|
||||
/**
|
||||
* Deactivate a bhnd resource.
|
||||
@ -247,7 +266,7 @@ METHOD int deactivate_resource {
|
||||
int type;
|
||||
int rid;
|
||||
struct bhnd_resource *r;
|
||||
} DEFAULT bhnd_generic_deactivate_bhnd_resource;
|
||||
} DEFAULT bhnd_bus_generic_deactivate_resource;
|
||||
|
||||
/**
|
||||
* Return true if @p region_num is a valid region on @p port_num of
|
||||
@ -259,13 +278,13 @@ METHOD int deactivate_resource {
|
||||
* @param port_num The port number being queried.
|
||||
* @param region_num The region number being queried.
|
||||
*/
|
||||
METHOD u_int is_region_valid {
|
||||
METHOD bool is_region_valid {
|
||||
device_t dev;
|
||||
device_t child;
|
||||
bhnd_port_type type;
|
||||
u_int port_num;
|
||||
u_int region_num;
|
||||
} DEFAULT bhnd_generic_is_region_valid;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the number of ports of type @p type attached to @p child.
|
||||
@ -278,7 +297,7 @@ METHOD u_int get_port_count {
|
||||
device_t dev;
|
||||
device_t child;
|
||||
bhnd_port_type type;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the number of memory regions mapped to @p child @p port of
|
||||
@ -294,7 +313,7 @@ METHOD u_int get_region_count {
|
||||
device_t child;
|
||||
bhnd_port_type type;
|
||||
u_int port;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the SYS_RES_MEMORY resource-ID for a port/region pair attached to
|
||||
|
@ -646,3 +646,160 @@ bhnd_set_generic_core_desc(device_t dev)
|
||||
device_set_desc(dev, dev_name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for implementing BHND_BUS_IS_HOSTB_DEVICE().
|
||||
*
|
||||
* If a parent device is available, this implementation delegates the
|
||||
* request to the BHND_BUS_IS_HOSTB_DEVICE() method on the parent of @p dev.
|
||||
*
|
||||
* If no parent device is available (i.e. on a the bus root), false
|
||||
* is returned.
|
||||
*/
|
||||
bool
|
||||
bhnd_bus_generic_is_hostb_device(device_t dev, device_t child) {
|
||||
if (device_get_parent(dev) != NULL)
|
||||
return (BHND_BUS_IS_HOSTB_DEVICE(device_get_parent(dev),
|
||||
child));
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for implementing BHND_BUS_IS_HW_DISABLED().
|
||||
*
|
||||
* If a parent device is available, this implementation delegates the
|
||||
* request to the BHND_BUS_IS_HW_DISABLED() method on the parent of @p dev.
|
||||
*
|
||||
* If no parent device is available (i.e. on a the bus root), the hardware
|
||||
* is assumed to be usable and false is returned.
|
||||
*/
|
||||
bool
|
||||
bhnd_bus_generic_is_hw_disabled(device_t dev, device_t child)
|
||||
{
|
||||
if (device_get_parent(dev) != NULL)
|
||||
return (BHND_BUS_IS_HW_DISABLED(device_get_parent(dev), child));
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for implementing BHND_BUS_GET_CHIPID().
|
||||
*
|
||||
* This implementation delegates the request to the BHND_BUS_GET_CHIPID()
|
||||
* method on the parent of @p dev. If no parent exists, the implementation
|
||||
* will panic.
|
||||
*/
|
||||
const struct bhnd_chipid *
|
||||
bhnd_bus_generic_get_chipid(device_t dev, device_t child)
|
||||
{
|
||||
if (device_get_parent(dev) != NULL)
|
||||
return (BHND_BUS_GET_CHIPID(device_get_parent(dev), child));
|
||||
|
||||
panic("missing BHND_BUS_GET_CHIPID()");
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for implementing BHND_BUS_ALLOC_RESOURCE().
|
||||
*
|
||||
* This implementation of BHND_BUS_ALLOC_RESOURCE() delegates allocation
|
||||
* of the underlying resource to BUS_ALLOC_RESOURCE(), and activation
|
||||
* to @p dev's BHND_BUS_ACTIVATE_RESOURCE().
|
||||
*/
|
||||
struct bhnd_resource *
|
||||
bhnd_bus_generic_alloc_resource(device_t dev, device_t child, int type,
|
||||
int *rid, rman_res_t start, rman_res_t end, rman_res_t count,
|
||||
u_int flags)
|
||||
{
|
||||
struct bhnd_resource *br;
|
||||
struct resource *res;
|
||||
int error;
|
||||
|
||||
br = NULL;
|
||||
res = NULL;
|
||||
|
||||
/* Allocate the real bus resource (without activating it) */
|
||||
res = BUS_ALLOC_RESOURCE(dev, child, type, rid, start, end, count,
|
||||
(flags & ~RF_ACTIVE));
|
||||
if (res == NULL)
|
||||
return (NULL);
|
||||
|
||||
/* Allocate our bhnd resource wrapper. */
|
||||
br = malloc(sizeof(struct bhnd_resource), M_BHND, M_NOWAIT);
|
||||
if (br == NULL)
|
||||
goto failed;
|
||||
|
||||
br->direct = false;
|
||||
br->res = res;
|
||||
|
||||
/* Attempt activation */
|
||||
if (flags & RF_ACTIVE) {
|
||||
error = BHND_BUS_ACTIVATE_RESOURCE(dev, child, type, *rid, br);
|
||||
if (error)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
return (br);
|
||||
|
||||
failed:
|
||||
if (res != NULL)
|
||||
BUS_RELEASE_RESOURCE(dev, child, type, *rid, res);
|
||||
|
||||
free(br, M_BHND);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for implementing BHND_BUS_RELEASE_RESOURCE().
|
||||
*
|
||||
* This implementation of BHND_BUS_RELEASE_RESOURCE() delegates release of
|
||||
* the backing resource to BUS_RELEASE_RESOURCE().
|
||||
*/
|
||||
int
|
||||
bhnd_bus_generic_release_resource(device_t dev, device_t child, int type,
|
||||
int rid, struct bhnd_resource *r)
|
||||
{
|
||||
int error;
|
||||
|
||||
if ((error = BUS_RELEASE_RESOURCE(dev, child, type, rid, r->res)))
|
||||
return (error);
|
||||
|
||||
free(r, M_BHND);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper function for implementing BHND_BUS_ACTIVATE_RESOURCE().
|
||||
*
|
||||
* This implementation of BHND_BUS_ACTIVATE_RESOURCE() simply calls the
|
||||
* BHND_BUS_ACTIVATE_RESOURCE() method of the parent of @p dev.
|
||||
*/
|
||||
int
|
||||
bhnd_bus_generic_activate_resource(device_t dev, device_t child, int type,
|
||||
int rid, struct bhnd_resource *r)
|
||||
{
|
||||
/* Try to delegate to the parent */
|
||||
if (device_get_parent(dev) != NULL)
|
||||
return (BHND_BUS_ACTIVATE_RESOURCE(device_get_parent(dev),
|
||||
child, type, rid, r));
|
||||
|
||||
return (EINVAL);
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper function for implementing BHND_BUS_DEACTIVATE_RESOURCE().
|
||||
*
|
||||
* This implementation of BHND_BUS_ACTIVATE_RESOURCE() simply calls the
|
||||
* BHND_BUS_ACTIVATE_RESOURCE() method of the parent of @p dev.
|
||||
*/
|
||||
int
|
||||
bhnd_bus_generic_deactivate_resource(device_t dev, device_t child,
|
||||
int type, int rid, struct bhnd_resource *r)
|
||||
{
|
||||
if (device_get_parent(dev) != NULL)
|
||||
return (BHND_BUS_DEACTIVATE_RESOURCE(device_get_parent(dev),
|
||||
child, type, rid, r));
|
||||
|
||||
return (EINVAL);
|
||||
};
|
@ -1048,15 +1048,15 @@ bhndb_alloc_resource(device_t dev, device_t child, int type,
|
||||
struct resource *rv;
|
||||
struct rman *rm;
|
||||
int error;
|
||||
bool immed_child, defaults;
|
||||
bool passthrough, isdefault;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
immed_child = (device_get_parent(child) == dev);
|
||||
defaults = (start == 0UL && end == ~0UL);
|
||||
passthrough = (device_get_parent(child) != dev);
|
||||
isdefault = RMAN_IS_DEFAULT_RANGE(start, end);
|
||||
rle = NULL;
|
||||
|
||||
/* Populate defaults */
|
||||
if (immed_child && defaults) {
|
||||
if (!passthrough && isdefault) {
|
||||
/* Fetch the resource list entry. */
|
||||
rle = resource_list_find(BUS_GET_RESOURCE_LIST(dev, child),
|
||||
type, *rid);
|
||||
@ -1083,7 +1083,7 @@ bhndb_alloc_resource(device_t dev, device_t child, int type,
|
||||
}
|
||||
|
||||
/* Validate resource addresses */
|
||||
if (start > end || end < start || count > ((end - start) + 1))
|
||||
if (start > end || count > ((end - start) + 1))
|
||||
return (NULL);
|
||||
|
||||
/* Fetch the resource manager */
|
||||
@ -1511,62 +1511,6 @@ bhndb_get_resource_list(device_t dev, device_t child)
|
||||
return (&dinfo->resources);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default bhndb(4) implementation of BHND_BUS_ALLOC_RESOURCE().
|
||||
*/
|
||||
static struct bhnd_resource *
|
||||
bhndb_alloc_bhnd_resource(device_t dev, device_t child, int type,
|
||||
int *rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
|
||||
{
|
||||
struct bhndb_softc *sc;
|
||||
struct bhnd_resource *br;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
/* Allocate resource wrapper */
|
||||
br = malloc(sizeof(struct bhnd_resource), M_BHND, M_NOWAIT|M_ZERO);
|
||||
if (br == NULL)
|
||||
return (NULL);
|
||||
|
||||
/* Configure */
|
||||
br->direct = false;
|
||||
br->res = bus_alloc_resource(child, type, rid, start, end, count,
|
||||
flags & ~RF_ACTIVE);
|
||||
if (br->res == NULL)
|
||||
goto failed;
|
||||
|
||||
|
||||
if (flags & RF_ACTIVE) {
|
||||
if (bhnd_activate_resource(child, type, *rid, br))
|
||||
goto failed;
|
||||
}
|
||||
|
||||
return (br);
|
||||
|
||||
failed:
|
||||
if (br->res != NULL)
|
||||
bus_release_resource(child, type, *rid, br->res);
|
||||
|
||||
free(br, M_BHND);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default bhndb(4) implementation of BHND_BUS_RELEASE_RESOURCE().
|
||||
*/
|
||||
static int
|
||||
bhndb_release_bhnd_resource(device_t dev, device_t child,
|
||||
int type, int rid, struct bhnd_resource *r)
|
||||
{
|
||||
int error;
|
||||
|
||||
if ((error = bus_release_resource(child, type, rid, r->res)))
|
||||
return (error);
|
||||
|
||||
free(r, M_BHND);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default bhndb(4) implementation of BHND_BUS_ACTIVATE_RESOURCE().
|
||||
*
|
||||
@ -1983,8 +1927,6 @@ static device_method_t bhndb_methods[] = {
|
||||
DEVMETHOD(bhnd_bus_is_hw_disabled, bhndb_is_hw_disabled),
|
||||
DEVMETHOD(bhnd_bus_is_hostb_device, bhndb_is_hostb_device),
|
||||
DEVMETHOD(bhnd_bus_get_chipid, bhndb_get_chipid),
|
||||
DEVMETHOD(bhnd_bus_alloc_resource, bhndb_alloc_bhnd_resource),
|
||||
DEVMETHOD(bhnd_bus_release_resource, bhndb_release_bhnd_resource),
|
||||
DEVMETHOD(bhnd_bus_activate_resource, bhndb_activate_bhnd_resource),
|
||||
DEVMETHOD(bhnd_bus_activate_resource, bhndb_deactivate_bhnd_resource),
|
||||
DEVMETHOD(bhnd_bus_read_1, bhndb_bus_read_1),
|
||||
|
@ -70,37 +70,5 @@ int bhnd_generic_suspend_child(device_t dev,
|
||||
device_t child);
|
||||
int bhnd_generic_resume_child(device_t dev,
|
||||
device_t child);
|
||||
|
||||
bool bhnd_generic_is_hostb_device(device_t dev,
|
||||
device_t child);
|
||||
bool bhnd_generic_is_hw_disabled(device_t dev,
|
||||
device_t child);
|
||||
bool bhnd_generic_is_region_valid(device_t dev,
|
||||
device_t child, bhnd_port_type type, u_int port,
|
||||
u_int region);
|
||||
|
||||
int bhnd_generic_read_nvram_var(device_t dev,
|
||||
device_t child, const char *name, void *buf,
|
||||
size_t *size);
|
||||
|
||||
const struct bhnd_chipid *bhnd_generic_get_chipid(device_t dev, device_t child);
|
||||
|
||||
struct bhnd_resource *bhnd_generic_alloc_bhnd_resource (device_t dev,
|
||||
device_t child, int type, int *rid,
|
||||
rman_res_t start, rman_res_t end, rman_res_t count,
|
||||
u_int flags);
|
||||
|
||||
int bhnd_generic_release_bhnd_resource (device_t dev,
|
||||
device_t child, int type, int rid,
|
||||
struct bhnd_resource *r);
|
||||
|
||||
int bhnd_generic_activate_bhnd_resource (device_t dev,
|
||||
device_t child, int type, int rid,
|
||||
struct bhnd_resource *r);
|
||||
|
||||
int bhnd_generic_deactivate_bhnd_resource (device_t dev,
|
||||
device_t child, int type, int rid,
|
||||
struct bhnd_resource *r);
|
||||
|
||||
|
||||
#endif /* _BHND_BHNDVAR_H_ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user