Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144396854
D42739.id130525.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D42739.id130525.diff
View Options
diff --git a/sys/kern/bus_if.m b/sys/kern/bus_if.m
--- a/sys/kern/bus_if.m
+++ b/sys/kern/bus_if.m
@@ -77,6 +77,12 @@
{
return (0);
}
+
+ static struct rman *
+ null_get_rman(device_t bus, int type, u_int flags)
+ {
+ return (NULL);
+ }
};
/**
@@ -622,6 +628,24 @@
device_t _child;
} DEFAULT bus_generic_get_resource_list;
+/**
+ * @brief Return a struct rman.
+ *
+ * Used by drivers which use bus_generic_rman_alloc_resource() etc. to
+ * implement their resource handling. It should return the resource
+ * manager used for the given resource type.
+ *
+ * @param _dev the bus device
+ * @param _type the resource type
+ * @param _flags resource flags (@c RF_XXX flags in
+ * <sys/rman.h>)
+ */
+METHOD struct rman * get_rman {
+ device_t _dev;
+ int _type;
+ u_int _flags;
+} DEFAULT null_get_rman;
+
/**
* @brief Is the hardware described by @p _child still attached to the
* system?
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -4189,6 +4189,163 @@
start, end, count, flags));
}
+/**
+ * @brief Helper function for implementing BUS_ALLOC_RESOURCE().
+ *
+ * This implementation of BUS_ALLOC_RESOURCE() allocates a
+ * resource from a resource manager. It uses BUS_GET_RMAN()
+ * to obtain the resource manager.
+ */
+struct resource *
+bus_generic_rman_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 resource *r;
+ struct rman *rm;
+
+ rm = BUS_GET_RMAN(dev, type, flags);
+ if (rm == NULL)
+ return (NULL);
+
+ r = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE,
+ child);
+ if (r == NULL)
+ return (NULL);
+ rman_set_rid(r, *rid);
+
+ if (flags & RF_ACTIVE) {
+ if (bus_activate_resource(child, type, *rid, r) != 0) {
+ rman_release_resource(r);
+ return (NULL);
+ }
+ }
+
+ return (r);
+}
+
+/**
+ * @brief Helper function for implementing BUS_ADJUST_RESOURCE().
+ *
+ * This implementation of BUS_ADJUST_RESOURCE() adjusts resources only
+ * if they were allocated from the resource manager returned by
+ * BUS_GET_RMAN().
+ */
+int
+bus_generic_rman_adjust_resource(device_t dev, device_t child, int type,
+ struct resource *r, rman_res_t start, rman_res_t end)
+{
+ struct rman *rm;
+
+ rm = BUS_GET_RMAN(dev, type, rman_get_flags(r));
+ if (rm == NULL)
+ return (ENXIO);
+ if (!rman_is_region_manager(r, rm))
+ return (EINVAL);
+ return (rman_adjust_resource(r, start, end));
+}
+
+/**
+ * @brief Helper function for implementing BUS_RELEASE_RESOURCE().
+ *
+ * This implementation of BUS_RELEASE_RESOURCE() releases resources
+ * allocated by bus_generic_rman_alloc_resource.
+ */
+int
+bus_generic_rman_release_resource(device_t dev, device_t child, int type,
+ int rid, struct resource *r)
+{
+#ifdef INVARIANTS
+ struct rman *rm;
+#endif
+ int error;
+
+#ifdef INVARIANTS
+ rm = BUS_GET_RMAN(dev, type, rman_get_flags(r));
+ KASSERT(rman_is_region_manager(r, rm),
+ ("%s: rman %p doesn't match for resource %p", __func__, rm, r));
+#endif
+
+ if (rman_get_flags(r) & RF_ACTIVE) {
+ error = bus_deactivate_resource(child, type, rid, r);
+ if (error != 0)
+ return (error);
+ }
+ return (rman_release_resource(r));
+}
+
+/**
+ * @brief Helper function for implementing BUS_ACTIVATE_RESOURCE().
+ *
+ * This implementation of BUS_ACTIVATE_RESOURCE() activates resources
+ * allocated by bus_generic_rman_alloc_resource.
+ */
+int
+bus_generic_rman_activate_resource(device_t dev, device_t child, int type,
+ int rid, struct resource *r)
+{
+ struct resource_map map;
+#ifdef INVARIANTS
+ struct rman *rm;
+#endif
+ int error;
+
+#ifdef INVARIANTS
+ rm = BUS_GET_RMAN(dev, type, rman_get_flags(r));
+ KASSERT(rman_is_region_manager(r, rm),
+ ("%s: rman %p doesn't match for resource %p", __func__, rm, r));
+#endif
+
+ error = rman_activate_resource(r);
+ if (error != 0)
+ return (error);
+
+ if ((rman_get_flags(r) & RF_UNMAPPED) == 0 &&
+ (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT)) {
+ error = BUS_MAP_RESOURCE(dev, child, type, r, NULL, &map);
+ if (error != 0) {
+ rman_deactivate_resource(r);
+ return (error);
+ }
+
+ rman_set_mapping(r, &map);
+ }
+ return (0);
+}
+
+/**
+ * @brief Helper function for implementing BUS_DEACTIVATE_RESOURCE().
+ *
+ * This implementation of BUS_DEACTIVATE_RESOURCE() deactivates
+ * resources allocated by bus_generic_rman_alloc_resource.
+ */
+int
+bus_generic_rman_deactivate_resource(device_t dev, device_t child, int type,
+ int rid, struct resource *r)
+{
+ struct resource_map map;
+#ifdef INVARIANTS
+ struct rman *rm;
+#endif
+ int error;
+
+#ifdef INVARIANTS
+ rm = BUS_GET_RMAN(dev, type, rman_get_flags(r));
+ KASSERT(rman_is_region_manager(r, rm),
+ ("%s: rman %p doesn't match for resource %p", __func__, rm, r));
+#endif
+
+ error = rman_deactivate_resource(r);
+ if (error != 0)
+ return (error);
+
+ if ((rman_get_flags(r) & RF_UNMAPPED) == 0 &&
+ (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT)) {
+ rman_get_mapping(r, &map);
+ BUS_UNMAP_RESOURCE(dev, child, type, r, &map);
+ }
+ return (0);
+}
+
/**
* @brief Helper function for implementing BUS_CHILD_PRESENT().
*
diff --git a/sys/sys/bus.h b/sys/sys/bus.h
--- a/sys/sys/bus.h
+++ b/sys/sys/bus.h
@@ -499,6 +499,23 @@
rman_res_t);
int bus_generic_rl_release_resource (device_t, device_t, int, int,
struct resource *);
+struct resource *
+ bus_generic_rman_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 bus_generic_rman_adjust_resource(device_t dev, device_t child, int type,
+ struct resource *r, rman_res_t start,
+ rman_res_t end);
+int bus_generic_rman_release_resource(device_t dev, device_t child,
+ int type, int rid,
+ struct resource *r);
+int bus_generic_rman_activate_resource(device_t dev, device_t child,
+ int type, int rid,
+ struct resource *r);
+int bus_generic_rman_deactivate_resource(device_t dev, device_t child,
+ int type, int rid,
+ struct resource *r);
int bus_generic_shutdown(device_t dev);
int bus_generic_suspend(device_t dev);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Feb 9, 5:37 AM (15 h, 9 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28513010
Default Alt Text
D42739.id130525.diff (6 KB)
Attached To
Mode
D42739: newbus: Add a set of bus resource helpers for nexus-like devices
Attached
Detach File
Event Timeline
Log In to Comment