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:
Poul-Henning Kamp 2005-09-24 19:31:10 +00:00
parent c4a4b66d17
commit a778923149
4 changed files with 43 additions and 5 deletions

View File

@ -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().
*

View File

@ -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);

View File

@ -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)

View File

@ -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)