The branch main has been updated by jhb:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=ee15875c01593b287e55147c482b914e3ab01152

commit ee15875c01593b287e55147c482b914e3ab01152
Author:     John Baldwin <j...@freebsd.org>
AuthorDate: 2025-01-11 04:01:48 +0000
Commit:     John Baldwin <j...@freebsd.org>
CommitDate: 2025-01-11 04:03:32 +0000

    stand/kshim: Update for devclass being removed from DRIVER_MODULE
    
    The kshim code abused the devclass argument to DRIVER_MODULE in some
    odd ways.  Instead, refactor the devclass handling to more closely
    mirror what new-bus does in the kernel by having a linked list of
    devclasses looked up by name and associate devices with a devclass.
    
    Devices are now only associated with a module while probing and
    attaching.
    
    Reviewed by:    imp, markj
    Differential Revision:  https://reviews.freebsd.org/D48409
---
 stand/kshim/bsd_kernel.c         | 140 ++++++++++++++++++---------------------
 stand/kshim/bsd_kernel.h         |  11 +--
 stand/usb/storage/umass_common.c |   4 +-
 3 files changed, 71 insertions(+), 84 deletions(-)

diff --git a/stand/kshim/bsd_kernel.c b/stand/kshim/bsd_kernel.c
index fb1b4239fd03..78b6f9e0b4d4 100644
--- a/stand/kshim/bsd_kernel.c
+++ b/stand/kshim/bsd_kernel.c
@@ -554,6 +554,8 @@ static const char unknown_string[] = { "unknown" };
 
 static TAILQ_HEAD(, module_data) module_head =
     TAILQ_HEAD_INITIALIZER(module_head);
+static TAILQ_HEAD(, devclass) devclasses =
+    TAILQ_HEAD_INITIALIZER(devclasses);
 
 static uint8_t
 devclass_equal(const char *a, const char *b)
@@ -686,58 +688,50 @@ device_get_nameunit(device_t dev)
        return (unknown_string);
 }
 
