mirror of
https://github.com/opnsense/src.git
synced 2026-02-18 18:20:26 -05:00
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 (cherry picked from commit ee15875c01593b287e55147c482b914e3ab01152)
This commit is contained in:
parent
4aed8b3b61
commit
bc8f3704f1
3 changed files with 71 additions and 84 deletions
|
|
@ -556,6 +556,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)
|
||||
|
|
@ -688,58 +690,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++;
|
||||
|
|
@ -750,26 +744,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__,
|
||||
|
|
@ -789,7 +783,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;
|
||||
}
|
||||
}
|
||||
|
|
@ -845,7 +839,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 */
|
||||
|
|
@ -913,7 +908,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);
|
||||
|
|
@ -944,16 +939,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));
|
||||
|
||||
mod = dev->dev_module;
|
||||
TAILQ_FOREACH(mod, &module_head, entry) {
|
||||
if (!devclass_equal(mod->bus_name, bus_name_parent))
|
||||
continue;
|
||||
|
||||
dc = devclass_find(mod->mod_name);
|
||||
|
||||
/* 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) {
|
||||
|
|
@ -965,40 +978,11 @@ device_probe_and_attach(device_t dev)
|
|||
}
|
||||
}
|
||||
}
|
||||
/* else try next driver */
|
||||
|
||||
device_detach(dev);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
error:
|
||||
return (ENODEV);
|
||||
}
|
||||
|
||||
|
|
@ -1017,9 +1001,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);
|
||||
}
|
||||
|
|
@ -1095,11 +1080,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);
|
||||
}
|
||||
|
|
@ -1110,6 +1095,7 @@ module_register(void *data)
|
|||
struct module_data *mdata = data;
|
||||
|
||||
TAILQ_INSERT_TAIL(&module_head, mdata, entry);
|
||||
(void)devclass_find_create(mdata->mod_name);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in a new issue