27 #include <sys/cdefs.h>
32 #include <sys/param.h>
34 #include <sys/filio.h>
36 #include <sys/kernel.h>
38 #include <sys/limits.h>
39 #include <sys/malloc.h>
40 #include <sys/module.h>
41 #include <sys/mutex.h>
44 #include <sys/condvar.h>
45 #include <sys/queue.h>
46 #include <machine/bus.h>
48 #include <sys/selinfo.h>
49 #include <sys/signalvar.h>
50 #include <sys/sysctl.h>
51 #include <sys/systm.h>
54 #include <sys/interrupt.h>
58 #include <machine/stdarg.h>
63 SYSCTL_NODE(, OID_AUTO, dev, CTLFLAG_RW, NULL, NULL);
79 typedef
TAILQ_HEAD(devclass_list, devclass) devclass_list_t;
84 TAILQ_ENTRY(devclass) link;
86 driver_list_t drivers;
91 #define DC_HAS_CHILDREN 1
93 struct sysctl_ctx_list sysctl_ctx;
94 struct sysctl_oid *sysctl_tree;
111 TAILQ_ENTRY(
device) devlink;
113 device_list_t children;
124 device_state_t state;
127 #define DF_ENABLED 0x01
128 #define DF_FIXEDCLASS 0x02
129 #define DF_WILDCARD 0x04
130 #define DF_DESCMALLOCED 0x08
131 #define DF_QUIET 0x10
132 #define DF_DONENOMATCH 0x20
133 #define DF_EXTERNALSOFTC 0x40
134 #define DF_REBID 0x80
139 struct sysctl_ctx_list sysctl_ctx;
140 struct sysctl_oid *sysctl_tree;
144 static MALLOC_DEFINE(M_BUS_SC,
"bus-sc",
"Bus data structures, softc");
148 static int bus_debug = 1;
150 SYSCTL_INT(_debug, OID_AUTO, bus_debug, CTLFLAG_RW, &bus_debug, 0,
153 #define PDEBUG(a) if (bus_debug) {printf("%s:%d: ", __func__, __LINE__), printf a; printf("\n");}
154 #define DEVICENAME(d) ((d)? device_get_name(d): "no device")
155 #define DRIVERNAME(d) ((d)? d->name : "no driver")
156 #define DEVCLANAME(d) ((d)? d->name : "no devclass")
162 #define indentprintf(p) do { int iJ; printf("."); for (iJ=0; iJ<indent; iJ++) printf(" "); printf p ; } while (0)
179 #define DEVICENAME(d)
180 #define DRIVERNAME(d)
181 #define DEVCLANAME(d)
183 #define print_device_short(d,i)
184 #define print_device(d,i)
185 #define print_device_tree_short(d,i)
186 #define print_device_tree(d,i)
187 #define print_driver_short(d,i)
188 #define print_driver(d,i)
189 #define print_driver_list(d,i)
190 #define print_devclass_short(d,i)
191 #define print_devclass(d,i)
192 #define print_devclass_list_short()
193 #define print_devclass_list()
207 devclass_t dc = (devclass_t)arg1;
212 value = dc->parent ? dc->parent->name :
"";
217 return (SYSCTL_OUT(req, value, strlen(value)));
224 if (dc->sysctl_tree != NULL)
227 dc->sysctl_tree = SYSCTL_ADD_NODE(&dc->sysctl_ctx,
228 SYSCTL_STATIC_CHILDREN(_dev), OID_AUTO, dc->name,
229 CTLFLAG_RD, NULL,
"");
230 SYSCTL_ADD_PROC(&dc->sysctl_ctx, SYSCTL_CHILDREN(dc->sysctl_tree),
231 OID_AUTO,
"%parent", CTLTYPE_STRING | CTLFLAG_RD,
247 device_t dev = (device_t)arg1;
255 value = dev->desc ? dev->desc :
"";
258 value = dev->driver ? dev->driver->name :
"";
261 value = buf =
malloc(1024, M_BUS, M_WAITOK | M_ZERO);
265 value = buf =
malloc(1024, M_BUS, M_WAITOK | M_ZERO);
269 value = dev->parent ? dev->parent->nameunit :
"";
274 error = SYSCTL_OUT(req, value, strlen(value));
283 devclass_t dc = dev->devclass;
285 if (dev->sysctl_tree != NULL)
289 dev->sysctl_tree = SYSCTL_ADD_NODE(&dev->sysctl_ctx,
290 SYSCTL_CHILDREN(dc->sysctl_tree), OID_AUTO,
291 dev->nameunit + strlen(dc->name),
292 CTLFLAG_RD, NULL,
"");
293 SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
294 OID_AUTO,
"%desc", CTLTYPE_STRING | CTLFLAG_RD,
296 "device description");
297 SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
298 OID_AUTO,
"%driver", CTLTYPE_STRING | CTLFLAG_RD,
300 "device driver name");
301 SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
302 OID_AUTO,
"%location", CTLTYPE_STRING | CTLFLAG_RD,
304 "device location relative to parent");
305 SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
306 OID_AUTO,
"%pnpinfo", CTLTYPE_STRING | CTLFLAG_RD,
308 "device identification");
309 SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
310 OID_AUTO,
"%parent", CTLTYPE_STRING | CTLFLAG_RD,
318 devclass_t dc = dev->devclass;
320 if (dev->sysctl_tree == NULL)
328 if (dev->sysctl_tree == NULL)
331 dev->sysctl_tree = NULL;
358 SYSCTL_PROC(_hw_bus, OID_AUTO, devctl_disable, CTLTYPE_INT | CTLFLAG_RW, NULL,
361 #define DEVCTL_DEFAULT_QUEUE_LEN 1000
364 TUNABLE_INT(
"hw.bus.devctl_queue", &devctl_queue_length);
365 SYSCTL_PROC(_hw_bus, OID_AUTO, devctl_queue, CTLTYPE_INT | CTLFLAG_RW, NULL,
375 .d_version = D_VERSION,
376 .d_flags = D_NEEDGIANT,
410 devctl_dev =
make_dev_credf(MAKEDEV_ETERNAL, &dev_cdevsw, 0, NULL,
411 UID_ROOT, GID_WHEEL, 0600,
"devctl");
418 devopen(
struct cdev *dev,
int oflags,
int devtype,
struct thread *td)
430 devclose(
struct cdev *dev,
int fflag,
int devtype,
struct thread *td)
449 devread(
struct cdev *dev,
struct uio *uio,
int ioflag)
480 devioctl(
struct cdev *dev, u_long cmd, caddr_t data,
int fflag,
struct thread *td)
510 devpoll(
struct cdev *dev,
int events,
struct thread *td)
515 if (events & (POLLIN | POLLRDNORM)) {
517 revents = events & (POLLIN | POLLRDNORM);
548 if (strlen(data) == 0)
550 if (devctl_queue_length == 0)
552 n1 =
malloc(
sizeof(*n1), M_BUS, flags);
557 if (devctl_queue_length == 0) {
567 free(n2->dei_data, M_BUS);
604 const char *data,
int flags)
611 if (subsystem == NULL)
615 len += strlen(
" system=") + strlen(system);
616 len += strlen(
" subsystem=") + strlen(subsystem);
617 len += strlen(
" type=") + strlen(type);
622 msg =
malloc(len, M_BUS, flags);
626 snprintf(msg, len,
"!system=%s subsystem=%s type=%s %s\n",
627 system, subsystem, type, data);
629 snprintf(msg, len,
"!system=%s subsystem=%s type=%s\n",
630 system, subsystem, type);
664 if (!devctl_queue_length)
666 data =
malloc(1024, M_BUS, M_NOWAIT);
671 loc =
malloc(1024, M_BUS, M_NOWAIT);
678 pnp =
malloc(1024, M_BUS, M_NOWAIT);
690 snprintf(data, 1024,
"%s%s at %s %s on %s\n", type, what, loc, pnp,
745 dis = devctl_queue_length == 0;
747 if (error || !req->newptr)
758 devctl_queue_length = 0;
774 if (error || !req->newptr)
779 devctl_queue_length = q;
794 static
int bus_data_generation = 1;
796 static kobj_method_t null_methods[] = {
806 static driver_list_t
passes = TAILQ_HEAD_INITIALIZER(passes);
825 if (bus_current_pass == BUS_PASS_DEFAULT)
833 TAILQ_FOREACH(dl, &passes, passlink) {
834 if (dl->pass < new->pass)
836 if (dl->pass == new->pass)
838 TAILQ_INSERT_BEFORE(dl,
new, passlink);
841 TAILQ_INSERT_TAIL(&passes,
new, passlink);
856 if (bus_current_pass > pass)
857 panic(
"Attempt to lower bus pass level");
859 TAILQ_FOREACH(dl, &passes, passlink) {
861 if (dl->pass <= bus_current_pass)
875 bus_current_pass = dl->pass;
884 if (bus_current_pass < pass)
885 bus_current_pass = pass;
886 KASSERT(bus_current_pass == pass, (
"Failed to update bus pass level"));
893 static devclass_list_t
devclasses = TAILQ_HEAD_INITIALIZER(devclasses);
916 PDEBUG((
"looking for %s", classname));
920 TAILQ_FOREACH(dc, &devclasses, link) {
921 if (!strcmp(dc->name, classname))
926 PDEBUG((
"creating %s", classname));
927 dc =
malloc(
sizeof(
struct devclass) + strlen(classname) + 1,
928 M_BUS, M_NOWAIT | M_ZERO);
932 dc->name = (
char*) (dc + 1);
933 strcpy(dc->name, classname);
934 TAILQ_INIT(&dc->drivers);
935 TAILQ_INSERT_TAIL(&devclasses, dc, link);
948 if (parentname && dc && !dc->parent &&
949 strcmp(classname, parentname) != 0) {
1011 for (i = 0; i < dc->maxunit; i++)
1013 BUS_DRIVER_ADDED(dc->devices[i], driver);
1026 TAILQ_FOREACH(dc, &devclasses, link) {
1027 if (dc->parent == parent)
1047 const char *parentname;
1052 if (pass <= BUS_PASS_ROOT)
1055 dl =
malloc(
sizeof *dl, M_BUS, M_NOWAIT|M_ZERO);
1074 if (driver->baseclasses)
1075 parentname = driver->baseclasses[0]->name;
1081 TAILQ_INSERT_TAIL(&dc->drivers, dl, link);
1127 for (i = 0; i < dc->maxunit; i++) {
1128 if (dc->devices[i]) {
1129 dev = dc->devices[i];
1130 if (dev->driver == driver && dev->parent &&
1131 dev->parent->devclass == busclass) {
1134 BUS_PROBE_NOMATCH(dev->parent, dev);
1152 TAILQ_FOREACH(busclass, &devclasses, link) {
1153 if (busclass->parent == parent) {
1191 TAILQ_FOREACH(dl, &busclass->drivers, link) {
1192 if (dl->
driver == driver)
1197 PDEBUG((
"%s not found in %s list", driver->name,
1206 TAILQ_REMOVE(&busclass->drivers, dl, link);
1211 if (driver->refs == 0)
1248 TAILQ_FOREACH(dl, &busclass->drivers, link) {
1249 if (dl->
driver == driver)
1254 PDEBUG((
"%s not found in %s list", driver->name,
1269 for (i = 0; i < dc->maxunit; i++) {
1270 if (dc->devices[i]) {
1271 dev = dc->devices[i];
1272 if (dev->driver == driver && dev->parent &&
1273 dev->parent->devclass == busclass) {
1293 TAILQ_FOREACH(dl, &dc->drivers, link) {
1294 if (!strcmp(dl->
driver->name, classname))
1323 if (dc == NULL || unit < 0 || unit >= dc->maxunit)
1325 return (dc->devices[unit]);
1373 list =
malloc(count *
sizeof(device_t), M_TEMP, M_NOWAIT|M_ZERO);
1378 for (i = 0; i < dc->maxunit; i++) {
1379 if (dc->devices[i]) {
1380 list[
count] = dc->devices[i];
1415 TAILQ_FOREACH(dl, &dc->drivers, link)
1417 list =
malloc(count *
sizeof(driver_t *), M_TEMP, M_NOWAIT);
1422 TAILQ_FOREACH(dl, &dc->drivers, link) {
1443 for (i = 0; i < dc->maxunit; i++)
1463 return (dc->maxunit);
1480 while (unit < dc->maxunit && dc->devices[unit] != NULL)
1508 return (dc->parent);
1511 struct sysctl_ctx_list *
1514 return (&dc->sysctl_ctx);
1520 return (dc->sysctl_tree);
1554 if (unit >= 0 && unit < dc->maxunit &&
1555 dc->devices[unit] != NULL) {
1557 printf(
"%s: %s%d already exists; skipping it\n",
1558 dc->name, dc->name, *unitp);
1564 for (unit = 0;; unit++) {
1571 if (unit < dc->maxunit && dc->devices[unit] != NULL)
1583 if (unit >= dc->maxunit) {
1584 device_t *newlist, *oldlist;
1587 oldlist = dc->devices;
1588 newsize = roundup((unit + 1), MINALLOCSIZE /
sizeof(device_t));
1589 newlist =
malloc(
sizeof(device_t) * newsize, M_BUS, M_NOWAIT);
1592 if (oldlist != NULL)
1593 bcopy(oldlist, newlist,
sizeof(device_t) * dc->maxunit);
1594 bzero(newlist + dc->maxunit,
1595 sizeof(device_t) * (newsize - dc->maxunit));
1596 dc->devices = newlist;
1597 dc->maxunit = newsize;
1598 if (oldlist != NULL)
1599 free(oldlist, M_BUS);
1630 buflen =
snprintf(NULL, 0,
"%s%d$", dc->name, INT_MAX);
1633 dev->nameunit =
malloc(buflen, M_BUS, M_NOWAIT|M_ZERO);
1638 free(dev->nameunit, M_BUS);
1639 dev->nameunit = NULL;
1642 dc->devices[dev->unit] = dev;
1644 snprintf(dev->nameunit, buflen,
"%s%d", dc->name, dev->unit);
1669 if (dev->devclass != dc || dc->devices[dev->unit] != dev)
1670 panic(
"devclass_delete_device: inconsistent device class");
1671 dc->devices[dev->unit] = NULL;
1674 dev->devclass = NULL;
1675 free(dev->nameunit, M_BUS);
1676 dev->nameunit = NULL;
1704 printf(
"make_device: can't find device class %s\n",
1712 dev =
malloc(
sizeof(
struct device), M_BUS, M_NOWAIT|M_ZERO);
1717 TAILQ_INIT(&dev->children);
1720 dev->devclass = NULL;
1722 dev->nameunit = NULL;
1740 dev->state = DS_NOTPRESENT;
1742 TAILQ_INSERT_TAIL(&bus_data_devices, dev, devlink);
1758 retval += BUS_PRINT_CHILD(dev, child);
1813 PDEBUG((
"%s at %s with order %u as unit %d",
1815 KASSERT(name != NULL || unit == -1,
1816 (
"child device with wildcard name and specific unit number"));
1821 child->order = order;
1823 TAILQ_FOREACH(place, &dev->children, link) {
1824 if (place->order > order)
1833 TAILQ_INSERT_BEFORE(place, child, link);
1839 TAILQ_INSERT_TAIL(&dev->children, child, link);
1863 device_t grandchild;
1868 while ((grandchild = TAILQ_FIRST(&child->children)) != NULL) {
1876 if (child->devclass)
1879 BUS_CHILD_DELETED(dev, child);
1880 TAILQ_REMOVE(&dev->children, child, link);
1881 TAILQ_REMOVE(&bus_data_devices, child, devlink);
1911 while ((child = TAILQ_FIRST(&dev->children)) != NULL) {
1947 if (child && child->parent == dev)
1952 if (child && child->parent == dev)
1967 return (TAILQ_FIRST(&dc->drivers));
1976 if (dev->devclass) {
1978 for (dl = TAILQ_NEXT(last, link); dl; dl = TAILQ_NEXT(dl, link))
1979 if (!strcmp(dev->devclass->name, dl->
driver->name))
1983 return (TAILQ_NEXT(last, link));
1993 driverlink_t best = NULL;
1996 int hasclass = (child->devclass != NULL);
2002 panic(
"device_probe_child: parent device has no devclass");
2008 if (child->state == DS_ALIVE && (child->flags &
DF_REBID) == 0)
2011 for (; dc; dc = dc->parent) {
2016 if (dl->pass > bus_current_pass)
2021 if (result == ENOMEM)
2023 else if (result != 0)
2027 dl->
driver->name) != 0) {
2028 printf(
"driver bug: Unable to set "
2029 "devclass (devname: %s)\n",
2038 "flags", &child->devflags);
2040 result = DEVICE_PROBE(child);
2043 child->devflags = 0;
2071 if (best == NULL || result > pri) {
2077 if (result <= BUS_PROBE_NOWILDCARD &&
2089 if (best && pri == 0)
2115 if (child->state > DS_ALIVE && best->
driver != child->driver)
2120 if (!child->devclass) {
2129 "flags", &child->devflags);
2136 DEVICE_PROBE(child);
2142 child->state = DS_ALIVE;
2157 return (dev->parent);
2184 TAILQ_FOREACH(child, &dev->children, link) {
2193 list =
malloc(count *
sizeof(device_t), M_TEMP, M_NOWAIT|M_ZERO);
2198 TAILQ_FOREACH(child, &dev->children, link) {
2199 list[
count] = child;
2216 return (dev->driver);
2226 return (dev->devclass);
2236 if (dev != NULL && dev->devclass)
2249 return (dev->nameunit);
2276 return (dev->devflags);
2279 struct sysctl_ctx_list *
2282 return (&dev->sysctl_ctx);
2288 return (dev->sysctl_tree);
2302 return (
printf(
"unknown: "));
2333 free(dev->desc, M_BUS);
2339 dev->desc =
malloc(strlen(desc) + 1, M_BUS, M_NOWAIT);
2341 strcpy(dev->desc, desc);
2346 dev->desc = (
char *)(uintptr_t) desc;
2383 dev->devflags = flags;
2395 return (dev->softc);
2408 free(dev->softc, M_BUS_SC);
2425 free(softc, M_BUS_SC);
2456 KASSERT(dev != NULL, (
"device_get_ivars(NULL, ...)"));
2457 return (dev->ivars);
2467 KASSERT(dev != NULL, (
"device_set_ivars(NULL, ...)"));
2477 return (dev->state);
2504 if (dev->state < DS_ATTACHING)
2505 panic(
"device_busy: called for unattached device");
2506 if (dev->busy == 0 && dev->parent)
2509 if (dev->state == DS_ATTACHED)
2510 dev->state = DS_BUSY;
2519 if (dev->busy != 0 && dev->state != DS_BUSY &&
2520 dev->state != DS_ATTACHING)
2521 panic(
"device_unbusy: called for non-busy device %s",
2524 if (dev->busy == 0) {
2527 if (dev->state == DS_BUSY)
2528 dev->state = DS_ATTACHED;
2556 return ((dev->flags &
DF_QUIET) != 0);
2574 return (dev->state >= DS_ALIVE);
2584 return (dev->state >= DS_ATTACHED);
2603 if (dev->devclass) {
2604 printf(
"device_set_devclass: device class already set\n");
2628 if (dev->state >= DS_ATTACHED)
2631 if (dev->driver == driver)
2635 free(dev->softc, M_BUS_SC);
2642 kobj_init((kobj_t) dev, (kobj_class_t) driver);
2644 dev->softc =
malloc(driver->size, M_BUS_SC,
2695 if (dev->state >= DS_ALIVE && (dev->flags &
DF_REBID) == 0)
2701 printf(
"not probed (disabled)\n");
2706 if (bus_current_pass == BUS_PASS_DEFAULT &&
2708 BUS_PROBE_NOMATCH(dev->parent, dev);
2732 else if (error != 0)
2735 CURVNET_SET_QUIET(vnet0);
2775 dev->state = DS_ATTACHING;
2776 if ((error = DEVICE_ATTACH(dev)) != 0) {
2777 printf(
"device_attach: %s%d attach returned %d\n",
2778 dev->driver->name, dev->unit, error);
2783 KASSERT(dev->busy == 0, (
"attach failed but busy"));
2784 dev->state = DS_NOTPRESENT;
2789 dev->state = DS_BUSY;
2791 dev->state = DS_ATTACHED;
2821 if (dev->state == DS_BUSY)
2823 if (dev->state != DS_ATTACHED)
2826 if ((error = DEVICE_DETACH(dev)) != 0)
2832 BUS_CHILD_DETACHED(dev->parent, dev);
2837 dev->state = DS_NOTPRESENT;
2862 if (dev->state == DS_BUSY)
2864 if (dev->state != DS_ATTACHED)
2867 return (DEVICE_QUIESCE(dev));
2881 if (dev->state < DS_ATTACHED)
2883 return (DEVICE_SHUTDOWN(dev));
2899 if (unit < dc->maxunit && dc->devices[unit])
2940 struct resource_list_entry *rle;
2942 while ((rle = STAILQ_FIRST(rl)) != NULL) {
2944 panic(
"resource_list_free: resource entry is busy");
2945 STAILQ_REMOVE_HEAD(rl, link);
2965 u_long end, u_long
count)
2991 struct resource_list_entry *
2995 struct resource_list_entry *rle;
2999 rle =
malloc(
sizeof(
struct resource_list_entry), M_BUS,
3002 panic(
"resource_list_add: can't record entry");
3003 STAILQ_INSERT_TAIL(rl, rle, link);
3011 panic(
"resource_list_add: resource entry is busy");
3034 struct resource_list_entry *rle;
3037 if (rle == NULL || rle->res == NULL)
3039 if ((rle->flags & (RLE_RESERVED | RLE_ALLOCATED)) == RLE_RESERVED) {
3041 (
"reserved resource is active"));
3063 struct resource_list_entry *rle;
3066 if (rle != NULL && rle->flags & RLE_RESERVED)
3081 struct resource_list_entry *
3084 struct resource_list_entry *rle;
3086 STAILQ_FOREACH(rle, rl, link) {
3087 if (rle->type == type && rle->rid == rid)
3106 if (rle->res != NULL)
3107 panic(
"resource_list_delete: resource has not been released");
3108 STAILQ_REMOVE(rl, rle, resource_list_entry, link);
3151 int type,
int *rid, u_long
start, u_long end, u_long
count, u_int flags)
3153 struct resource_list_entry *rle = NULL;
3159 "resource_list_reserve() should only be called for direct children");
3160 if (flags & RF_ACTIVE)
3162 "resource_list_reserve() should only reserve inactive resources");
3168 rle->flags |= RLE_RESERVED;
3208 int type,
int *rid, u_long
start, u_long end, u_long
count, u_int flags)
3210 struct resource_list_entry *rle = NULL;
3212 int isdefault = (start == 0UL && end == ~0UL);
3225 if (rle->flags & RLE_RESERVED) {
3226 if (rle->flags & RLE_ALLOCATED)
3228 if ((flags & RF_ACTIVE) &&
3232 rle->flags |= RLE_ALLOCATED;
3236 "resource entry %#x type %d for child %s is busy\n", *rid,
3243 count = ulmax(count, rle->count);
3244 end = ulmax(rle->end, start + count - 1);
3248 type, rid, start, end, count, flags);
3281 int type,
int rid,
struct resource *res)
3283 struct resource_list_entry *rle = NULL;
3295 panic(
"resource_list_release: can't find resource");
3297 panic(
"resource_list_release: resource entry is not busy");
3298 if (rle->flags & RLE_RESERVED) {
3299 if (rle->flags & RLE_ALLOCATED) {
3306 rle->flags &= ~RLE_ALLOCATED;
3341 struct resource_list_entry *rle = NULL;
3346 "resource_list_unreserve() should only be called for direct children");
3351 panic(
"resource_list_unreserve: can't find resource");
3352 if (!(rle->flags & RLE_RESERVED))
3354 if (rle->flags & RLE_ALLOCATED)
3356 rle->flags &= ~RLE_RESERVED;
3379 struct resource_list_entry *rle;
3380 int printed, retval;
3385 STAILQ_FOREACH(rle, rl, link) {
3386 if (rle->type == type) {
3388 retval +=
printf(
" %s ", name);
3392 retval +=
printf(format, rle->start);
3393 if (rle->count > 1) {
3395 retval +=
printf(format, rle->start +
3413 struct resource_list_entry *rle;
3415 while ((rle = STAILQ_FIRST(rl)) != NULL) {
3418 rle->type, rle->rid, rle->res);
3419 STAILQ_REMOVE_HEAD(rl, link);
3442 devclass_t dc = dev->devclass;
3445 TAILQ_FOREACH(dl, &dc->drivers, link) {
3455 if (dl->pass > bus_current_pass)
3457 DEVICE_IDENTIFY(dl->
driver, dev);
3475 TAILQ_FOREACH(child, &dev->children, link) {
3495 if (dev->state != DS_ATTACHED)
3498 TAILQ_FOREACH(child, &dev->children, link) {
3518 TAILQ_FOREACH(child, &dev->children, link) {
3538 device_t child, child2;
3540 TAILQ_FOREACH(child, &dev->children, link) {
3541 error = DEVICE_SUSPEND(child);
3543 for (child2 = TAILQ_FIRST(&dev->children);
3544 child2 && child2 != child;
3545 child2 = TAILQ_NEXT(child2, link))
3546 DEVICE_RESUME(child2);
3564 TAILQ_FOREACH(child, &dev->children, link) {
3565 DEVICE_RESUME(child);
3657 struct resource_list *
3675 DEVICE_IDENTIFY(driver, dev);
3676 TAILQ_FOREACH(child, &dev->children, link) {
3677 if (child->state == DS_NOTPRESENT ||
3701 TAILQ_FOREACH(dl, &dc->drivers, link) {
3702 if (dl->pass == bus_current_pass)
3703 DEVICE_IDENTIFY(dl->
driver, dev);
3705 TAILQ_FOREACH(child, &dev->children, link) {
3706 if (child->state >= DS_ATTACHED)
3707 BUS_NEW_PASS(child);
3708 else if (child->state == DS_NOTPRESENT)
3721 int flags, driver_filter_t *filter, driver_intr_t *intr,
void *arg,
3726 return (BUS_SETUP_INTR(dev->parent, child, irq, flags,
3727 filter, intr, arg, cookiep));
3743 return (BUS_TEARDOWN_INTR(dev->parent, child, irq, cookie));
3755 struct resource *r, u_long
start, u_long end)
3759 return (BUS_ADJUST_RESOURCE(dev->parent, child, type, r, start,
3772 u_long
start, u_long end, u_long
count, u_int flags)
3776 return (BUS_ALLOC_RESOURCE(dev->parent, child, type, rid,
3777 start, end, count, flags));
3793 return (BUS_RELEASE_RESOURCE(dev->parent, child, type, rid,
3810 return (BUS_ACTIVATE_RESOURCE(dev->parent, child, type, rid,
3823 int rid,
struct resource *r)
3827 return (BUS_DEACTIVATE_RESOURCE(dev->parent, child, type, rid,
3845 return (BUS_BIND_INTR(dev->parent, child, irq, cpu));
3857 enum intr_polarity pol)
3862 return (BUS_CONFIG_INTR(dev->parent, irq, trig, pol));
3874 void *cookie,
const char *descr)
3879 return (BUS_DESCRIBE_INTR(dev->parent, child, irq, cookie,
3895 if (dev->parent != NULL)
3896 return (BUS_GET_DMA_TAG(dev->parent, child));
3910 u_long *startp, u_long *countp)
3912 struct resource_list * rl = NULL;
3913 struct resource_list_entry * rle = NULL;
3915 rl = BUS_GET_RESOURCE_LIST(dev, child);
3924 *startp = rle->start;
3926 *countp = rle->count;
3943 struct resource_list * rl = NULL;
3945 rl = BUS_GET_RESOURCE_LIST(dev, child);
3965 struct resource_list * rl = NULL;
3967 rl = BUS_GET_RESOURCE_LIST(dev, child);
3985 int rid,
struct resource *r)
3987 struct resource_list * rl = NULL;
3993 rl = BUS_GET_RESOURCE_LIST(dev, child);
4009 int *rid, u_long
start, u_long end, u_long
count, u_int flags)
4011 struct resource_list * rl = NULL;
4015 type, rid, start, end, count, flags));
4017 rl = BUS_GET_RESOURCE_LIST(dev, child);
4022 start, end, count, flags));
4047 struct resource **res)
4051 for (i = 0; rs[i].type != -1; i++)
4053 for (i = 0; rs[i].type != -1; i++) {
4054 res[i] = bus_alloc_resource_any(dev,
4055 rs[i].
type, &rs[i].rid, rs[i].flags);
4056 if (res[i] == NULL && !(rs[i].flags & RF_OPTIONAL)) {
4066 struct resource **res)
4070 for (i = 0; rs[i].type != -1; i++)
4071 if (res[i] != NULL) {
4073 dev, rs[i].
type, rs[i].rid, res[i]);
4086 u_long
count, u_int flags)
4088 if (dev->parent == NULL)
4090 return (BUS_ALLOC_RESOURCE(dev->parent, dev, type, rid, start, end,
4104 if (dev->parent == NULL)
4106 return (BUS_ADJUST_RESOURCE(dev->parent, dev, type, r, start, end));
4118 if (dev->parent == NULL)
4120 return (BUS_ACTIVATE_RESOURCE(dev->parent, dev, type, rid, r));
4132 if (dev->parent == NULL)
4134 return (BUS_DEACTIVATE_RESOURCE(dev->parent, dev, type, rid, r));
4146 if (dev->parent == NULL)
4148 return (BUS_RELEASE_RESOURCE(dev->parent, dev, type, rid, r));
4159 driver_filter_t filter, driver_intr_t handler,
void *arg,
void **cookiep)
4163 if (dev->parent == NULL)
4165 error = BUS_SETUP_INTR(dev->parent, dev, r, flags, filter, handler,
4169 if (handler != NULL && !(flags & INTR_MPSAFE))
4183 if (dev->parent == NULL)
4185 return (BUS_TEARDOWN_INTR(dev->parent, dev, r, cookie));
4197 if (dev->parent == NULL)
4199 return (BUS_BIND_INTR(dev->parent, dev, r, cpu));
4211 const char *fmt, ...)
4214 char descr[MAXCOMLEN + 1];
4216 if (dev->parent == NULL)
4219 vsnprintf(descr,
sizeof(descr), fmt, ap);
4221 return (BUS_DESCRIBE_INTR(dev->parent, dev, irq, cookie, descr));
4246 u_long *startp, u_long *countp)
4326 if (parent == NULL) {
4330 return (BUS_CHILD_PNPINFO_STR(parent, child, buf, buflen));
4345 if (parent == NULL) {
4349 return (BUS_CHILD_LOCATION_STR(parent, child, buf, buflen));
4366 return (BUS_GET_DMA_TAG(parent, dev));
4394 driver_filter_t *filter, driver_intr_t *intr,
void *arg,
void **cookiep)
4399 panic(
"root_setup_intr");
4445 TAILQ_INIT(&bus_data_devices);
4448 root_bus->desc =
"System root bus";
4449 kobj_init((kobj_t) root_bus, (kobj_class_t) &root_driver);
4451 root_bus->state = DS_ATTACHED;
4460 return (EOPNOTSUPP);
4471 DECLARE_MODULE(rootbus, root_bus_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
4500 struct driver_module_data *dmd;
4501 devclass_t bus_devclass;
4505 dmd = (
struct driver_module_data *)arg;
4511 if (dmd->dmd_chainevh)
4512 error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg);
4514 pass = dmd->dmd_pass;
4515 driver = dmd->dmd_driver;
4516 PDEBUG((
"Loading module: driver %s on bus %s (pass %d)",
4517 DRIVERNAME(driver), dmd->dmd_busname, pass));
4523 PDEBUG((
"Unloading module: driver %s from bus %s",
4529 if (!error && dmd->dmd_chainevh)
4530 error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg);
4533 PDEBUG((
"Quiesce module: driver %s from bus %s",
4539 if (!error && dmd->dmd_chainevh)
4540 error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg);
4564 const char *dname, *busname;
4573 BUS_HINTED_CHILD(bus, dname, dunit);
4581 BUS_HINTED_CHILD(bus, dname, dunit);
4596 indentprintf((
"device %d: <%s> %sparent,%schildren,%s%s%s%s%s,%sivars,%ssoftc,busy=%d\n",
4597 dev->unit, dev->desc,
4598 (dev->parent?
"":
"no "),
4599 (TAILQ_EMPTY(&dev->children)?
"no ":
""),
4600 (dev->flags&
DF_ENABLED?
"enabled,":
"disabled,"),
4604 (dev->flags&
DF_REBID?
"rebiddable,":
""),
4605 (dev->ivars?
"":
"no "),
4606 (dev->softc?
"":
"no "),
4618 indentprintf((
"Parent:\n"));
4620 indentprintf((
"Driver:\n"));
4622 indentprintf((
"Devclass:\n"));
4637 TAILQ_FOREACH(child, &dev->children, link) {
4653 TAILQ_FOREACH(child, &dev->children, link) {
4664 indentprintf((
"driver %s: softc size = %zd\n",
4665 driver->name, driver->size));
4682 TAILQ_FOREACH(driver, &drivers, link) {
4693 indentprintf((
"devclass %s: max units = %d\n", dc->name, dc->maxunit));
4705 indentprintf((
"Drivers:\n"));
4708 indentprintf((
"Devices:\n"));
4709 for (i = 0; i < dc->maxunit; i++)
4719 printf(
"Short listing of devclasses, drivers & devices:\n");
4720 TAILQ_FOREACH(dc, &devclasses, link) {
4730 printf(
"Full listing of devclasses, drivers & devices:\n");
4731 TAILQ_FOREACH(dc, &devclasses, link) {
4755 struct u_businfo ubus;
4757 ubus.ub_version = BUS_USER_VERSION;
4758 ubus.ub_generation = bus_data_generation;
4760 return (SYSCTL_OUT(req, &ubus,
sizeof(ubus)));
4763 "bus-related data");
4768 int *
name = (
int *)arg1;
4769 u_int namelen = arg2;
4772 struct u_device udev;
4786 TAILQ_FOREACH(dev, &bus_data_devices, devlink) {
4796 bzero(&udev,
sizeof(udev));
4797 udev.dv_handle = (uintptr_t)dev;
4798 udev.dv_parent = (uintptr_t)dev->parent;
4799 if (dev->nameunit != NULL)
4800 strlcpy(udev.dv_name, dev->nameunit,
sizeof(udev.dv_name));
4801 if (dev->desc != NULL)
4802 strlcpy(udev.dv_desc, dev->desc,
sizeof(udev.dv_desc));
4803 if (dev->driver != NULL && dev->driver->name != NULL)
4804 strlcpy(udev.dv_drivername, dev->driver->name,
4805 sizeof(udev.dv_drivername));
4808 udev.dv_devflags = dev->devflags;
4809 udev.dv_flags = dev->flags;
4810 udev.dv_state = dev->state;
4811 error = SYSCTL_OUT(req, &udev,
sizeof(udev));
4816 "system device tree");
4821 if (generation != bus_data_generation)
4831 bus_data_generation++;
int device_is_quiet(device_t dev)
Return non-zero if the DF_QUIET flag is set on the device.
#define print_devclass_list()
static void devremoved(device_t dev)
void device_disable(device_t dev)
Clear the DF_ENABLED flag for the device.
u_int rman_get_flags(struct resource *r)
struct resource * bus_alloc_resource(device_t dev, int type, int *rid, u_long start, u_long end, u_long count, u_int flags)
Wrapper function for BUS_ALLOC_RESOURCE().
static void devnomatch(device_t dev)
void bus_generic_driver_added(device_t dev, driver_t *driver)
Helper function for implementing BUS_DRIVER_ADDED().
device_t device_find_child(device_t dev, const char *classname, int unit)
Find a device given a unit number.
static int device_print_child(device_t dev, device_t child)
Print a description of a device.
int device_quiesce(device_t dev)
Tells a driver to quiesce itself.
const char * device_get_desc(device_t dev)
Return the device's description string.
int device_delete_children(device_t dev)
Delete all children devices of the given device, if any.
static kobj_method_t root_methods[]
static driverlink_t devclass_find_driver_internal(devclass_t dc, const char *classname)
int bus_generic_write_ivar(device_t dev, device_t child, int index, uintptr_t value)
Stub function for implementing BUS_WRITE_IVAR().
int bus_generic_teardown_intr(device_t dev, device_t child, struct resource *irq, void *cookie)
Helper function for implementing BUS_TEARDOWN_INTR().
int bus_child_pnpinfo_str(device_t child, char *buf, size_t buflen)
Wrapper function for BUS_CHILD_PNPINFO_STR().
device_t device_add_child(device_t dev, const char *name, int unit)
Create a new device.
void * devclass_get_softc(devclass_t dc, int unit)
Find the softc field of a device given a unit number.
int device_is_attached(device_t dev)
Return non-zero if the device currently has a driver attached to it.
int bus_generic_adjust_resource(device_t dev, device_t child, int type, struct resource *r, u_long start, u_long end)
Helper function for implementing BUS_ADJUST_RESOURCE().
#define print_device_short(d, i)
static int sysctl_devctl_disable(SYSCTL_HANDLER_ARGS)
int device_printf(device_t dev, const char *fmt,...)
Print the name of the device followed by a colon, a space and the result of calling vprintf() with th...
void selwakeup(struct selinfo *sip)
int snprintf(char *str, size_t size, const char *format,...)
int device_is_enabled(device_t dev)
Return non-zero if the DF_ENABLED flag is set on the device.
int rman_get_rid(struct resource *r)
void resource_list_delete(struct resource_list *rl, int type, int rid)
Delete a resource entry.
int bus_generic_rl_set_resource(device_t dev, device_t child, int type, int rid, u_long start, u_long count)
Helper function for implementing BUS_SET_RESOURCE().
int bus_generic_setup_intr(device_t dev, device_t child, struct resource *irq, int flags, driver_filter_t *filter, driver_intr_t *intr, void *arg, void **cookiep)
Helper function for implementing BUS_SETUP_INTR().
static void device_set_desc_internal(device_t dev, const char *desc, int copy)
void selrecord(struct thread *selector, struct selinfo *sip)
int bus_generic_child_present(device_t dev, device_t child)
Helper function for implementing BUS_CHILD_PRESENT().
int bus_generic_rl_get_resource(device_t dev, device_t child, int type, int rid, u_long *startp, u_long *countp)
Helper function for implementing BUS_GET_RESOURCE().
struct resource * resource_list_alloc(struct resource_list *rl, device_t bus, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags)
Helper function for implementing BUS_ALLOC_RESOURCE()
int devclass_add_driver(devclass_t dc, driver_t *driver, int pass, devclass_t *dcp)
Add a device driver to a device class.
static int sysctl_devices(SYSCTL_HANDLER_ARGS)
void * malloc(unsigned long size, struct malloc_type *mtp, int flags)
void device_busy(device_t dev)
Increment the busy counter for the device.
void bus_delete_resource(device_t dev, int type, int rid)
Wrapper function for BUS_DELETE_RESOURCE().
int resource_find_match(int *anchor, const char **name, int *unit, const char *resname, const char *value)
int bus_setup_intr(device_t dev, struct resource *r, int flags, driver_filter_t filter, driver_intr_t handler, void *arg, void **cookiep)
Wrapper function for BUS_SETUP_INTR().
int resource_list_busy(struct resource_list *rl, int type, int rid)
Determine if a resource entry is busy.
static int devclass_sysctl_handler(SYSCTL_HANDLER_ARGS)
int devclass_get_drivers(devclass_t dc, driver_t ***listp, int *countp)
Get a list of drivers in the devclass.
static devclass_t devclass_find_internal(const char *classname, const char *parentname, int create)
Find or create a device class.
void panic(const char *fmt,...)
void device_quiet(device_t dev)
Set the DF_QUIET flag for the device.
void device_enable(device_t dev)
Set the DF_ENABLED flag for the device.
static struct dev_softc devsoftc
device_t bus_generic_add_child(device_t dev, u_int order, const char *name, int unit)
static void driver_register_pass(struct driverlink *new)
Register the pass level of a new driver attachment.
int device_get_unit(device_t dev)
Return the device's unit number.
u_long bus_get_resource_start(device_t dev, int type, int rid)
Wrapper function for BUS_GET_RESOURCE().
static driver_t root_driver
static void device_sysctl_update(device_t dev)
SYSCTL_PROC(_hw_bus, OID_AUTO, devctl_disable, CTLTYPE_INT|CTLFLAG_RW, NULL, 0, sysctl_devctl_disable,"I","devctl disable -- deprecated")
#define print_devclass(d, i)
static moduledata_t root_bus_mod
void resource_list_init(struct resource_list *rl)
Initialise a resource list.
struct resource * bus_generic_alloc_resource(device_t dev, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags)
Helper function for implementing BUS_ALLOC_RESOURCE().
const char * devclass_get_name(devclass_t dc)
Return the name of the devclass.
void bus_enumerate_hinted_children(device_t bus)
Enumerate all hinted devices for this bus.
void device_set_flags(device_t dev, uint32_t flags)
Set the device's flags.
static int root_print_child(device_t dev, device_t child)
static void devclass_sysctl_init(devclass_t dc)
int bus_deactivate_resource(device_t dev, int type, int rid, struct resource *r)
Wrapper function for BUS_DEACTIVATE_RESOURCE().
device_state_t device_get_state(device_t dev)
Return the device's state.
int resource_disabled(const char *name, int unit)
void * device_get_ivars(device_t dev)
Get the device's ivars field.
boolean_t devctl_process_running(void)
Return whether the userland process is running.
void resource_list_purge(struct resource_list *rl)
Releases all the resources in a list.
SYSCTL_INT(_debug, OID_AUTO, boothowto, CTLFLAG_RD,&boothowto, 0,"Boot control flags, passed from loader")
#define print_device_tree_short(d, i)
#define print_driver_short(d, i)
int devclass_get_devices(devclass_t dc, device_t **devlistp, int *devcountp)
Get a list of devices in the devclass.
struct cdev * make_dev_credf(int flags, struct cdevsw *devsw, int unit, struct ucred *cr, uid_t uid, gid_t gid, int mode, const char *fmt,...)
u_long bus_get_resource_count(device_t dev, int type, int rid)
Wrapper function for BUS_GET_RESOURCE().
void kern_psignal(struct proc *p, int sig)
int bus_generic_activate_resource(device_t dev, device_t child, int type, int rid, struct resource *r)
Helper function for implementing BUS_ACTIVATE_RESOURCE().
int bus_generic_resume(device_t dev)
Helper function for implementing DEVICE_RESUME()
int resource_string_value(const char *name, int unit, const char *resname, const char **result)
int resource_list_print_type(struct resource_list *rl, const char *name, int type, const char *format)
Print a description of resources in a resource list.
int devclass_get_count(devclass_t dc)
Get the number of devices in a devclass.
static struct cdevsw dev_cdevsw
int vsnprintf(char *str, size_t size, const char *format, va_list ap)
int bus_get_resource(device_t dev, int type, int rid, u_long *startp, u_long *countp)
Wrapper function for BUS_GET_RESOURCE().
void device_claim_softc(device_t dev)
Claim softc.
int resource_list_reserved(struct resource_list *rl, int type, int rid)
Determine if a resource entry is reserved.
u_long rman_get_start(struct resource *r)
int device_probe(device_t dev)
Probe a device, and return this status.
struct sysctl_ctx_list * device_get_sysctl_ctx(device_t dev)
static int sysctl_bus(SYSCTL_HANDLER_ARGS)
int resource_list_add_next(struct resource_list *rl, int type, u_long start, u_long end, u_long count)
Add a resource entry.
Implementation of device.
void bus_generic_rl_delete_resource(device_t dev, device_t child, int type, int rid)
Helper function for implementing BUS_DELETE_RESOURCE().
void devclass_set_parent(devclass_t dc, devclass_t pdc)
Set the parent of a devclass.
static int root_setup_intr(device_t dev, device_t child, struct resource *irq, int flags, driver_filter_t *filter, driver_intr_t *intr, void *arg, void **cookiep)
void device_unbusy(device_t dev)
Decrement the busy counter for the device.
int device_probe_and_attach(device_t dev)
Probe a device and attach a driver if possible.
int bus_set_resource(device_t dev, int type, int rid, u_long start, u_long count)
Wrapper function for BUS_SET_RESOURCE().
#define print_devclass_short(d, i)
static void devclass_driver_added(devclass_t dc, driver_t *driver)
Register that a device driver has been added to a devclass.
static int root_bus_module_handler(module_t mod, int what, void *arg)
void bus_generic_new_pass(device_t dev)
Helper function for implementing BUS_NEW_PASS().
void bus_set_pass(int pass)
Raise the current bus pass.
TUNABLE_INT("hw.bus.devctl_queue",&devctl_queue_length)
static void device_sysctl_fini(device_t dev)
void sysctl_rename_oid(struct sysctl_oid *oidp, const char *name)
int bus_generic_describe_intr(device_t dev, device_t child, struct resource *irq, void *cookie, const char *descr)
Helper function for implementing BUS_DESCRIBE_INTR().
int devclass_find_free_unit(devclass_t dc, int unit)
Find a free unit number in a devclass.
int bus_generic_suspend(device_t dev)
Helper function for implementing DEVICE_SUSPEND()
devclass_t devclass_get_parent(devclass_t dc)
Get the parent of a devclass.
int bus_describe_intr(device_t dev, struct resource *irq, void *cookie, const char *fmt,...)
Wrapper function for BUS_DESCRIBE_INTR().
typedef TAILQ_HEAD(devclass_list, devclass)
void resource_list_free(struct resource_list *rl)
Reclaim memory used by a resource list.
int bus_generic_detach(device_t dev)
Helper function for implementing DEVICE_DETACH()
int resource_int_value(const char *name, int unit, const char *resname, int *result)
bus_dma_tag_t bus_get_dma_tag(device_t dev)
Wrapper function for BUS_GET_DMA_TAG().
int bus_child_present(device_t child)
Wrapper function for BUS_CHILD_PRESENT().
int device_is_alive(device_t dev)
Return non-zero if the device was successfully probed.
static void devinit(void)
static int devclass_driver_deleted(devclass_t busclass, devclass_t dc, driver_t *driver)
Register that a device driver has been deleted from a devclass.
struct resource_list * bus_generic_get_resource_list(device_t dev, device_t child)
Stub function for implementing BUS_GET_RESOURCE_LIST().
device_t device_get_parent(device_t dev)
Return the parent of a device.
int device_probe_child(device_t dev, device_t child)
int bus_data_generation_check(int generation)
int bus_generic_probe(device_t dev)
Helper function for implementing DEVICE_PROBE()
void bus_release_resources(device_t dev, const struct resource_spec *rs, struct resource **res)
struct sysctl_ctx_list * devclass_get_sysctl_ctx(devclass_t dc)
static driverlink_t next_matching_driver(devclass_t dc, device_t dev, driverlink_t last)
int device_print_prettyname(device_t dev)
Print the name of the device followed by a colon and a space.
struct device * rman_get_device(struct resource *r)
struct sysctl_oid * device_get_sysctl_tree(device_t dev)
#define print_devclass_list_short()
int bus_generic_bind_intr(device_t dev, device_t child, struct resource *irq, int cpu)
Helper function for implementing BUS_BIND_INTR().
devclass_t device_get_devclass(device_t dev)
Return the current devclass for the device or NULL if there is none.
static MALLOC_DEFINE(M_BUS,"bus","Bus data structures")
void kobj_delete(kobj_t obj, struct malloc_type *mtype)
int bus_print_child_header(device_t dev, device_t child)
Helper function for implementing BUS_PRINT_CHILD().
static int devclass_alloc_unit(devclass_t dc, device_t dev, int *unitp)
Allocate a unit number.
static int devctl_queue_length
int bus_print_child_footer(device_t dev, device_t child)
Helper function for implementing BUS_PRINT_CHILD().
int bus_child_location_str(device_t child, char *buf, size_t buflen)
Wrapper function for BUS_CHILD_LOCATION_STR().
static struct cdev * devctl_dev
int device_detach(device_t dev)
Detach a driver from a device.
void devctl_queue_data(char *data)
int bus_generic_attach(device_t dev)
Helper function for implementing DEVICE_ATTACH()
int bus_generic_release_resource(device_t dev, device_t child, int type, int rid, struct resource *r)
Helper function for implementing BUS_RELEASE_RESOURCE().
int bus_activate_resource(device_t dev, int type, int rid, struct resource *r)
Wrapper function for BUS_ACTIVATE_RESOURCE().
SYSCTL_NODE(_hw, OID_AUTO, bus, CTLFLAG_RW, NULL, NULL)
int device_set_driver(device_t dev, driver_t *driver)
Set the driver of a device.
#define print_driver(d, i)
int device_set_devclass(device_t dev, const char *classname)
Set the devclass of a device.
void device_verbose(device_t dev)
Clear the DF_QUIET flag for the device.
int sysctl_handle_int(SYSCTL_HANDLER_ARGS)
static int root_resume(device_t dev)
void devctl_notify(const char *system, const char *subsystem, const char *type, const char *data)
#define DEVCTL_DEFAULT_QUEUE_LEN
int bus_free_resource(device_t dev, int type, struct resource *r)
struct sysctl_oid * devclass_get_sysctl_tree(devclass_t dc)
static driver_list_t passes
int bus_generic_read_ivar(device_t dev, device_t child, int index, uintptr_t *result)
Stub function for implementing BUS_READ_IVAR().
void devctl_queue_data_f(char *data, int flags)
Queue data to be read from the devctl device.
static driverlink_t first_matching_driver(devclass_t dc, device_t dev)
static int devclass_delete_device(devclass_t dc, device_t dev)
Delete a device from a devclass.
int bus_teardown_intr(device_t dev, struct resource *r, void *cookie)
Wrapper function for BUS_TEARDOWN_INTR().
int resource_list_unreserve(struct resource_list *rl, device_t bus, device_t child, int type, int rid)
Fully release a reserved resource.
static int devclass_quiesce_driver(devclass_t busclass, driver_t *driver)
Quiesces a set of device drivers from a device class.
void kobj_class_free(kobj_class_t cls)
void device_set_desc_copy(device_t dev, const char *desc)
Set the device's description.
device_t devclass_get_device(devclass_t dc, int unit)
Find a device given a unit number.
void device_set_softc(device_t dev, void *softc)
Set the device's softc field.
int device_shutdown(device_t dev)
Notify a device of system shutdown.
void cv_init(struct cv *cvp, const char *desc)
#define print_device_tree(d, i)
int bus_generic_shutdown(device_t dev)
Helper function for implementing DEVICE_SHUTDOWN()
int resource_list_release(struct resource_list *rl, device_t bus, device_t child, int type, int rid, struct resource *res)
Helper function for implementing BUS_RELEASE_RESOURCE()
int uiomove(void *cp, int n, struct uio *uio)
void root_bus_configure(void)
Automatically configure devices.
void devctl_notify_f(const char *system, const char *subsystem, const char *type, const char *data, int flags)
Send a 'notification' to userland, using standard ways.
int devclass_get_maxunit(devclass_t dc)
Get the maximum unit number used in a devclass.
void free(void *addr, struct malloc_type *mtp)
#define print_driver_list(d, i)
int printf(const char *fmt,...)
struct resource * bus_generic_rl_alloc_resource(device_t dev, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags)
Helper function for implementing BUS_ALLOC_RESOURCE().
static int root_child_present(device_t dev, device_t child)
DEFINE_CLASS(null, null_methods, 0)
int devclass_delete_driver(devclass_t busclass, driver_t *driver)
Delete a device driver from a device class.
struct resource_list_entry * resource_list_find(struct resource_list *rl, int type, int rid)
Find a resource entry by type and rid.
static devclass_list_t devclasses
void * device_get_softc(device_t dev)
Return the device's softc field.
static void device_sysctl_init(device_t dev)
struct resource * resource_list_reserve(struct resource_list *rl, device_t bus, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags)
Allocate a reserved resource.
void mtx_init(struct mtx *m, const char *name, const char *type, int opts)
static d_close_t devclose
int bus_generic_print_child(device_t dev, device_t child)
Helper function for implementing BUS_PRINT_CHILD().
int bus_alloc_resources(device_t dev, struct resource_spec *rs, struct resource **res)
int bus_release_resource(device_t dev, int type, int rid, struct resource *r)
Wrapper function for BUS_RELEASE_RESOURCE().
u_long rman_get_end(struct resource *r)
DECLARE_MODULE(rootbus, root_bus_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST)
#define print_device(d, i)
void kobj_class_compile(kobj_class_t cls)
const char * device_get_nameunit(device_t dev)
Return a string containing the device's devclass name followed by an ascii representation of the devi...
int device_attach(device_t dev)
Attach a device driver to a device.
int bus_adjust_resource(device_t dev, int type, struct resource *r, u_long start, u_long end)
Wrapper function for BUS_ADJUST_RESOURCE().
int device_delete_child(device_t dev, device_t child)
Delete a device.
const char * device_get_name(device_t dev)
Return the name of the device's devclass or NULL if there is none.
int vprintf(const char *fmt, va_list ap)
int bus_generic_rl_release_resource(device_t dev, device_t child, int type, int rid, struct resource *r)
Helper function for implementing BUS_RELEASE_RESOURCE().
struct driverlink * driverlink_t
static d_ioctl_t devioctl
driver_t * device_get_driver(device_t dev)
Return the current driver for the device or NULL if there is no driver currently attached.
void device_set_desc(device_t dev, const char *desc)
Set the device's description.
int sysctl_ctx_free(struct sysctl_ctx_list *clist)
int bus_bind_intr(device_t dev, struct resource *r, int cpu)
Wrapper function for BUS_BIND_INTR().
int bus_generic_config_intr(device_t dev, int irq, enum intr_trigger trig, enum intr_polarity pol)
Helper function for implementing BUS_CONFIG_INTR().
int device_get_children(device_t dev, device_t **devlistp, int *devcountp)
Get a list of children of a device.
void kobj_init(kobj_t obj, kobj_class_t cls)
struct resource_list_entry * resource_list_add(struct resource_list *rl, int type, int rid, u_long start, u_long end, u_long count)
Add or modify a resource entry.
int bus_generic_deactivate_resource(device_t dev, device_t child, int type, int rid, struct resource *r)
Helper function for implementing BUS_DEACTIVATE_RESOURCE().
int device_set_unit(device_t dev, int unit)
Set the unit number of a device.
void device_free_softc(void *softc)
Free claimed softc.
devclass_t devclass_find(const char *classname)
Find a device class.
uint32_t device_get_flags(device_t dev)
Return the device's flags.
void bus_data_generation_update(void)
static int device_sysctl_handler(SYSCTL_HANDLER_ARGS)
static device_t make_device(device_t parent, const char *name, int unit)
Make a new device and add it as a child of parent.
void device_set_ivars(device_t dev, void *ivars)
Set the device's ivars field.
int driver_module_handler(module_t mod, int what, void *arg)
Module handler for registering device drivers.
static void devaddq(const char *type, const char *what, device_t dev)
static int sysctl_devctl_queue(SYSCTL_HANDLER_ARGS)
bus_dma_tag_t bus_generic_get_dma_tag(device_t dev, device_t child)
Helper function for implementing BUS_GET_DMA_TAG().
devclass_t devclass_create(const char *classname)
Create a device class.
static void devadded(device_t dev)
static int devclass_add_device(devclass_t dc, device_t dev)
Add a device to a devclass.
device_t device_add_child_ordered(device_t dev, u_int order, const char *name, int unit)
Create a new device.
int sysctl_ctx_init(struct sysctl_ctx_list *c)