-static uint8_t
-devclass_create(devclass_t *dc_pp)
+static devclass_t
+devclass_create(const char *classname)
 {
-       if (dc_pp == NULL) {
-               return (1);
-       }
-       if (dc_pp[0] == NULL) {
-               dc_pp[0] = malloc(sizeof(**(dc_pp)),
-                   M_DEVBUF, M_WAITOK | M_ZERO);
+       devclass_t dc;
 
-               if (dc_pp[0] == NULL) {
-                       return (1);
-               }
+       dc = malloc(sizeof(*dc), M_DEVBUF, M_WAITOK | M_ZERO);
+       if (dc == NULL) {
+               return (NULL);
        }
-       return (0);
+       dc->name = classname;
+       TAILQ_INSERT_TAIL(&devclasses, dc, link);
+       return (dc);
 }
 
-static const struct module_data *
+static devclass_t
 devclass_find_create(const char *classname)
 {
-       const struct module_data *mod;
+       devclass_t dc;
 
-       TAILQ_FOREACH(mod, &module_head, entry) {
-               if (devclass_equal(mod->mod_name, classname)) {
-                       if (devclass_create(mod->devclass_pp)) {
-                               continue;
-                       }
-                       return (mod);
-               }
-       }
-       return (NULL);
+       dc = devclass_find(classname);
+       if (dc == NULL)
+               dc = devclass_create(classname);
+       return (dc);
 }
 
 static uint8_t
-devclass_add_device(const struct module_data *mod, device_t dev)
+devclass_add_device(devclass_t dc, device_t dev)
 {
        device_t *pp_dev;
        device_t *end;
        uint8_t unit;
 
-       pp_dev = mod->devclass_pp[0]->dev_list;
+       pp_dev = dc->dev_list;
        end = pp_dev + DEVCLASS_MAXUNIT;
        unit = 0;
 
        while (pp_dev != end) {
                if (*pp_dev == NULL) {
                        *pp_dev = dev;
+                       dev->dev_class = dc;
                        dev->dev_unit = unit;
-                       dev->dev_module = mod;
                        snprintf(dev->dev_nameunit,
                            sizeof(dev->dev_nameunit),
-                           "%s%d", device_get_name(dev), unit);
+                           "%s%d", dc->name, unit);
                        return (0);
                }
                pp_dev++;
@@ -748,26 +742,26 @@ devclass_add_device(const struct module_data *mod, 
device_t dev)
 }
 
 static void
-devclass_delete_device(const struct module_data *mod, device_t dev)
+devclass_delete_device(devclass_t dc, device_t dev)
 {
-       if (mod == NULL) {
+       if (dc == NULL) {
                return;
        }
-       mod->devclass_pp[0]->dev_list[dev->dev_unit] = NULL;
-       dev->dev_module = NULL;
+       dc->dev_list[dev->dev_unit] = NULL;
+       dev->dev_class = NULL;
 }
 
 static device_t
 make_device(device_t parent, const char *name)
 {
        device_t dev = NULL;
-       const struct module_data *mod = NULL;
+       devclass_t dc = NULL;
 
        if (name) {
 
-               mod = devclass_find_create(name);
+               dc = devclass_find_create(name);
 
-               if (!mod) {
+               if (!dc) {
 
                        DPRINTF("%s:%d:%s: can't find device "
                            "class %s\n", __FILE__, __LINE__,
@@ -787,7 +781,7 @@ make_device(device_t parent, const char *name)
 
        if (name) {
                dev->dev_fixed_class = 1;
-               if (devclass_add_device(mod, dev)) {
+               if (devclass_add_device(dc, dev)) {
                        goto error;
                }
        }
@@ -843,7 +837,8 @@ device_delete_child(device_t dev, device_t child)
                }
        }
 
-       devclass_delete_device(child->dev_module, child);
+       if (child->dev_class != NULL)
+               devclass_delete_device(child->dev_class, child);
 
        if (dev != NULL) {
                /* remove child from parent */
@@ -911,7 +906,7 @@ device_get_method(device_t dev, const char *what)
 const char *
 device_get_name(device_t dev)
 {
-       if (dev == NULL)
+       if (dev == NULL || dev->dev_module == NULL)
                return (unknown_string);
 
        return (dev->dev_module->driver->name);
@@ -942,16 +937,34 @@ device_probe_and_attach(device_t dev)
 {
        const struct module_data *mod;
        const char *bus_name_parent;
-
-       bus_name_parent = device_get_name(device_get_parent(dev));
+       devclass_t dc;
 
        if (dev->dev_attached)
                return (0);             /* fail-safe */
 
-       if (dev->dev_fixed_class) {
+       /*
+         * Find a module for our device, if any
+         */
+       bus_name_parent = device_get_name(device_get_parent(dev));
+
+       TAILQ_FOREACH(mod, &module_head, entry) {
+               if (!devclass_equal(mod->bus_name, bus_name_parent))
+                       continue;
+
+               dc = devclass_find(mod->mod_name);
 
-               mod = dev->dev_module;
+               /* Does this device need assigning to the new devclass? */
+               if (dev->dev_class != dc) {
+                       if (dev->dev_fixed_class)
+                               continue;
+                       if (dev->dev_class != NULL)
+                               devclass_delete_device(dev->dev_class, dev);
+                       if (devclass_add_device(dc, dev)) {
+                               continue;
+                       }
+               }
 
+               dev->dev_module = mod;
                if (DEVICE_PROBE(dev) <= 0) {
 
                        if (device_allocate_softc(dev) == 0) {
@@ -963,40 +976,11 @@ device_probe_and_attach(device_t dev)
                                }
                        }
                }
-               device_detach(dev);
+               /* else try next driver */
 
-               goto error;
-       }
-       /*
-         * Else find a module for our device, if any
-         */
-
-       TAILQ_FOREACH(mod, &module_head, entry) {
-               if (devclass_equal(mod->bus_name, bus_name_parent)) {
-                       if (devclass_create(mod->devclass_pp)) {
-                               continue;
-                       }
-                       if (devclass_add_device(mod, dev)) {
-                               continue;
-                       }
-                       if (DEVICE_PROBE(dev) <= 0) {
-
-                               if (device_allocate_softc(dev) == 0) {
-
-                                       if (DEVICE_ATTACH(dev) == 0) {
-                                               /* success */
-                                               dev->dev_attached = 1;
-                                               return (0);
-                                       }
-                               }
-                       }
-                       /* else try next driver */
-
-                       device_detach(dev);
-               }
+               device_detach(dev);
        }
 
-error:
        return (ENODEV);
 }
 
@@ -1015,9 +999,10 @@ device_detach(device_t dev)
                dev->dev_attached = 0;
        }
        device_set_softc(dev, NULL);
+       dev->dev_module = NULL;
 
        if (dev->dev_fixed_class == 0)
-               devclass_delete_device(mod, dev);
+               devclass_delete_device(dev->dev_class, dev);
 
        return (0);
 }
@@ -1093,11 +1078,11 @@ devclass_get_device(devclass_t dc, int unit)
 devclass_t
 devclass_find(const char *classname)
 {
-       const struct module_data *mod;
+       devclass_t dc;
 
-       TAILQ_FOREACH(mod, &module_head, entry) {
-               if (devclass_equal(mod->driver->name, classname))
-                       return (mod->devclass_pp[0]);
+       TAILQ_FOREACH(dc, &devclasses, link) {
+               if (devclass_equal(dc->name, classname))
+                       return (dc);
        }
        return (NULL);
 }
@@ -1108,6 +1093,7 @@ module_register(void *data)
        struct module_data *mdata = data;
 
        TAILQ_INSERT_TAIL(&module_head, mdata, entry);
+       (void)devclass_find_create(mdata->mod_name);
 }
 
 /*------------------------------------------------------------------------*
diff --git a/stand/kshim/bsd_kernel.h b/stand/kshim/bsd_kernel.h
index 0b5d659951a2..8600bd1f31dc 100644
--- a/stand/kshim/bsd_kernel.h
+++ b/stand/kshim/bsd_kernel.h
@@ -87,11 +87,11 @@ struct sysctl_req {
 #define        MOD_UNLOAD 2
 #define        DEVMETHOD(what,func) { #what, (void *)&func }
 #define        DEVMETHOD_END {0,0}
-#define        EARLY_DRIVER_MODULE(a, b, c, d, e, f, g)        
DRIVER_MODULE(a, b, c, d, e, f)
-#define        DRIVER_MODULE(name, busname, driver, devclass, evh, arg)        
\
+#define        EARLY_DRIVER_MODULE(a, b, c, d, e, f)   DRIVER_MODULE(a, b, c, 
d, e)
+#define        DRIVER_MODULE(name, busname, driver, evh, arg)  \
   static struct module_data bsd_##name##_##busname##_driver_mod = {    \
        evh, arg, #busname, #name, #busname "/" #name,                  \
-       &driver, &devclass, { 0, 0 } };                                 \
+       &driver, { 0, 0 } };                                    \
 SYSINIT(bsd_##name##_##busname##_driver_mod, SI_SUB_DRIVERS,           \
   SI_ORDER_MIDDLE, module_register,                                    \
   &bsd_##name##_##busname##_driver_mod)
@@ -135,6 +135,7 @@ SYSINIT_ENTRY(uniq##_entry, "sysuninit", (subs),    \
 #define        cold 0
 #define        BUS_PROBE_GENERIC 0
 #define        BUS_PROBE_DEFAULT (-20)
+#define        DEVICE_UNIT_ANY -1
 #define        CALLOUT_RETURNUNLOCKED 0x1
 #undef ffs
 #define        ffs(x) __builtin_ffs(x)
@@ -406,6 +407,7 @@ struct device {
        TAILQ_HEAD(device_list, device) dev_children;
        TAILQ_ENTRY(device) dev_link;
 
+       devclass_t dev_class;
        struct device *dev_parent;
        const struct module_data *dev_module;
        void   *dev_sc;
@@ -429,6 +431,8 @@ struct device {
 };
 
 struct devclass {
+       TAILQ_ENTRY(devclass) link;
+       const char *name;
        device_t dev_list[DEVCLASS_MAXUNIT];
 };
 
@@ -445,7 +449,6 @@ struct module_data {
        const char *mod_name;
        const char *long_name;
        const struct driver *driver;
-       struct devclass **devclass_pp;
        TAILQ_ENTRY(module_data) entry;
 };
 
diff --git a/stand/usb/storage/umass_common.c b/stand/usb/storage/umass_common.c
index 639d70a7f7e6..b62412b13637 100644
--- a/stand/usb/storage/umass_common.c
+++ b/stand/usb/storage/umass_common.c
@@ -38,8 +38,6 @@ static device_probe_t umass_probe;
 static device_attach_t umass_attach;
 static device_detach_t umass_detach;
 
-static devclass_t umass_devclass;
-
 static device_method_t umass_methods[] = {
        /* Device interface */
        DEVMETHOD(device_probe, umass_probe),
@@ -54,7 +52,7 @@ static driver_t umass_driver = {
        .methods = umass_methods,
 };
 
-DRIVER_MODULE(umass, uhub, umass_driver, umass_devclass, NULL, 0);
+DRIVER_MODULE(umass, uhub, umass_driver, NULL, 0);
 
 static int
 umass_probe(device_t dev)

Reply via email to