Page MenuHomeFreeBSD

D46605.diff
No OneTemporary

D46605.diff

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
@@ -105,6 +105,16 @@
struct sysctl_oid *sysctl_tree;
};
+struct device_prop_elm {
+ const char *name;
+ void *val;
+ void *dtr_ctx;
+ device_prop_dtr_t dtr;
+ LIST_ENTRY(device_prop_elm) link;
+};
+
+static void device_destroy_props(device_t dev);
+
/**
* @brief Implementation of _device.
*
@@ -141,6 +151,7 @@
u_int order; /**< order from device_add_child_ordered() */
void *ivars; /**< instance variables */
void *softc; /**< current driver's variables */
+ LIST_HEAD(, device_prop_elm) props;
struct sysctl_ctx_list sysctl_ctx; /**< state for sysctl variables */
struct sysctl_oid *sysctl_tree; /**< state for sysctl variables */
@@ -1349,6 +1360,7 @@
dev->flags |= DF_QUIET | DF_QUIET_CHILDREN;
dev->ivars = NULL;
dev->softc = NULL;
+ LIST_INIT(&dev->props);
dev->state = DS_NOTPRESENT;
@@ -1488,6 +1500,7 @@
return (error);
}
+ device_destroy_props(dev);
if (child->devclass)
devclass_delete_device(child->devclass, child);
if (child->parent)
@@ -6017,6 +6030,110 @@
return (strcmp(res->dln_path, cp) == 0);
}
+static struct device_prop_elm *
+device_prop_find(device_t dev, const char *name)
+{
+ struct device_prop_elm *e;
+
+ bus_topo_assert();
+
+ LIST_FOREACH(e, &dev->props, link) {
+ if (strcmp(name, e->name) == 0)
+ return (e);
+ }
+ return (NULL);
+}
+
+int
+device_set_prop(device_t dev, const char *name, void *val,
+ device_prop_dtr_t dtr, void *dtr_ctx)
+{
+ struct device_prop_elm *e, *e1;
+
+ bus_topo_assert();
+
+ e = device_prop_find(dev, name);
+ if (e != NULL)
+ goto found;
+
+ e1 = malloc(sizeof(*e), M_BUS, M_WAITOK);
+ e = device_prop_find(dev, name);
+ if (e != NULL) {
+ free(e1, M_BUS);
+ goto found;
+ }
+
+ e1->name = name;
+ e1->val = val;
+ e1->dtr = dtr;
+ e1->dtr_ctx = dtr_ctx;
+ LIST_INSERT_HEAD(&dev->props, e1, link);
+ return (0);
+
+found:
+ LIST_REMOVE(e, link);
+ e->dtr(dev, name, e->val, e->dtr_ctx);
+ e->val = val;
+ e->dtr = dtr;
+ e->dtr_ctx = dtr_ctx;
+ LIST_INSERT_HEAD(&dev->props, e, link);
+ return (EEXIST);
+}
+
+int
+device_get_prop(device_t dev, const char *name, void **valp)
+{
+ struct device_prop_elm *e;
+
+ bus_topo_assert();
+
+ e = device_prop_find(dev, name);
+ if (e == NULL)
+ return (ENOENT);
+ *valp = e->val;
+ return (0);
+}
+
+int
+device_clear_prop(device_t dev, const char *name)
+{
+ struct device_prop_elm *e;
+
+ bus_topo_assert();
+
+ e = device_prop_find(dev, name);
+ if (e == NULL)
+ return (ENOENT);
+ LIST_REMOVE(e, link);
+ e->dtr(dev, e->name, e->val, e->dtr_ctx);
+ free(e, M_BUS);
+ return (0);
+}
+
+static void
+device_destroy_props(device_t dev)
+{
+ struct device_prop_elm *e;
+
+ bus_topo_assert();
+
+ while ((e = LIST_FIRST(&dev->props)) != NULL) {
+ LIST_REMOVE_HEAD(&dev->props, link);
+ e->dtr(dev, e->name, e->val, e->dtr_ctx);
+ free(e, M_BUS);
+ }
+}
+
+void
+device_clear_prop_alldev(const char *name)
+{
+ device_t dev;
+
+ TAILQ_FOREACH(dev, &bus_data_devices, devlink) {
+ device_clear_prop(dev, name);
+ }
+}
+
/*
* APIs to manage deprecation and obsolescence.
*/
diff --git a/sys/sys/bus.h b/sys/sys/bus.h
--- a/sys/sys/bus.h
+++ b/sys/sys/bus.h
@@ -924,6 +924,13 @@
void dev_wired_cache_fini(device_location_cache_t *dcp);
bool dev_wired_cache_match(device_location_cache_t *dcp, device_t dev, const char *at);
+typedef void (*device_prop_dtr_t)(device_t dev, const char *name, void *val,
+ void *dtr_ctx);
+int device_set_prop(device_t dev, const char *name, void *val,
+ device_prop_dtr_t dtr, void *dtr_ctx);
+int device_get_prop(device_t dev, const char *name, void **valp);
+int device_clear_prop(device_t dev, const char *name);
+void device_clear_prop_alldev(const char *name);
/**
* Shorthand macros, taking resource argument

File Metadata

Mime Type
text/plain
Expires
Mon, Sep 23, 8:44 PM (19 h, 10 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
12591342
Default Alt Text
D46605.diff (3 KB)

Event Timeline