Add two convenience functions for device drivers: bus_alloc_resources()
and bus_free_resources(). These functions take a list of resources and handle them all in one go. A flag makes it possible to mark a resource as optional. A typical device driver can save 10-30 lines of code by using these. Usage examples will follow RSN. MFC: A good idea, eventually.
This commit is contained in:
parent
c4a4b66d17
commit
a778923149
@ -3321,6 +3321,37 @@ bus_generic_child_present(device_t dev, device_t child)
|
||||
* to maintain some sort of a list of resources allocated by each device.
|
||||
*/
|
||||
|
||||
int
|
||||
bus_alloc_resources(device_t dev, struct resource_spec *rs,
|
||||
struct resource **res)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; rs[i].type != -1; i++)
|
||||
res[i] = NULL;
|
||||
for (i = 0; rs[i].type != -1; i++) {
|
||||
res[i] = bus_alloc_resource_any(dev,
|
||||
rs[i].type, &rs[i].rid, rs[i].flags);
|
||||
if (res[i] == NULL && !(rs[i].flags & RF_OPTIONAL)) {
|
||||
bus_release_resources(dev, rs, res);
|
||||
return (ENXIO);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
bus_release_resources(device_t dev, struct resource_spec *rs,
|
||||
struct resource **res)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; rs[i].type != -1; i++)
|
||||
if (res[i] != NULL)
|
||||
bus_release_resource(
|
||||
dev, rs[i].type, rs[i].rid, res[i]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wrapper function for BUS_ALLOC_RESOURCE().
|
||||
*
|
||||
|
@ -85,11 +85,6 @@ void devctl_notify(const char *__system, const char *__subsystem,
|
||||
const char *__type, const char *__data);
|
||||
void devctl_queue_data(char *__data);
|
||||
|
||||
/*
|
||||
* Forward declarations
|
||||
*/
|
||||
typedef struct device *device_t;
|
||||
|
||||
/**
|
||||
* @brief A device driver (included mainly for compatibility with
|
||||
* FreeBSD 4.x).
|
||||
@ -294,6 +289,16 @@ int bus_generic_write_ivar(device_t dev, device_t child, int which,
|
||||
* Wrapper functions for the BUS_*_RESOURCE methods to make client code
|
||||
* a little simpler.
|
||||
*/
|
||||
|
||||
struct resource_spec {
|
||||
int type;
|
||||
int rid;
|
||||
int flags;
|
||||
};
|
||||
|
||||
int bus_alloc_resources(device_t dev, struct resource_spec *rs, struct resource **res);
|
||||
void bus_release_resources(device_t dev, struct resource_spec *rs, struct resource **res);
|
||||
|
||||
struct resource *bus_alloc_resource(device_t dev, int type, int *rid,
|
||||
u_long start, u_long end, u_long count,
|
||||
u_int flags);
|
||||
|
@ -46,6 +46,7 @@
|
||||
#define RF_WANTED 0x0010 /* somebody is waiting for this resource */
|
||||
#define RF_FIRSTSHARE 0x0020 /* first in sharing list */
|
||||
#define RF_PREFETCHABLE 0x0040 /* resource is prefetchable */
|
||||
#define RF_OPTIONAL 0x0080 /* for bus_alloc_resources() */
|
||||
|
||||
#define RF_ALIGNMENT_SHIFT 10 /* alignment size bit starts bit 10 */
|
||||
#define RF_ALIGNMENT_MASK (0x003F << RF_ALIGNMENT_SHIFT)
|
||||
|
@ -285,6 +285,7 @@ typedef __uint32_t intrmask_t; /* Interrupt mask (spl, xxx_imask...) */
|
||||
typedef __uintfptr_t uintfptr_t;
|
||||
typedef __uint64_t uoff_t;
|
||||
typedef struct vm_page *vm_page_t;
|
||||
typedef struct device *device_t;
|
||||
|
||||
#define offsetof(type, field) __offsetof(type, field)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user