37#include <sys/domainset.h>
38#include <sys/eventhandler.h>
41#include <sys/kernel.h>
43#include <sys/limits.h>
44#include <sys/malloc.h>
45#include <sys/module.h>
50#include <sys/condvar.h>
52#include <machine/bus.h>
53#include <sys/random.h>
54#include <sys/refcount.h>
57#include <sys/selinfo.h>
58#include <sys/signalvar.h>
60#include <sys/sysctl.h>
64#include <sys/cpuset.h>
68#include <machine/cpu.h>
69#include <machine/stdarg.h>
90#define DL_DEFERRED_PROBE 1
97typedef TAILQ_HEAD(devclass_list, devclass) devclass_list_t;
102 TAILQ_ENTRY(devclass) link;
104 driver_list_t drivers;
109#define DC_HAS_CHILDREN 1
111 struct sysctl_ctx_list sysctl_ctx;
112 struct sysctl_oid *sysctl_tree;
134 device_list_t children;
145 device_state_t state;
152 struct sysctl_ctx_list sysctl_ctx;
153 struct sysctl_oid *sysctl_tree;
166#define DRIVERNAME(d) ((d)? d->name : "no driver")
167#define DEVCLANAME(d) ((d)? d->name : "no devclass")
171static int bus_debug = 1;
172SYSCTL_INT(_debug, OID_AUTO, bus_debug, CTLFLAG_RWTUN, &bus_debug, 0,
174#define PDEBUG(a) if (bus_debug) {printf("%s:%d: ", __func__, __LINE__), printf a; printf("\n");}
175#define DEVICENAME(d) ((d)? device_get_name(d): "no device")
181#define indentprintf(p) do { int iJ; printf("."); for (iJ=0; iJ<indent; iJ++) printf(" "); printf p ; } while (0)
200#define print_device_short(d,i)
201#define print_device(d,i)
202#define print_device_tree_short(d,i)
203#define print_device_tree(d,i)
204#define print_driver_short(d,i)
205#define print_driver(d,i)
206#define print_driver_list(d,i)
207#define print_devclass_short(d,i)
208#define print_devclass(d,i)
209#define print_devclass_list_short()
210#define print_devclass_list()
224 devclass_t dc = (devclass_t)arg1;
229 value = dc->parent ? dc->parent->name :
"";
234 return (SYSCTL_OUT_STR(req,
value));
240 if (dc->sysctl_tree != NULL)
243 dc->sysctl_tree = SYSCTL_ADD_NODE(&dc->sysctl_ctx,
244 SYSCTL_STATIC_CHILDREN(_dev), OID_AUTO, dc->name,
245 CTLFLAG_RD | CTLFLAG_MPSAFE, NULL,
"");
246 SYSCTL_ADD_PROC(&dc->sysctl_ctx, SYSCTL_CHILDREN(dc->sysctl_tree),
248 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
265 device_t dev = (device_t)arg1;
273 sbuf_cat(&sb, dev->desc ? dev->desc :
"");
276 sbuf_cat(&sb, dev->driver ? dev->driver->name :
"");
285 sbuf_cat(&sb, dev->parent ? dev->parent->nameunit :
"");
301 devclass_t dc = dev->devclass;
304 if (dev->sysctl_tree != NULL)
308 dev->sysctl_tree = SYSCTL_ADD_NODE_WITH_LABEL(&dev->sysctl_ctx,
309 SYSCTL_CHILDREN(dc->sysctl_tree), OID_AUTO,
310 dev->nameunit + strlen(dc->name),
311 CTLFLAG_RD | CTLFLAG_MPSAFE, NULL,
"",
"device_index");
312 SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
313 OID_AUTO,
"%desc", CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
315 "device description");
316 SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
318 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
320 "device driver name");
321 SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
322 OID_AUTO,
"%location",
323 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
325 "device location relative to parent");
326 SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
327 OID_AUTO,
"%pnpinfo",
328 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
330 "device identification");
331 SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
333 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
337 SYSCTL_ADD_INT(&dev->sysctl_ctx,
338 SYSCTL_CHILDREN(dev->sysctl_tree), OID_AUTO,
"%domain",
339 CTLFLAG_RD | CTLFLAG_MPSAFE, NULL,
domain,
"NUMA domain");
345 devclass_t dc = dev->devclass;
347 if (dev->sysctl_tree == NULL)
355 if (dev->sysctl_tree == NULL)
358 dev->sysctl_tree = NULL;
375#define DEVCTL_DEFAULT_QUEUE_LEN 1000
389 .d_version = D_VERSION,
399#define DEVCTL_BUFFER (1024 - sizeof(void *))
438 UID_ROOT, GID_WHEEL, 0600,
"devctl");
439 mtx_init(&
devsoftc.
mtx,
"dev mtx",
"devd", MTX_DEF);
456 uma_zone_set_maxcache(z, 0);
457 uma_zone_reserve(z, reserve);
458 uma_prealloc(z, reserve);
464devopen(
struct cdev *dev,
int oflags,
int devtype,
struct thread *td)
478devclose(
struct cdev *dev,
int fflag,
int devtype,
struct thread *td)
499devread(
struct cdev *dev,
struct uio *uio,
int ioflag)
523 rv =
uiomove(n1->dei_data, strlen(n1->dei_data), uio);
529devioctl(
struct cdev *dev, u_long cmd, caddr_t
data,
int fflag,
struct thread *td)
561devpoll(
struct cdev *dev,
int events,
struct thread *td)
566 if (events & (POLLIN | POLLRDNORM)) {
568 revents = events & (POLLIN | POLLRDNORM);
582 if (kn->kn_filter == EVFILT_READ) {
601 return (kn->kn_data != 0);
623 dei = uma_zalloc(
devsoftc.
zone, M_NOWAIT | M_USE_RESERVE);
640 *dei->dei_data =
'\0';
653 sbuf_new(sb, dei->dei_data,
sizeof(dei->dei_data), SBUF_FIXEDLEN);
687 if (system == NULL || subsystem == NULL ||
type == NULL)
806 if (error || !req->newptr)
852 while (*
src !=
'\0') {
853 if (*
src ==
'"' || *
src ==
'\\')
929 TAILQ_FOREACH(dl, &
passes, passlink) {
930 if (dl->pass < new->pass)
932 if (dl->pass == new->pass)
934 TAILQ_INSERT_BEFORE(dl,
new, passlink);
937 TAILQ_INSERT_TAIL(&
passes,
new, passlink);
953 panic(
"Attempt to lower bus pass level");
955 TAILQ_FOREACH(dl, &
passes, passlink) {
1012 PDEBUG((
"looking for %s", classname));
1017 if (!strcmp(dc->name, classname))
1021 if (create && !dc) {
1022 PDEBUG((
"creating %s", classname));
1023 dc =
malloc(
sizeof(
struct devclass) + strlen(classname) + 1,
1024 M_BUS, M_NOWAIT | M_ZERO);
1028 dc->name = (
char*) (dc + 1);
1029 strcpy(dc->name, classname);
1030 TAILQ_INIT(&dc->drivers);
1044 if (parentname && dc && !dc->parent &&
1045 strcmp(classname, parentname) != 0) {
1107 for (i = 0; i < dc->maxunit; i++)
1109 BUS_DRIVER_ADDED(dc->devices[i],
driver);
1123 if (dc->parent ==
parent)
1143 const char *parentname;
1148 if (pass <= BUS_PASS_ROOT)
1151 dl =
malloc(
sizeof *dl, M_BUS, M_NOWAIT|M_ZERO);
1171 parentname =
driver->baseclasses[0]->name;
1177 TAILQ_INSERT_TAIL(&dc->drivers, dl, link);
1230 for (i = 0; i < dc->maxunit; i++) {
1231 if (dc->devices[i]) {
1232 dev = dc->devices[i];
1233 if (dev->driver ==
driver && dev->parent &&
1234 dev->parent->devclass == busclass) {
1238 dev->flags &= ~DF_DONENOMATCH;
1239 dev->flags |= DF_NEEDNOMATCH;
1241 BUS_PROBE_NOMATCH(dev->parent, dev);
1243 dev->flags |= DF_DONENOMATCH;
1261 if (busclass->parent ==
parent) {
1299 TAILQ_FOREACH(dl, &busclass->drivers, link) {
1314 TAILQ_REMOVE(&busclass->drivers, dl, link);
1356 TAILQ_FOREACH(dl, &busclass->drivers, link) {
1377 for (i = 0; i < dc->maxunit; i++) {
1378 if (dc->devices[i]) {
1379 dev = dc->devices[i];
1380 if (dev->driver ==
driver && dev->parent &&
1381 dev->parent->devclass == busclass) {
1401 TAILQ_FOREACH(dl, &dc->drivers, link) {
1402 if (!strcmp(dl->
driver->name, classname))
1431 if (dc == NULL || unit < 0 || unit >= dc->maxunit)
1433 return (dc->devices[unit]);
1481 list =
malloc(
count *
sizeof(device_t), M_TEMP, M_NOWAIT|M_ZERO);
1486 for (i = 0; i < dc->maxunit; i++) {
1487 if (dc->devices[i]) {
1488 list[
count] = dc->devices[i];
1523 TAILQ_FOREACH(dl, &dc->drivers, link)
1525 list =
malloc(
count *
sizeof(driver_t *), M_TEMP, M_NOWAIT);
1530 TAILQ_FOREACH(dl, &dc->drivers, link) {
1551 for (i = 0; i < dc->maxunit; i++)
1571 return (dc->maxunit);
1588 while (unit < dc->maxunit && dc->devices[unit] != NULL)
1616 return (dc->parent);
1619struct sysctl_ctx_list *
1622 return (&dc->sysctl_ctx);
1628 return (dc->sysctl_tree);
1662 if (unit >= 0 && unit < dc->maxunit &&
1663 dc->devices[unit] != NULL) {
1665 printf(
"%s: %s%d already exists; skipping it\n",
1666 dc->name, dc->name, *unitp);
1672 for (unit = 0;; unit++) {
1674 if (unit < dc->maxunit && dc->devices[unit] != NULL)
1691 if (unit >= dc->maxunit) {
1692 device_t *newlist, *oldlist;
1695 oldlist = dc->devices;
1696 newsize = roundup((unit + 1),
1697 MAX(1, MINALLOCSIZE /
sizeof(device_t)));
1698 newlist =
malloc(
sizeof(device_t) * newsize, M_BUS, M_NOWAIT);
1701 if (oldlist != NULL)
1702 bcopy(oldlist, newlist,
sizeof(device_t) * dc->maxunit);
1703 bzero(newlist + dc->maxunit,
1704 sizeof(device_t) * (newsize - dc->maxunit));
1705 dc->devices = newlist;
1706 dc->maxunit = newsize;
1707 if (oldlist != NULL)
1708 free(oldlist, M_BUS);
1739 buflen =
snprintf(NULL, 0,
"%s%d$", dc->name, INT_MAX);
1742 dev->nameunit =
malloc(buflen, M_BUS, M_NOWAIT|M_ZERO);
1747 free(dev->nameunit, M_BUS);
1748 dev->nameunit = NULL;
1751 dc->devices[dev->unit] = dev;
1753 snprintf(dev->nameunit, buflen,
"%s%d", dc->name, dev->unit);
1778 if (dev->devclass != dc || dc->devices[dev->unit] != dev)
1779 panic(
"devclass_delete_device: inconsistent device class");
1780 dc->devices[dev->unit] = NULL;
1781 if (dev->flags & DF_WILDCARD)
1783 dev->devclass = NULL;
1784 free(dev->nameunit, M_BUS);
1785 dev->nameunit = NULL;
1813 printf(
"make_device: can't find device class %s\n",
1821 dev =
malloc(
sizeof(*dev), M_BUS, M_NOWAIT|M_ZERO);
1826 TAILQ_INIT(&dev->children);
1829 dev->devclass = NULL;
1831 dev->nameunit = NULL;
1835 dev->flags = DF_ENABLED;
1838 dev->flags |= DF_WILDCARD;
1840 dev->flags |= DF_FIXEDCLASS;
1847 dev->flags |= DF_QUIET | DF_QUIET_CHILDREN;
1851 dev->state = DS_NOTPRESENT;
1869 retval += BUS_PRINT_CHILD(dev,
child);
1924 PDEBUG((
"%s at %s with order %u as unit %d",
1926 KASSERT(
name != NULL || unit == -1,
1927 (
"child device with wildcard name and specific unit number"));
1932 child->order = order;
1934 TAILQ_FOREACH(place, &dev->children, link) {
1935 if (place->order > order)
1944 TAILQ_INSERT_BEFORE(place,
child, link);
1950 TAILQ_INSERT_TAIL(&dev->children,
child, link);
1974 device_t grandchild;
1983 while ((grandchild = TAILQ_FIRST(&
child->children)) != NULL) {
1989 if (
child->devclass)
1992 BUS_CHILD_DELETED(dev,
child);
1993 TAILQ_REMOVE(&dev->children,
child, link);
2024 while ((
child = TAILQ_FIRST(&dev->children)) != NULL) {
2080 return (TAILQ_FIRST(&dc->drivers));
2089 if (dev->devclass) {
2091 for (dl = TAILQ_NEXT(last, link); dl; dl = TAILQ_NEXT(dl, link))
2092 if (!strcmp(dev->devclass->name, dl->
driver->name))
2096 return (TAILQ_NEXT(last, link));
2110 int hasclass = (
child->devclass != NULL);
2116 panic(
"device_probe_child: parent device has no devclass");
2121 if (
child->state == DS_ALIVE)
2124 for (; dc; dc = dc->parent) {
2140 dl->
driver->name) != 0) {
2141 char const * devname =
2143 if (devname == NULL)
2144 devname =
"(unknown)";
2145 printf(
"driver bug: Unable to set "
2146 "devclass (class: %s "
2157 "flags", &
child->devflags);
2172 child->devflags = 0;
2187 if (
result <= BUS_PROBE_NOWILDCARD &&
2188 !(
child->flags & DF_FIXEDCLASS)) {
2206 if (best == NULL ||
result > pri) {
2216 if (best && pri == 0)
2231 if (!
child->devclass) {
2239 "flags", &
child->devflags);
2254 child->state = DS_ALIVE;
2265 return (dev->parent);
2292 TAILQ_FOREACH(
child, &dev->children, link) {
2301 list =
malloc(
count *
sizeof(device_t), M_TEMP, M_NOWAIT|M_ZERO);
2306 TAILQ_FOREACH(
child, &dev->children, link) {
2324 return (dev->driver);
2334 return (dev->devclass);
2344 if (dev != NULL && dev->devclass)
2357 return (dev->nameunit);
2384 return (dev->devflags);
2387struct sysctl_ctx_list *
2390 return (&dev->sysctl_ctx);
2396 return (dev->sysctl_tree);
2410 return (
printf(
"unknown: "));
2499 if (dev->desc && (dev->flags & DF_DESCMALLOCED)) {
2500 free(dev->desc, M_BUS);
2501 dev->flags &= ~DF_DESCMALLOCED;
2506 dev->desc =
malloc(strlen(desc) + 1, M_BUS, M_NOWAIT);
2508 strcpy(dev->desc, desc);
2509 dev->flags |= DF_DESCMALLOCED;
2513 dev->desc = (
char *)(uintptr_t) desc;
2550 dev->devflags =
flags;
2562 return (dev->softc);
2574 if (dev->softc && !(dev->flags & DF_EXTERNALSOFTC))
2575 free(dev->softc, M_BUS_SC);
2578 dev->flags |= DF_EXTERNALSOFTC;
2580 dev->flags &= ~DF_EXTERNALSOFTC;
2592 free(softc, M_BUS_SC);
2607 dev->flags |= DF_EXTERNALSOFTC;
2609 dev->flags &= ~DF_EXTERNALSOFTC;
2622 KASSERT(dev != NULL, (
"device_get_ivars(NULL, ...)"));
2623 return (dev->ivars);
2632 KASSERT(dev != NULL, (
"device_set_ivars(NULL, ...)"));
2642 return (dev->state);
2651 dev->flags |= DF_ENABLED;
2660 dev->flags &= ~DF_ENABLED;
2674 if (refcount_acquire(&dev->busy) == 0 && dev->parent != NULL)
2688 if (refcount_release(&dev->busy) && dev->parent != NULL)
2698 dev->flags |= DF_QUIET;
2707 dev->flags |= DF_QUIET_CHILDREN;
2716 dev->flags &= ~DF_QUIET;
2721 device_property_type_t
type)
2726 case DEVICE_PROP_ANY:
2727 case DEVICE_PROP_BUFFER:
2729 case DEVICE_PROP_UINT32:
2733 case DEVICE_PROP_UINT64:
2741 return (BUS_GET_PROPERTY(
bus, dev, prop, val, sz,
type));
2756 return ((dev->flags & DF_QUIET_CHILDREN) != 0);
2765 return ((dev->flags & DF_QUIET) != 0);
2774 return ((dev->flags & DF_ENABLED) != 0);
2783 return (dev->state >= DS_ALIVE);
2793 return (dev->state >= DS_ATTACHED);
2802 return ((dev->flags & DF_SUSPENDED) != 0);
2821 if (dev->devclass) {
2822 printf(
"device_set_devclass: device class already set\n");
2845 if (classname == NULL)
2851 dev->flags |= DF_FIXEDCLASS;
2862 return ((dev->flags & DF_FIXEDCLASS) != 0);
2876 struct domainset *policy;
2878 if (dev->state >= DS_ATTACHED)
2881 if (dev->driver == driver)
2884 if (dev->softc && !(dev->flags & DF_EXTERNALSOFTC)) {
2885 free(dev->softc, M_BUS_SC);
2890 dev->driver = driver;
2892 kobj_init((kobj_t) dev, (kobj_class_t) driver);
2893 if (!(dev->flags & DF_EXTERNALSOFTC) && driver->size > 0) {
2895 policy = DOMAINSET_PREF(
domain);
2897 policy = DOMAINSET_RR();
2899 policy, M_NOWAIT | M_ZERO);
2949 if (dev->state >= DS_ALIVE)
2952 if (!(dev->flags & DF_ENABLED)) {
2955 printf(
"not probed (disabled)\n");
2961 !(dev->flags & DF_DONENOMATCH)) {
2962 BUS_PROBE_NOMATCH(dev->parent, dev);
2964 dev->flags |= DF_DONENOMATCH;
2986 else if (error != 0)
2989 CURVNET_SET_QUIET(vnet0);
3017 uint64_t attachtime;
3018 uint16_t attachentropy;
3031 attachtime = get_cyclecount();
3032 dev->state = DS_ATTACHING;
3033 if ((error = DEVICE_ATTACH(dev)) != 0) {
3034 printf(
"device_attach: %s%d attach returned %d\n",
3035 dev->driver->name, dev->unit, error);
3036 if (!(dev->flags & DF_FIXEDCLASS))
3040 KASSERT(dev->busy == 0, (
"attach failed but busy"));
3041 dev->state = DS_NOTPRESENT;
3044 dev->flags |= DF_ATTACHED_ONCE;
3048 attachentropy = (uint16_t)(get_cyclecount() - attachtime);
3049 random_harvest_direct(&attachentropy,
sizeof(attachentropy), RANDOM_ATTACH);
3051 dev->state = DS_ATTACHED;
3052 dev->flags &= ~DF_DONENOMATCH;
3084 if (dev->state == DS_ATTACHING) {
3085 device_printf(dev,
"device in attaching state! Deferring detach.\n");
3088 if (dev->state != DS_ATTACHED)
3091 EVENTHANDLER_DIRECT_INVOKE(
device_detach, dev, EVHDEV_DETACH_BEGIN);
3092 if ((error = DEVICE_DETACH(dev)) != 0) {
3094 EVHDEV_DETACH_FAILED);
3098 EVHDEV_DETACH_COMPLETE);
3104 BUS_CHILD_DETACHED(dev->parent, dev);
3106 if (!(dev->flags & DF_FIXEDCLASS))
3110 dev->state = DS_NOTPRESENT;
3136 if (dev->state != DS_ATTACHED)
3139 return (DEVICE_QUIESCE(dev));
3153 if (dev->state < DS_ATTACHED)
3155 return (DEVICE_SHUTDOWN(dev));
3170 if (unit == dev->unit)
3173 if (unit < dc->maxunit && dc->devices[unit])
3197 args->memattr = VM_MEMATTR_DEVICE;
3222 struct resource_list_entry *rle;
3224 while ((rle = STAILQ_FIRST(rl)) != NULL) {
3226 panic(
"resource_list_free: resource entry is busy");
3227 STAILQ_REMOVE_HEAD(rl, link);
3247 rman_res_t end, rman_res_t
count)
3273struct resource_list_entry *
3275 rman_res_t
start, rman_res_t end, rman_res_t
count)
3277 struct resource_list_entry *rle;
3281 rle =
malloc(
sizeof(
struct resource_list_entry), M_BUS,
3284 panic(
"resource_list_add: can't record entry");
3285 STAILQ_INSERT_TAIL(rl, rle, link);
3293 panic(
"resource_list_add: resource entry is busy");
3316 struct resource_list_entry *rle;
3319 if (rle == NULL || rle->res == NULL)
3321 if ((rle->flags & (RLE_RESERVED | RLE_ALLOCATED)) == RLE_RESERVED) {
3323 (
"reserved resource is active"));
3345 struct resource_list_entry *rle;
3348 if (rle != NULL && rle->flags & RLE_RESERVED)
3363struct resource_list_entry *
3366 struct resource_list_entry *rle;
3368 STAILQ_FOREACH(rle, rl, link) {
3369 if (rle->type ==
type && rle->rid == rid)
3388 if (rle->res != NULL)
3389 panic(
"resource_list_delete: resource has not been released");
3390 STAILQ_REMOVE(rl, rle, resource_list_entry, link);
3435 struct resource_list_entry *rle = NULL;
3441 "resource_list_reserve() should only be called for direct children");
3442 if (
flags & RF_ACTIVE)
3444 "resource_list_reserve() should only reserve inactive resources");
3450 rle->flags |= RLE_RESERVED;
3492 struct resource_list_entry *rle = NULL;
3494 int isdefault = RMAN_IS_DEFAULT_RANGE(
start, end);
3507 if (rle->flags & RLE_RESERVED) {
3508 if (rle->flags & RLE_ALLOCATED)
3510 if ((
flags & RF_ACTIVE) &&
3514 rle->flags |= RLE_ALLOCATED;
3518 "resource entry %#x type %d for child %s is busy\n", *rid,
3563 int type,
int rid,
struct resource *
res)
3565 struct resource_list_entry *rle = NULL;
3577 panic(
"resource_list_release: can't find resource");
3579 panic(
"resource_list_release: resource entry is not busy");
3580 if (rle->flags & RLE_RESERVED) {
3581 if (rle->flags & RLE_ALLOCATED) {
3588 rle->flags &= ~RLE_ALLOCATED;
3622 struct resource_list_entry *rle;
3626 STAILQ_FOREACH(rle, rl, link) {
3627 if (rle->type !=
type)
3629 if (rle->res == NULL)
3631 if ((rle->flags & (RLE_RESERVED | RLE_ALLOCATED)) ==
3639 "Failed to release active resource: %d\n", error);
3664 struct resource_list_entry *rle = NULL;
3669 "resource_list_unreserve() should only be called for direct children");
3674 panic(
"resource_list_unreserve: can't find resource");
3675 if (!(rle->flags & RLE_RESERVED))
3677 if (rle->flags & RLE_ALLOCATED)
3679 rle->flags &= ~RLE_RESERVED;
3702 struct resource_list_entry *rle;
3703 int printed, retval;
3708 STAILQ_FOREACH(rle, rl, link) {
3709 if (rle->type ==
type) {
3715 retval +=
printf(format, rle->start);
3716 if (rle->count > 1) {
3718 retval +=
printf(format, rle->start +
3736 struct resource_list_entry *rle;
3738 while ((rle = STAILQ_FIRST(rl)) != NULL) {
3741 rle->type, rle->rid, rle->res);
3742 STAILQ_REMOVE_HEAD(rl, link);
3764 devclass_t dc = dev->devclass;
3767 TAILQ_FOREACH(dl, &dc->drivers, link) {
3779 DEVICE_IDENTIFY(dl->
driver, dev);
3797 TAILQ_FOREACH(
child, &dev->children, link) {
3833 if (dev->state != DS_ATTACHED)
3840 TAILQ_FOREACH_REVERSE(
child, &dev->children, device_list, link) {
3864 TAILQ_FOREACH_REVERSE(
child, &dev->children, device_list, link) {
3881 error = DEVICE_SUSPEND(
child);
3884 child->flags |= DF_SUSPENDED;
3897 DEVICE_RESUME(
child);
3898 child->flags &= ~DF_SUSPENDED;
3925 TAILQ_FOREACH_REVERSE(
child, &dev->children, device_list, link) {
3926 error = BUS_SUSPEND_CHILD(dev,
child);
3929 if (
child != NULL) {
3930 TAILQ_FOREACH_FROM(
child, &dev->children, link)
3931 BUS_RESUME_CHILD(dev,
child);
3950 TAILQ_FOREACH(
child, &dev->children, link) {
3951 BUS_RESUME_CHILD(dev,
child);
3974 TAILQ_FOREACH(
child, &dev->children,link) {
3975 BUS_RESET_POST(dev,
child);
3976 error1 = (
flags & DEVF_RESET_DETACH) != 0 ?
3978 BUS_RESUME_CHILD(dev,
child);
3979 if (error == 0 && error1 != 0)
3991 TAILQ_FOREACH_FROM(
child, &dev->children,link) {
3992 BUS_RESET_POST(dev,
child);
3993 if ((
flags & DEVF_RESET_DETACH) != 0)
3996 BUS_RESUME_CHILD(dev,
child);
4017 if (dev->state != DS_ATTACHED)
4020 TAILQ_FOREACH_REVERSE(
child, &dev->children, device_list, link) {
4021 if ((
flags & DEVF_RESET_DETACH) != 0) {
4025 error = BUS_SUSPEND_CHILD(dev,
child);
4028 error = BUS_RESET_PREPARE(dev,
child);
4030 if ((
flags & DEVF_RESET_DETACH) != 0)
4033 BUS_RESUME_CHILD(dev,
child);
4153 void *propvalue,
size_t size, device_property_type_t
type)
4157 propname, propvalue, size,
type));
4167struct resource_list *
4185 DEVICE_IDENTIFY(driver, dev);
4186 TAILQ_FOREACH(
child, &dev->children, link) {
4187 if (
child->state == DS_NOTPRESENT)
4210 TAILQ_FOREACH(dl, &dc->drivers, link) {
4212 DEVICE_IDENTIFY(dl->
driver, dev);
4214 TAILQ_FOREACH(
child, &dev->children, link) {
4215 if (
child->state >= DS_ATTACHED)
4216 BUS_NEW_PASS(
child);
4217 else if (
child->state == DS_NOTPRESENT)
4230 int flags, driver_filter_t *filter, driver_intr_t *intr,
void *arg,
4235 return (BUS_SETUP_INTR(dev->parent,
child, irq,
flags,
4236 filter, intr, arg, cookiep));
4252 return (BUS_TEARDOWN_INTR(dev->parent,
child, irq, cookie));
4267 return (BUS_SUSPEND_INTR(dev->parent,
child, irq));
4282 return (BUS_RESUME_INTR(dev->parent,
child, irq));
4294 struct resource *r, rman_res_t
start, rman_res_t end)
4312 rman_res_t *newstart)
4315 return (BUS_TRANSLATE_RESOURCE(dev->parent,
type,
start,
4333 return (BUS_ALLOC_RESOURCE(dev->parent,
child,
type, rid,
4350 return (BUS_RELEASE_RESOURCE(dev->parent,
child,
type, rid,
4367 return (BUS_ACTIVATE_RESOURCE(dev->parent,
child,
type, rid,
4380 int rid,
struct resource *r)
4384 return (BUS_DEACTIVATE_RESOURCE(dev->parent,
child,
type, rid,
4397 struct resource *r,
struct resource_map_request *args,
4398 struct resource_map *map)
4402 return (BUS_MAP_RESOURCE(dev->parent,
child,
type, r, args,
4415 struct resource *r,
struct resource_map *map)
4419 return (BUS_UNMAP_RESOURCE(dev->parent,
child,
type, r, map));
4435 return (BUS_BIND_INTR(dev->parent,
child, irq, cpu));
4447 enum intr_polarity pol)
4451 return (BUS_CONFIG_INTR(dev->parent, irq, trig, pol));
4463 void *cookie,
const char *descr)
4467 return (BUS_DESCRIBE_INTR(dev->parent,
child, irq, cookie,
4480 size_t setsize, cpuset_t *cpuset)
4483 if (dev->parent != NULL)
4484 return (BUS_GET_CPUS(dev->parent,
child, op, setsize, cpuset));
4498 if (dev->parent != NULL)
4499 return (BUS_GET_DMA_TAG(dev->parent,
child));
4513 if (dev->parent != NULL)
4514 return (BUS_GET_BUS_TAG(dev->parent,
child));
4515 return ((bus_space_tag_t)0);
4528 rman_res_t *startp, rman_res_t *countp)
4530 struct resource_list * rl = NULL;
4531 struct resource_list_entry * rle = NULL;
4533 rl = BUS_GET_RESOURCE_LIST(dev,
child);
4542 *startp = rle->start;
4544 *countp = rle->count;
4561 struct resource_list * rl = NULL;
4563 rl = BUS_GET_RESOURCE_LIST(dev,
child);
4583 struct resource_list * rl = NULL;
4585 rl = BUS_GET_RESOURCE_LIST(dev,
child);
4603 int rid,
struct resource *r)
4605 struct resource_list * rl = NULL;
4611 rl = BUS_GET_RESOURCE_LIST(dev,
child);
4627 int *rid, rman_res_t
start, rman_res_t end, rman_res_t
count, u_int
flags)
4629 struct resource_list * rl = NULL;
4635 rl = BUS_GET_RESOURCE_LIST(dev,
child);
4659 return (BUS_GET_DOMAIN(dev->parent, dev,
domain));
4692 if (
parent != NULL && strcmp(locator, BUS_LOCATOR_ACPI) != 0) {
4693 rv = BUS_GET_DEVICE_PATH(
parent,
bus, locator, sb);
4695 if (strcmp(locator, BUS_LOCATOR_FREEBSD) == 0) {
4731 struct resource **
res)
4735 for (i = 0; rs[i].type != -1; i++)
4737 for (i = 0; rs[i].type != -1; i++) {
4738 res[i] = bus_alloc_resource_any(dev,
4740 if (
res[i] == NULL && !(rs[i].
flags & RF_OPTIONAL)) {
4750 struct resource **
res)
4754 for (i = 0; rs[i].type != -1; i++)
4755 if (
res[i] != NULL) {
4757 dev, rs[i].
type, rs[i].rid,
res[i]);
4770 rman_res_t end, rman_res_t
count, u_int
flags)
4772 struct resource *
res;
4774 if (dev->parent == NULL)
4776 res = BUS_ALLOC_RESOURCE(dev->parent, dev,
type, rid,
start, end,
4791 if (dev->parent == NULL)
4793 return (BUS_ADJUST_RESOURCE(dev->parent, dev,
type, r,
start, end));
4804 rman_res_t *newstart)
4806 if (dev->parent == NULL)
4808 return (BUS_TRANSLATE_RESOURCE(dev->parent,
type,
start, newstart));
4820 if (dev->parent == NULL)
4822 return (BUS_ACTIVATE_RESOURCE(dev->parent, dev,
type, rid, r));
4834 if (dev->parent == NULL)
4836 return (BUS_DEACTIVATE_RESOURCE(dev->parent, dev,
type, rid, r));
4847 struct resource_map_request *args,
struct resource_map *map)
4849 if (dev->parent == NULL)
4851 return (BUS_MAP_RESOURCE(dev->parent, dev,
type, r, args, map));
4862 struct resource_map *map)
4864 if (dev->parent == NULL)
4866 return (BUS_UNMAP_RESOURCE(dev->parent, dev,
type, r, map));
4880 if (dev->parent == NULL)
4882 rv = BUS_RELEASE_RESOURCE(dev->parent, dev,
type, rid, r);
4894 driver_filter_t filter, driver_intr_t handler,
void *arg,
void **cookiep)
4898 if (dev->parent == NULL)
4900 error = BUS_SETUP_INTR(dev->parent, dev, r,
flags, filter, handler,
4904 if (handler != NULL && !(
flags & INTR_MPSAFE))
4918 if (dev->parent == NULL)
4920 return (BUS_TEARDOWN_INTR(dev->parent, dev, r, cookie));
4932 if (dev->parent == NULL)
4934 return (BUS_SUSPEND_INTR(dev->parent, dev, r));
4946 if (dev->parent == NULL)
4948 return (BUS_RESUME_INTR(dev->parent, dev, r));
4960 if (dev->parent == NULL)
4962 return (BUS_BIND_INTR(dev->parent, dev, r, cpu));
4974 const char *fmt, ...)
4977 char descr[MAXCOMLEN + 1];
4979 if (dev->parent == NULL)
4982 vsnprintf(descr,
sizeof(descr), fmt, ap);
4984 return (BUS_DESCRIBE_INTR(dev->parent, dev, irq, cookie, descr));
5009 rman_res_t *startp, rman_res_t *countp)
5144bus_get_cpus(device_t dev,
enum cpu_sets op,
size_t setsize, cpuset_t *cpuset)
5151 return (BUS_GET_CPUS(
parent, dev, op, setsize, cpuset));
5168 return (BUS_GET_DMA_TAG(
parent, dev));
5184 return ((bus_space_tag_t)0);
5185 return (BUS_GET_BUS_TAG(
parent, dev));
5227 driver_filter_t *filter, driver_intr_t *intr,
void *arg,
void **cookiep)
5232 panic(
"root_setup_intr");
5255 if (setsize !=
sizeof(cpuset_t))
5298 root_bus->desc =
"System root bus";
5310 return (EOPNOTSUPP);
5349 struct driver_module_data *dmd;
5350 devclass_t bus_devclass;
5351 kobj_class_t driver;
5354 dmd = (
struct driver_module_data *)arg;
5360 if (dmd->dmd_chainevh)
5361 error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg);
5363 pass = dmd->dmd_pass;
5364 driver = dmd->dmd_driver;
5365 PDEBUG((
"Loading module: driver %s on bus %s (pass %d)",
5366 DRIVERNAME(driver), dmd->dmd_busname, pass));
5372 PDEBUG((
"Unloading module: driver %s from bus %s",
5378 if (!error && dmd->dmd_chainevh)
5379 error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg);
5382 PDEBUG((
"Quiesce module: driver %s from bus %s",
5388 if (!error && dmd->dmd_chainevh)
5389 error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg);
5413 const char *dname, *busname;
5422 BUS_HINTED_CHILD(
bus, dname, dunit);
5430 BUS_HINTED_CHILD(
bus, dname, dunit);
5445 indentprintf((
"device %d: <%s> %sparent,%schildren,%s%s%s%s%s,%sivars,%ssoftc,busy=%d\n",
5446 dev->unit, dev->desc,
5447 (dev->parent?
"":
"no "),
5448 (TAILQ_EMPTY(&dev->children)?
"no ":
""),
5449 (dev->flags&DF_ENABLED?
"enabled,":
"disabled,"),
5450 (dev->flags&DF_FIXEDCLASS?
"fixed,":
""),
5451 (dev->flags&DF_WILDCARD?
"wildcard,":
""),
5452 (dev->flags&DF_DESCMALLOCED?
"descmalloced,":
""),
5453 (dev->flags&DF_SUSPENDED?
"suspended,":
""),
5454 (dev->ivars?
"":
"no "),
5455 (dev->softc?
"":
"no "),
5467 indentprintf((
"Parent:\n"));
5469 indentprintf((
"Driver:\n"));
5471 indentprintf((
"Devclass:\n"));
5486 TAILQ_FOREACH(
child, &dev->children, link) {
5502 TAILQ_FOREACH(
child, &dev->children, link) {
5513 indentprintf((
"driver %s: softc size = %zd\n",
5514 driver->name, driver->size));
5531 TAILQ_FOREACH(driver, &drivers, link) {
5542 indentprintf((
"devclass %s: max units = %d\n", dc->name, dc->maxunit));
5554 indentprintf((
"Drivers:\n"));
5557 indentprintf((
"Devices:\n"));
5558 for (i = 0; i < dc->maxunit; i++)
5568 printf(
"Short listing of devclasses, drivers & devices:\n");
5579 printf(
"Full listing of devclasses, drivers & devices:\n");
5604 struct u_businfo ubus;
5606 ubus.ub_version = BUS_USER_VERSION;
5609 return (SYSCTL_OUT(req, &ubus,
sizeof(ubus)));
5613 "bus-related data");
5619 int *
name = (
int *)arg1;
5620 u_int namelen = arg2;
5623 struct u_device *udev;
5647 udev =
malloc(
sizeof(*udev), M_BUS, M_WAITOK | M_ZERO);
5650 udev->dv_handle = (uintptr_t)dev;
5651 udev->dv_parent = (uintptr_t)dev->parent;
5652 udev->dv_devflags = dev->devflags;
5653 udev->dv_flags = dev->flags;
5654 udev->dv_state = dev->state;
5655 sbuf_new(&sb, udev->dv_fields,
sizeof(udev->dv_fields), SBUF_FIXEDLEN);
5656 if (dev->nameunit != NULL)
5659 if (dev->desc != NULL)
5662 if (dev->driver != NULL)
5671 error = SYSCTL_OUT(req, udev,
sizeof(*udev));
5679 "system device tree");
5711 if (dev->nameunit != NULL && strcmp(dev->nameunit,
name) == 0)
5730 if (memchr(req->dr_name,
'\0',
sizeof(req->dr_name)) == NULL)
5745 EVENTHANDLER_DIRECT_INVOKE(dev_lookup, req->dr_name, &dev);
5757 for (dc =
bus->devclass; dc != NULL; dc = dc->parent) {
5769 if (dev->flags & DF_NEEDNOMATCH &&
5770 dev->state == DS_NOTPRESENT) {
5771 BUS_PROBE_NOMATCH(dev->parent, dev);
5773 dev->flags |= DF_DONENOMATCH;
5775 dev->flags &= ~DF_NEEDNOMATCH;
5776 TAILQ_FOREACH(
child, &dev->children, link) {
5795 TAILQ_FOREACH(dl, &dc->drivers, link) {
5798 dl->flags &= ~DL_DEFERRED_PROBE;
5819 sb =
sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND | SBUF_INCLUDENUL);
5827 rv =
malloc(len, M_BUS, M_NOWAIT);
5844 req = (
struct devreq *)
data;
5852 case DEV_SET_DRIVER:
5853 case DEV_CLEAR_DRIVER:
5892 if (!(req->dr_flags & DEVF_FORCE_DETACH)) {
5918 dev->unit,
"disabled");
5929 if (!(req->dr_flags & DEVF_FORCE_DETACH)) {
5940 dev->flags |= DF_FIXEDCLASS;
5942 if (!(old & DF_FIXEDCLASS))
5943 dev->flags &= ~DF_FIXEDCLASS;
5969 case DEV_SET_DRIVER: {
5973 error = copyinstr(req->dr_data, driver,
sizeof(driver), NULL);
5976 if (driver[0] ==
'\0') {
5980 if (dev->devclass != NULL &&
5981 strcmp(driver, dev->devclass->name) == 0)
5989 if (dev->parent == NULL) {
6005 if (req->dr_flags & DEVF_SET_DRIVER_DETACH)
6014 if (dev->flags & DF_FIXEDCLASS)
6016 dev->flags |= DF_WILDCARD;
6023 dev->flags |= DF_FIXEDCLASS;
6027 case DEV_CLEAR_DRIVER:
6028 if (!(dev->flags & DF_FIXEDCLASS)) {
6033 if (req->dr_flags & DEVF_CLEAR_DRIVER_DETACH)
6041 dev->flags &= ~DF_FIXEDCLASS;
6042 dev->flags |= DF_WILDCARD;
6051 error = BUS_RESCAN(dev);
6061 if (!(req->dr_flags & DEVF_FORCE_DELETE)) {
6086 if ((req->dr_flags & ~(DEVF_RESET_DETACH)) != 0) {
6093 case DEV_GET_PATH: {
6098 error = copyinstr(req->dr_buffer.buffer, locator,
sizeof(locator), NULL);
6106 len = strlen(
path) + 1;
6107 if (req->dr_buffer.length < len) {
6108 error = ENAMETOOLONG;
6110 error = copyout(
path, req->dr_buffer.buffer, len);
6112 req->dr_buffer.length = len;
6122 .d_version = D_VERSION,
6124 .d_name =
"devctl2",
6131 UID_ROOT, GID_WHEEL, 0644,
"devctl2");
6144struct device_location_cache {
6145 device_location_list_t dlc_list;
6152device_location_cache_t *
6155 device_location_cache_t *dcp;
6157 dcp =
malloc(
sizeof(*dcp), M_BUS, M_WAITOK | M_ZERO);
6158 TAILQ_INIT(&dcp->dlc_list);
6168 TAILQ_FOREACH_SAFE(dln, &dcp->dlc_list, dln_link, tdln) {
6181 TAILQ_FOREACH(dln, &dcp->dlc_list, dln_link) {
6195 dln =
malloc(
sizeof(*dln) + strlen(locator) + 1, M_BUS, M_WAITOK | M_ZERO);
6197 memcpy(l, locator, strlen(locator) + 1);
6199 TAILQ_INSERT_HEAD(&dcp->dlc_list, dln, dln_link);
6207 const char *cp, *
path;
6212 cp = strchr(at,
':');
6216 if (len >
sizeof(locator) - 1)
6218 memcpy(locator, at, len);
6219 locator[len] =
'\0';
6228 if (
res == NULL ||
res->dln_path == NULL)
6231 return (strcmp(
res->dln_path, cp) == 0);
6239 "Panic when obsolete features are used (0 = never, 1 = if obsolete, "
6240 "2 = if deprecated)");
6250 if (running < major)
6261 gone_panic(major, P_OSREL_MAJOR(__FreeBSD_version), msg);
6262 if (P_OSREL_MAJOR(__FreeBSD_version) >= major)
6263 printf(
"Obsolete code will be removed soon: %s\n", msg);
6265 printf(
"Deprecated code (to be removed in FreeBSD %d): %s\n",
6272 gone_panic(major, P_OSREL_MAJOR(__FreeBSD_version), msg);
6273 if (P_OSREL_MAJOR(__FreeBSD_version) >= major)
6275 "Obsolete code will be removed soon: %s\n", msg);
6278 "Deprecated code (to be removed in FreeBSD %d): %s\n",
6283DB_SHOW_COMMAND(
device, db_show_device)
6290 dev = (device_t)
addr;
6293 db_printf(
" driver: %s\n",
DRIVERNAME(dev->driver));
6294 db_printf(
" class: %s\n",
DEVCLANAME(dev->devclass));
6295 db_printf(
" addr: %p\n", dev);
6296 db_printf(
" parent: %p\n", dev->parent);
6297 db_printf(
" softc: %p\n", dev->softc);
6298 db_printf(
" ivars: %p\n", dev->ivars);
6301DB_SHOW_ALL_COMMAND(devices, db_show_all_devices)
6306 db_show_device((db_expr_t)dev,
true,
count, modif);
device_property_type_t type
void cv_init(struct cv *cvp, const char *desc)
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,...)
int fsetown(pid_t pgid, struct sigio **sigiop)
void funsetown(struct sigio **sigiop)
pid_t fgetown(struct sigio **sigiop)
void knlist_remove(struct knlist *knl, struct knote *kn, int islocked)
void knlist_add(struct knlist *knl, struct knote *kn, int islocked)
void knote(struct knlist *list, long hint, int lockflags)
void knlist_init_mtx(struct knlist *knl, struct mtx *lock)
void *() malloc(size_t size, struct malloc_type *mtp, int flags)
void * malloc_domainset(size_t size, struct malloc_type *mtp, struct domainset *ds, int flags)
void free(void *addr, struct malloc_type *mtp)
struct mtx __exclusive_cache_line Giant
int priv_check(struct thread *td, int priv)
void panic(const char *fmt,...)
void pgsigio(struct sigio **sigiop, int sig, int checkctty)
int sysctl_ctx_free(struct sysctl_ctx_list *clist)
void sysctl_rename_oid(struct sysctl_oid *oidp, const char *name)
int sysctl_handle_int(SYSCTL_HANDLER_ARGS)
int sysctl_ctx_init(struct sysctl_ctx_list *c)
struct sbuf * sbuf_new_for_sysctl(struct sbuf *s, char *buf, int length, struct sysctl_req *req)
struct iommu_domain ** domain
struct intr_irqsrc ** src
Implementation of _device.
void config_intrhook_oneshot(ich_func_t func, void *arg)
static void bus_helper_reset_prepare_rollback(device_t dev, device_t child, int flags)
static driverlink_t next_matching_driver(devclass_t dc, device_t dev, driverlink_t last)
int bus_translate_resource(device_t dev, int type, rman_res_t start, rman_res_t *newstart)
Wrapper function for BUS_TRANSLATE_RESOURCE().
static void devctl_queue(struct dev_event_info *dei)
void device_set_ivars(device_t dev, void *ivars)
Set the device's ivars field.
struct resource_list_entry * resource_list_add(struct resource_list *rl, int type, int rid, rman_res_t start, rman_res_t end, rman_res_t count)
Add or modify a resource entry.
bus_dma_tag_t bus_get_dma_tag(device_t dev)
Wrapper function for BUS_GET_DMA_TAG().
static devclass_list_t devclasses
struct resource_list * bus_generic_get_resource_list(device_t dev, device_t child)
Stub function for implementing BUS_GET_RESOURCE_LIST().
#define print_driver_short(d, i)
void bus_generic_driver_added(device_t dev, driver_t *driver)
Helper function for implementing BUS_DRIVER_ADDED().
int bus_deactivate_resource(device_t dev, int type, int rid, struct resource *r)
Wrapper function for BUS_DEACTIVATE_RESOURCE().
int bus_alloc_resources(device_t dev, struct resource_spec *rs, struct resource **res)
static driver_list_t passes
int bus_generic_translate_resource(device_t dev, int type, rman_res_t start, rman_res_t *newstart)
#define print_device_tree_short(d, i)
static void driver_register_pass(struct driverlink *new)
Register the pass level of a new driver attachment.
int devclass_get_devices(devclass_t dc, device_t **devlistp, int *devcountp)
Get a list of devices in the devclass.
device_t devclass_get_device(devclass_t dc, int unit)
Find a device given a unit number.
int devclass_get_drivers(devclass_t dc, driver_t ***listp, int *countp)
Get a list of drivers in the devclass.
static int bus_data_generation
int device_is_enabled(device_t dev)
Return non-zero if the DF_ENABLED flag is set on the device.
static int root_resume(device_t dev)
int bus_generic_child_location(device_t dev, device_t child, struct sbuf *sb)
Generic implementation that does nothing for bus_child_location.
int device_is_suspended(device_t dev)
Return non-zero if the device is currently suspended.
const char * device_get_desc(device_t dev)
Return the device's description string.
int bus_suspend_intr(device_t dev, struct resource *r)
Wrapper function for BUS_SUSPEND_INTR().
int device_delete_children(device_t dev)
Delete all children devices of the given device, if any.
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().
static void device_sysctl_update(device_t dev)
void devctl_notify(const char *system, const char *subsystem, const char *type, const char *data)
Send a 'notification' to userland, using standard ways.
int device_set_devclass_fixed(device_t dev, const char *classname)
Set the devclass of a device and mark the devclass fixed.
int bus_generic_resume(device_t dev)
Helper function for implementing DEVICE_RESUME()
device_location_cache_t * dev_wired_cache_init(void)
static void devclass_driver_added(devclass_t dc, driver_t *driver)
Register that a device driver has been added to a devclass.
static struct dev_event_info * devctl_alloc_dei(void)
int device_set_driver(device_t dev, driver_t *driver)
Set the driver of a device.
device_state_t device_get_state(device_t dev)
Return the device's state.
static char * device_get_path(device_t dev, const char *locator)
int device_get_children(device_t dev, device_t **devlistp, int *devcountp)
Get a list of children of a device.
int bus_generic_get_cpus(device_t dev, device_t child, enum cpu_sets op, size_t setsize, cpuset_t *cpuset)
Helper function for implementing BUS_GET_CPUS().
int device_probe(device_t dev)
Probe a device, and return this status.
void device_quiet_children(device_t dev)
Set the DF_QUIET_CHILDREN flag for the device.
struct resource_list_entry * resource_list_find(struct resource_list *rl, int type, int rid)
Find a resource entry by type and rid.
SYSCTL_NODE(_hw, OID_AUTO, bus, CTLFLAG_RW|CTLFLAG_MPSAFE, NULL, NULL)
static driver_t root_driver
ssize_t device_get_property(device_t dev, const char *prop, void *val, size_t sz, device_property_type_t type)
static bool device_frozen
int device_detach(device_t dev)
Detach a driver from a device.
int bus_generic_suspend(device_t dev)
Helper function for implementing DEVICE_SUSPEND()
static void devremoved(device_t dev)
static int root_get_cpus(device_t dev, device_t child, enum cpu_sets op, size_t setsize, cpuset_t *cpuset)
void bus_data_generation_update(void)
static int device_sysctl_handler(SYSCTL_HANDLER_ARGS)
#define print_devclass_list_short()
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 bus_generic_get_device_path(device_t bus, device_t child, const char *locator, struct sbuf *sb)
Helper function to implement normal BUS_GET_DEVICE_PATH()
static int devclass_sysctl_handler(SYSCTL_HANDLER_ARGS)
void bus_delete_resource(device_t dev, int type, int rid)
Wrapper function for BUS_DELETE_RESOURCE().
static void device_do_deferred_actions(void)
DEFINE_CLASS(null, null_methods, 0)
int devclass_get_maxunit(devclass_t dc)
Get the maximum unit number used in a devclass.
int bus_child_pnpinfo(device_t child, struct sbuf *sb)
Wrapper function for BUS_CHILD_PNPINFO().
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().
EVENTHANDLER_LIST_DEFINE(device_attach)
bus_space_tag_t bus_generic_get_bus_tag(device_t dev, device_t child)
Helper function for implementing BUS_GET_BUS_TAG().
int bus_child_location(device_t child, struct sbuf *sb)
Wrapper function for BUS_CHILD_LOCATION().
void resource_init_map_request_impl(struct resource_map_request *args, size_t sz)
static int filt_devctl_read(struct knote *kn, long hint)
int devclass_get_count(devclass_t dc)
Get the number of devices in a devclass.
static struct device_location_node * dev_wired_cache_lookup(device_location_cache_t *dcp, const char *locator)
#define DL_DEFERRED_PROBE
void bus_topo_unlock(void)
static int devctl2_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag, struct thread *td)
int device_is_attached(device_t dev)
Return non-zero if the device currently has a driver attached to it.
int bus_set_resource(device_t dev, int type, int rid, rman_res_t start, rman_res_t count)
Wrapper function for BUS_SET_RESOURCE().
void devclass_set_parent(devclass_t dc, devclass_t pdc)
Set the parent of a devclass.
int bus_activate_resource(device_t dev, int type, int rid, struct resource *r)
Wrapper function for BUS_ACTIVATE_RESOURCE().
void device_set_softc(device_t dev, void *softc)
Set the device's softc field.
static void device_set_desc_internal(device_t dev, const char *desc, int copy)
STAILQ_HEAD(devq, dev_event_info)
devclass_t device_get_devclass(device_t dev)
Return the current devclass for the device or NULL if there is none.
void resource_list_purge(struct resource_list *rl)
Releases all the resources in a list.
void root_bus_configure(void)
Automatically configure devices.
int bus_unmap_resource(device_t dev, int type, struct resource *r, struct resource_map *map)
Wrapper function for BUS_UNMAP_RESOURCE().
static struct dev_event_info * devctl_alloc_dei_sb(struct sbuf *sb)
int bus_print_child_domain(device_t dev, device_t child)
Helper function for implementing BUS_PRINT_CHILD().
int driver_module_handler(module_t mod, int what, void *arg)
Module handler for registering device drivers.
void device_verbose(device_t dev)
Clear the DF_QUIET flag for the device.
void _gone_in(int major, const char *msg)
void device_quiet(device_t dev)
Set the DF_QUIET flag for the device.
SYSCTL_INT(_debug, OID_AUTO, obsolete_panic, CTLFLAG_RWTUN, &obsolete_panic, 0, "Panic when obsolete features are used (0 = never, 1 = if obsolete, " "2 = if deprecated)")
int resource_list_release_active(struct resource_list *rl, device_t bus, device_t child, int type)
Release all active resources of a given type.
int device_probe_child(device_t dev, device_t child)
void device_set_desc_copy(device_t dev, const char *desc)
Set the device's description.
static int root_bus_module_handler(module_t mod, int what, void *arg)
void resource_list_init(struct resource_list *rl)
Initialise a resource list.
int resource_list_busy(struct resource_list *rl, int type, int rid)
Determine if a resource entry is busy.
int bus_get_resource(device_t dev, int type, int rid, rman_res_t *startp, rman_res_t *countp)
Wrapper function for BUS_GET_RESOURCE().
int bus_helper_reset_post(device_t dev, int flags)
Helper function for implementing BUS_RESET_POST.
struct sysctl_oid * device_get_sysctl_tree(device_t dev)
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...
static struct cdev * devctl_dev
static struct cdevsw devctl2_cdevsw
int bus_generic_suspend_child(device_t dev, device_t child)
Default function for suspending a child device.
device_t device_add_child_ordered(device_t dev, u_int order, const char *name, int unit)
Create a new device.
bus_dma_tag_t bus_generic_get_dma_tag(device_t dev, device_t child)
Helper function for implementing BUS_GET_DMA_TAG().
int bus_bind_intr(device_t dev, struct resource *r, int cpu)
Wrapper function for BUS_BIND_INTR().
int device_set_devclass(device_t dev, const char *classname)
Set the devclass of a device.
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().
void device_enable(device_t dev)
Set the DF_ENABLED flag for the device.
bus_space_tag_t bus_get_bus_tag(device_t dev)
Wrapper function for BUS_GET_BUS_TAG().
SYSCTL_ROOT_NODE(OID_AUTO, dev, CTLFLAG_RW|CTLFLAG_MPSAFE, NULL, NULL)
int bus_generic_suspend_intr(device_t dev, device_t child, struct resource *irq)
Helper function for implementing BUS_SUSPEND_INTR().
int bus_adjust_resource(device_t dev, int type, struct resource *r, rman_res_t start, rman_res_t end)
Wrapper function for BUS_ADJUST_RESOURCE().
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().
static int find_device(struct devreq *req, device_t *devp)
int bus_print_child_header(device_t dev, device_t child)
Helper function for implementing BUS_PRINT_CHILD().
int resource_list_reserved(struct resource_list *rl, int type, int rid)
Determine if a resource entry is reserved.
static void device_sysctl_init(device_t dev)
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.
int device_has_quiet_children(device_t dev)
Return non-zero if the DF_QUIET_CHIDLREN flag is set on the device.
int bus_resume_intr(device_t dev, struct resource *r)
Wrapper function for BUS_RESUME_INTR().
devclass_t devclass_get_parent(devclass_t dc)
Get the parent of a devclass.
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_resume_intr(device_t dev, device_t child, struct resource *irq)
Helper function for implementing BUS_RESUME_INTR().
SYSCTL_PROC(_hw_bus, OID_AUTO, devctl_queue, CTLTYPE_INT|CTLFLAG_RWTUN|CTLFLAG_MPSAFE, NULL, 0, sysctl_devctl_queue, "I", "devctl queue length")
int bus_child_present(device_t child)
Wrapper function for BUS_CHILD_PRESENT().
static void gone_panic(int major, int running, const char *msg)
device_t device_get_parent(device_t dev)
Return the parent of a device.
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.
static void devctl2_init(void)
static driverlink_t devclass_find_driver_internal(devclass_t dc, const char *classname)
static moduledata_t root_bus_mod
struct driverlink * driverlink_t
#define print_device(d, i)
struct resource * resource_list_reserve(struct resource_list *rl, device_t bus, device_t child, int type, int *rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
Allocate a reserved resource.
bool devctl_process_running(void)
Return whether the userland process is running.
void bus_generic_new_pass(device_t dev)
Helper function for implementing BUS_NEW_PASS().
device_t bus_generic_add_child(device_t dev, u_int order, const char *name, int unit)
static struct cdevsw dev_cdevsw
int bus_generic_attach(device_t dev)
Helper function for implementing DEVICE_ATTACH()
static void devnomatch(device_t dev)
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)
int bus_map_resource(device_t dev, int type, struct resource *r, struct resource_map_request *args, struct resource_map *map)
Wrapper function for BUS_MAP_RESOURCE().
void device_set_desc(device_t dev, const char *desc)
Set the device's description.
static d_ioctl_t devioctl
static void devclass_sysctl_init(devclass_t dc)
void bus_enumerate_hinted_children(device_t bus)
Enumerate all hinted devices for this bus.
bool dev_wired_cache_match(device_location_cache_t *dcp, device_t dev, const char *at)
int device_get_unit(device_t dev)
Return the device's unit number.
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().
static int sysctl_bus_info(SYSCTL_HANDLER_ARGS)
static bool driver_exists(device_t bus, const char *driver)
static int root_print_child(device_t dev, device_t child)
struct sysctl_oid * devclass_get_sysctl_tree(devclass_t dc)
rman_res_t bus_get_resource_start(device_t dev, int type, int rid)
Wrapper function for BUS_GET_RESOURCE().
int bus_null_rescan(device_t dev)
Helper function for implementing BUS_RESCAN().
int bus_teardown_intr(device_t dev, struct resource *r, void *cookie)
Wrapper function for BUS_TEARDOWN_INTR().
static void devinit(void)
#define print_driver_list(d, i)
static void devctl_free_dei(struct dev_event_info *dei)
void bus_generic_rl_delete_resource(device_t dev, device_t child, int type, int rid)
Helper function for implementing BUS_DELETE_RESOURCE().
#define print_devclass_short(d, i)
device_t device_find_child(device_t dev, const char *classname, int unit)
Find a device given a unit number.
int bus_generic_get_domain(device_t dev, device_t child, int *domain)
void device_set_flags(device_t dev, uint32_t flags)
Set the device's flags.
ssize_t bus_generic_get_property(device_t dev, device_t child, const char *propname, void *propvalue, size_t size, device_property_type_t type)
Helper function for implementing BUS_GET_PROPERTY().
device_t device_add_child(device_t dev, const char *name, int unit)
Create a new device.
void device_unbusy(device_t dev)
Decrement the busy counter for the device.
void device_claim_softc(device_t dev)
Claim softc.
int bus_get_domain(device_t dev, int *domain)
Wrapper function for BUS_GET_DOMAIN().
#define print_devclass(d, i)
int devclass_add_driver(devclass_t dc, driver_t *driver, int pass, devclass_t *dcp)
Add a device driver to a device class.
int bus_describe_intr(device_t dev, struct resource *irq, void *cookie, const char *fmt,...)
Wrapper function for BUS_DESCRIBE_INTR().
void resource_list_free(struct resource_list *rl)
Reclaim memory used by a resource list.
int bus_generic_rl_set_resource(device_t dev, device_t child, int type, int rid, rman_res_t start, rman_res_t count)
Helper function for implementing BUS_SET_RESOURCE().
int bus_delayed_attach_children(device_t dev)
Helper function for delaying attaching children.
static d_kqfilter_t devkqfilter
#define print_device_short(d, i)
static MALLOC_DEFINE(M_BUS, "bus", "Bus data structures")
void device_busy(device_t dev)
Increment the busy counter for the device.
#define DEVCTL_DEFAULT_QUEUE_LEN
int device_delete_child(device_t dev, device_t child)
Delete a device.
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().
static d_close_t devclose
bool device_is_devclass_fixed(device_t dev)
Query the device to determine if it's of a fixed devclass.
static struct dev_softc devsoftc
int device_log(device_t dev, int pri, const char *fmt,...)
Print the name of the device followed by a colon, a space and the result of calling log() with the va...
int bus_generic_teardown_intr(device_t dev, device_t child, struct resource *irq, void *cookie)
Helper function for implementing BUS_TEARDOWN_INTR().
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 int devclass_alloc_unit(devclass_t dc, device_t dev, int *unitp)
Allocate a unit number.
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()
static void device_sysctl_fini(device_t dev)
int devclass_delete_driver(devclass_t busclass, driver_t *driver)
Delete a device driver from a device class.
#define print_driver(d, i)
int devclass_find_free_unit(devclass_t dc, int unit)
Find a free unit number in a devclass.
static kobj_method_t root_methods[]
int bus_generic_bind_intr(device_t dev, device_t child, struct resource *irq, int cpu)
Helper function for implementing BUS_BIND_INTR().
int bus_generic_map_resource(device_t dev, device_t child, int type, struct resource *r, struct resource_map_request *args, struct resource_map *map)
Helper function for implementing BUS_MAP_RESOURCE().
int resource_list_add_next(struct resource_list *rl, int type, rman_res_t start, rman_res_t end, rman_res_t count)
Add a resource entry.
static int devclass_quiesce_driver(devclass_t busclass, driver_t *driver)
Quiesces a set of device drivers from a device class.
struct sysctl_ctx_list * device_get_sysctl_ctx(device_t dev)
rman_res_t bus_get_resource_count(device_t dev, int type, int rid)
Wrapper function for BUS_GET_RESOURCE().
driver_t * device_get_driver(device_t dev)
Return the current driver for the device or NULL if there is no driver currently attached.
static devclass_t devclass_find_internal(const char *classname, const char *parentname, int create)
Find or create a device class.
int bus_generic_shutdown(device_t dev)
Helper function for implementing DEVICE_SHUTDOWN()
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 bus_helper_reset_prepare(device_t dev, int flags)
Helper function for implementing BUS_RESET_PREPARE.
static int devctl_queue_length
static int devclass_delete_device(devclass_t dc, device_t dev)
Delete a device from a devclass.
struct mtx * bus_topo_mtx(void)
int device_attach(device_t dev)
Attach a device driver to a device.
static int devclass_add_device(devclass_t dc, device_t dev)
Add a device to a devclass.
#define print_devclass_list()
int device_probe_and_attach(device_t dev)
Probe a device and attach a driver if possible.
struct resource * resource_list_alloc(struct resource_list *rl, device_t bus, device_t child, int type, int *rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
Helper function for implementing BUS_ALLOC_RESOURCE()
int device_print_prettyname(device_t dev)
Print the name of the device followed by a colon and a space.
static void devaddq(const char *type, const char *what, device_t dev)
int bus_free_resource(device_t dev, int type, struct resource *r)
struct resource * bus_generic_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)
Helper function for implementing BUS_ALLOC_RESOURCE().
int device_is_alive(device_t dev)
Return non-zero if the device was successfully probed.
int bus_generic_unmap_resource(device_t dev, device_t child, int type, struct resource *r, struct resource_map *map)
Helper function for implementing BUS_UNMAP_RESOURCE().
int device_quiesce(device_t dev)
Tells a driver to quiesce itself.
void * device_get_ivars(device_t dev)
Get the device's ivars field.
devclass_t devclass_create(const char *classname)
Create a device class.
int bus_generic_rl_get_resource(device_t dev, device_t child, int type, int rid, rman_res_t *startp, rman_res_t *countp)
Helper function for implementing BUS_GET_RESOURCE().
void _gone_in_dev(device_t dev, int major, const char *msg)
static struct device_list bus_data_devices
int bus_generic_probe(device_t dev)
Helper function for implementing DEVICE_PROBE()
void devctl_safe_quote_sb(struct sbuf *sb, const char *src)
safely quotes strings that might have double quotes in them.
static kobj_method_t null_methods[]
int bus_generic_read_ivar(device_t dev, device_t child, int index, uintptr_t *result)
Stub function for implementing BUS_READ_IVAR().
static void device_gen_nomatch(device_t dev)
static driverlink_t first_matching_driver(devclass_t dc, device_t dev)
void * devclass_get_softc(devclass_t dc, int unit)
Find the softc field of a device given a unit number.
int device_is_quiet(device_t dev)
Return non-zero if the DF_QUIET flag is set on the device.
void dev_wired_cache_fini(device_location_cache_t *dcp)
static int obsolete_panic
static struct device_location_node * dev_wired_cache_add(device_location_cache_t *dcp, const char *locator, const char *path)
int device_shutdown(device_t dev)
Notify a device of system shutdown.
static void devadded(device_t dev)
static int sysctl_devices(SYSCTL_HANDLER_ARGS)
int bus_generic_adjust_resource(device_t dev, device_t child, int type, struct resource *r, rman_res_t start, rman_res_t end)
Helper function for implementing BUS_ADJUST_RESOURCE().
int device_set_unit(device_t dev, int unit)
Set the unit number of a device.
int bus_generic_child_pnpinfo(device_t dev, device_t child, struct sbuf *sb)
Generic implementation that does nothing for bus_child_pnpinfo.
void resource_list_delete(struct resource_list *rl, int type, int rid)
Delete a resource entry.
struct resource * bus_alloc_resource(device_t dev, int type, int *rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
Wrapper function for BUS_ALLOC_RESOURCE().
int bus_data_generation_check(int generation)
const char * device_get_name(device_t dev)
Return the name of the device's devclass or NULL if there is none.
void device_free_softc(void *softc)
Free claimed softc.
void * device_get_softc(device_t dev)
Return the device's softc field.
int bus_generic_child_present(device_t dev, device_t child)
Helper function for implementing BUS_CHILD_PRESENT().
int bus_get_cpus(device_t dev, enum cpu_sets op, size_t setsize, cpuset_t *cpuset)
Wrapper function for BUS_GET_CPUS().
device_t device_lookup_by_name(const char *name)
int bus_release_resource(device_t dev, int type, int rid, struct resource *r)
Wrapper function for BUS_RELEASE_RESOURCE().
int resource_list_unreserve(struct resource_list *rl, device_t bus, device_t child, int type, int rid)
Fully release a reserved resource.
struct resource * bus_generic_rl_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)
Helper function for implementing BUS_ALLOC_RESOURCE().
int bus_generic_detach(device_t dev)
Helper function for implementing DEVICE_DETACH()
bool device_has_property(device_t dev, const char *prop)
void bus_set_pass(int pass)
Raise the current bus pass.
int bus_generic_resume_child(device_t dev, device_t child)
Default function for resuming a child device.
devclass_t devclass_find(const char *classname)
Find a device class.
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 int device_print_child(device_t dev, device_t child)
Print a description of a device.
const char * devclass_get_name(devclass_t dc)
Return the name of the devclass.
static int root_child_present(device_t dev, device_t child)
void device_disable(device_t dev)
Clear the DF_ENABLED flag for the device.
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...
uint32_t device_get_flags(device_t dev)
Return the device's flags.
struct filterops devctl_rfiltops
static int sysctl_devctl_queue(SYSCTL_HANDLER_ARGS)
#define print_device_tree(d, i)
int bus_generic_print_child(device_t dev, device_t child)
Helper function for implementing BUS_PRINT_CHILD().
DECLARE_MODULE(rootbus, root_bus_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST)
typedef TAILQ_HEAD(devclass_list, devclass)
static void filt_devctl_detach(struct knote *kn)
int bus_print_child_footer(device_t dev, device_t child)
Helper function for implementing BUS_PRINT_CHILD().
int resource_disabled(const char *name, int unit)
int resource_unset_value(const char *name, int unit, const char *resname)
int resource_find_match(int *anchor, const char **name, int *unit, const char *resname, const char *value)
int resource_string_value(const char *name, int unit, const char *resname, const char **result)
int resource_int_value(const char *name, int unit, const char *resname, int *result)
void kobj_init(kobj_t obj, kobj_class_t cls)
void kobj_class_free(kobj_class_t cls)
void kobj_delete(kobj_t obj, struct malloc_type *mtype)
void kobj_class_compile(kobj_class_t cls)
int vsnprintf(char *str, size_t size, const char *format, va_list ap)
int sbuf_printf_drain(void *arg, const char *data, int len)
int printf(const char *fmt,...)
int snprintf(char *str, size_t size, const char *format,...)
void log(int level, const char *fmt,...)
device_t rman_get_device(struct resource *r)
u_int rman_get_flags(struct resource *r)
rman_res_t rman_get_end(struct resource *r)
int rman_get_rid(struct resource *r)
rman_res_t rman_get_start(struct resource *r)
void sbuf_clear_flags(struct sbuf *s, int flags)
int sbuf_finish(struct sbuf *s)
int sbuf_putc(struct sbuf *s, int c)
void sbuf_delete(struct sbuf *s)
int sbuf_printf(struct sbuf *s, const char *fmt,...)
void sbuf_set_drain(struct sbuf *s, sbuf_drain_func *func, void *ctx)
int sbuf_vprintf(struct sbuf *s, const char *fmt, va_list ap)
ssize_t sbuf_len(struct sbuf *s)
char * sbuf_data(struct sbuf *s)
int sbuf_cpy(struct sbuf *s, const char *str)
struct sbuf * sbuf_new(struct sbuf *s, char *buf, int length, int flags)
int sbuf_cat(struct sbuf *s, const char *str)
int uiomove(void *cp, int n, struct uio *uio)
void selrecord(struct thread *selector, struct selinfo *sip)
void selwakeup(struct selinfo *sip)