summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/subr_bus.c31
-rw-r--r--sys/sys/bus.h15
-rw-r--r--sys/sys/rman.h1
-rw-r--r--sys/sys/types.h1
4 files changed, 43 insertions, 5 deletions
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
index 2bfa275..b475257 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -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().
*
diff --git a/sys/sys/bus.h b/sys/sys/bus.h
index 6fc77b4..8216eda 100644
--- a/sys/sys/bus.h
+++ b/sys/sys/bus.h
@@ -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);
diff --git a/sys/sys/rman.h b/sys/sys/rman.h
index c043e80..857a5c8 100644
--- a/sys/sys/rman.h
+++ b/sys/sys/rman.h
@@ -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)
diff --git a/sys/sys/types.h b/sys/sys/types.h
index 5a0951c..fa1e0bd 100644
--- a/sys/sys/types.h
+++ b/sys/sys/types.h
@@ -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)
OpenPOWER on IntegriCloud