Lines Matching +full:parent +full:- +full:child

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
103 devclass_t parent; /* parent in devclass hierarchy */
141 TAILQ_ENTRY(_device) link; /**< list of devices in parent */
143 device_t parent; /**< parent of this device */
144 device_list_t children; /**< list of child devices */
168 static MALLOC_DEFINE(M_BUS_SC, "bus-sc", "Bus data structures, softc");
178 #define DRIVERNAME(d) ((d)? d->name : "no driver")
179 #define DEVCLANAME(d) ((d)? d->name : "no devclass")
241 value = dc->parent ? dc->parent->name : "";
252 if (dc->sysctl_tree != NULL)
254 sysctl_ctx_init(&dc->sysctl_ctx);
255 dc->sysctl_tree = SYSCTL_ADD_NODE(&dc->sysctl_ctx,
256 SYSCTL_STATIC_CHILDREN(_dev), OID_AUTO, dc->name,
258 SYSCTL_ADD_PROC(&dc->sysctl_ctx, SYSCTL_CHILDREN(dc->sysctl_tree),
259 OID_AUTO, "%parent",
262 "parent class");
289 sbuf_cat(&sb, dev->desc ? dev->desc : "");
292 sbuf_cat(&sb, dev->driver ? dev->driver->name : "");
301 sbuf_cat(&sb, dev->parent ? dev->parent->nameunit : "");
333 devclass_t dc = dev->devclass;
336 if (dev->sysctl_tree != NULL)
339 sysctl_ctx_init(&dev->sysctl_ctx);
340 dev->sysctl_tree = SYSCTL_ADD_NODE_WITH_LABEL(&dev->sysctl_ctx,
341 SYSCTL_CHILDREN(dc->sysctl_tree), OID_AUTO,
342 dev->nameunit + strlen(dc->name),
344 SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
348 SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
353 SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
357 "device location relative to parent");
358 SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
363 SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
364 OID_AUTO, "%parent",
367 "parent device");
368 SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
374 SYSCTL_ADD_INT(&dev->sysctl_ctx,
375 SYSCTL_CHILDREN(dev->sysctl_tree), OID_AUTO, "%domain",
382 devclass_t dc = dev->devclass;
384 if (dev->sysctl_tree == NULL)
386 sysctl_rename_oid(dev->sysctl_tree, dev->nameunit + strlen(dc->name));
392 if (dev->sysctl_tree == NULL)
394 sysctl_ctx_free(&dev->sysctl_ctx);
395 dev->sysctl_tree = NULL;
467 if (dl->pass < new->pass)
469 if (dl->pass == new->pass)
508 if (dl->pass <= bus_current_pass)
515 if (dl->pass > pass)
522 bus_current_pass = dl->pass;
547 * otherwise if @p create is non-zero create and return a new device
550 * If @p parentname is non-NULL, the parent of the devclass is set to
554 * @param parentname the parent devclass name or @c NULL
555 * @param create non-zero to create a devclass
568 if (!strcmp(dc->name, classname))
578 dc->parent = NULL;
579 dc->name = (char*) (dc + 1);
580 strcpy(dc->name, classname);
581 TAILQ_INIT(&dc->drivers);
588 * If a parent class is specified, then set that as our parent so
589 * that this devclass will support drivers for the parent class as
590 * well. If the parent class has the same name don't do this though
595 if (parentname && dc && !dc->parent &&
597 dc->parent = devclass_find_internal(parentname, NULL, TRUE);
598 dc->parent->flags |= DC_HAS_CHILDREN;
642 * level to save storing children-lists in the devclass structure. If
652 devclass_t parent;
658 for (i = 0; i < dc->maxunit; i++)
659 if (dc->devices[i] && device_is_attached(dc->devices[i]))
660 BUS_DRIVER_ADDED(dc->devices[i], driver);
664 * single parent pointer around, we walk the entire list of
666 * DC_HAS_CHILDREN flag when a child devclass is created on
667 * the parent, so we only walk the list for those devclasses
670 if (!(dc->flags & DC_HAS_CHILDREN))
672 parent = dc;
674 if (dc->parent == parent)
682 BUS_PROBE_NOMATCH(dev->parent, dev);
684 dev->flags |= DF_DONENOMATCH;
693 * to re-probe any unmatched children.
719 * double-free in devclass_delete_driver.
730 if (driver->baseclasses)
731 parentname = driver->baseclasses[0]->name;
734 child_dc = devclass_find_internal(driver->name, parentname, TRUE);
738 dl->driver = driver;
739 TAILQ_INSERT_TAIL(&dc->drivers, dl, link);
740 driver->refs++; /* XXX: kobj_mtx */
741 dl->pass = pass;
745 dl->flags |= DL_DEFERRED_PROBE;
764 * level to save storing children-lists in the devclass structure. If
768 * @param busclass the devclass of the parent bus
775 devclass_t parent;
782 * using the driver and which have a parent in the devclass which
792 for (i = 0; i < dc->maxunit; i++) {
793 if (dc->devices[i]) {
794 dev = dc->devices[i];
795 if (dev->driver == driver && dev->parent &&
796 dev->parent->devclass == busclass) {
800 dev->flags &= ~DF_DONENOMATCH;
801 dev->flags |= DF_NEEDNOMATCH;
811 * single parent pointer around, we walk the entire list of
813 * DC_HAS_CHILDREN flag when a child devclass is created on
814 * the parent, so we only walk the list for those devclasses
817 if (!(busclass->flags & DC_HAS_CHILDREN))
819 parent = busclass;
821 if (busclass->parent == parent) {
847 devclass_t dc = devclass_find(driver->name);
851 PDEBUG(("%s from devclass %s", driver->name, DEVCLANAME(busclass)));
859 TAILQ_FOREACH(dl, &busclass->drivers, link) {
860 if (dl->driver == driver)
865 PDEBUG(("%s not found in %s list", driver->name,
866 busclass->name));
874 TAILQ_REMOVE(&busclass->drivers, dl, link);
878 driver->refs--;
879 if (driver->refs == 0)
902 devclass_t dc = devclass_find(driver->name);
908 PDEBUG(("%s from devclass %s", driver->name, DEVCLANAME(busclass)));
916 TAILQ_FOREACH(dl, &busclass->drivers, link) {
917 if (dl->driver == driver)
922 PDEBUG(("%s not found in %s list", driver->name,
923 busclass->name));
930 * the driver and which have a parent in the devclass which we
937 for (i = 0; i < dc->maxunit; i++) {
938 if (dc->devices[i]) {
939 dev = dc->devices[i];
940 if (dev->driver == driver && dev->parent &&
941 dev->parent->devclass == busclass) {
961 TAILQ_FOREACH(dl, &dc->drivers, link) {
962 if (!strcmp(dl->driver->name, classname))
976 return (dc->name);
991 if (dc == NULL || unit < 0 || unit >= dc->maxunit)
993 return (dc->devices[unit]);
1046 for (i = 0; i < dc->maxunit; i++) {
1047 if (dc->devices[i]) {
1048 list[count] = dc->devices[i];
1083 TAILQ_FOREACH(dl, &dc->drivers, link)
1090 TAILQ_FOREACH(dl, &dc->drivers, link) {
1091 list[count] = dl->driver;
1111 for (i = 0; i < dc->maxunit; i++)
1112 if (dc->devices[i])
1120 * Note that this is one greater than the highest currently-allocated unit. If
1121 * @p dc is NULL, @c -1 is returned to indicate that not even the devclass has
1130 return (-1);
1131 return (dc->maxunit);
1149 while (unit < dc->maxunit && dc->devices[unit] != NULL)
1155 * @brief Set the parent of a devclass
1157 * The parent class is normally initialised automatically by
1161 * @param pdc the new parent devclass
1166 dc->parent = pdc;
1170 * @brief Get the parent of a devclass
1177 return (dc->parent);
1183 return (&dc->sysctl_ctx);
1189 return (dc->sysctl_tree);
1216 /* Ask the parent bus if it wants to wire this device. */
1218 BUS_HINT_DEVICE_UNIT(device_get_parent(dev), dev, dc->name,
1227 if (unit < dc->maxunit && dc->devices[unit] != NULL) {
1230 dc->name, dc->name, *unitp);
1238 if (unit < dc->maxunit && dc->devices[unit] != NULL)
1242 if (resource_string_value(dc->name, unit, "at", &s) ==
1263 if (unit >= dc->maxunit) {
1267 dc->devices = reallocf(dc->devices,
1268 newsize * sizeof(*dc->devices), M_BUS, M_WAITOK);
1269 memset(dc->devices + dc->maxunit, 0,
1270 sizeof(device_t) * (newsize - dc->maxunit));
1271 dc->maxunit = newsize;
1303 buflen = snprintf(NULL, 0, "%s%d$", dc->name, INT_MAX);
1306 dev->nameunit = malloc(buflen, M_BUS, M_NOWAIT|M_ZERO);
1307 if (!dev->nameunit)
1310 if ((error = devclass_alloc_unit(dc, dev, &dev->unit)) != 0) {
1311 free(dev->nameunit, M_BUS);
1312 dev->nameunit = NULL;
1315 dc->devices[dev->unit] = dev;
1316 dev->devclass = dc;
1317 snprintf(dev->nameunit, buflen, "%s%d", dc->name, dev->unit);
1342 if (dev->devclass != dc || dc->devices[dev->unit] != dev)
1344 dc->devices[dev->unit] = NULL;
1345 if (dev->flags & DF_WILDCARD)
1346 dev->unit = DEVICE_UNIT_ANY;
1347 dev->devclass = NULL;
1348 free(dev->nameunit, M_BUS);
1349 dev->nameunit = NULL;
1356 * @brief Make a new device and add it as a child of @p parent
1358 * @param parent the parent of the new device
1367 make_device(device_t parent, const char *name, int unit)
1372 PDEBUG(("%s at %s as unit %d", name, DEVICENAME(parent), unit));
1389 dev->parent = parent;
1390 TAILQ_INIT(&dev->children);
1392 dev->driver = NULL;
1393 dev->devclass = NULL;
1394 dev->unit = unit;
1395 dev->nameunit = NULL;
1396 dev->desc = NULL;
1397 dev->busy = 0;
1398 dev->devflags = 0;
1399 dev->flags = DF_ENABLED;
1400 dev->order = 0;
1402 dev->flags |= DF_WILDCARD;
1404 dev->flags |= DF_FIXEDCLASS;
1410 if (parent != NULL && device_has_quiet_children(parent))
1411 dev->flags |= DF_QUIET | DF_QUIET_CHILDREN;
1412 dev->ivars = NULL;
1413 dev->softc = NULL;
1414 LIST_INIT(&dev->props);
1416 dev->state = DS_NOTPRESENT;
1429 device_print_child(device_t dev, device_t child)
1433 if (device_is_alive(child))
1434 retval += BUS_PRINT_CHILD(dev, child);
1436 retval += device_printf(child, " not found\n");
1444 * This creates a new device and adds it as a child of an existing
1445 * parent device. The new device will be added after the last existing
1446 * child with order zero.
1448 * @param dev the device which will be the parent of the
1449 * new child device
1466 * This creates a new device and adds it as a child of an existing
1467 * parent device. The new device will be added after the last existing
1468 * child with the same order.
1470 * @param dev the device which will be the parent of the
1471 * new child device
1473 * children of @p dev - devices created using
1486 device_t child;
1492 ("child device with wildcard name and specific unit number"));
1494 child = make_device(dev, name, unit);
1495 if (child == NULL)
1496 return (child);
1497 child->order = order;
1499 TAILQ_FOREACH(place, &dev->children, link) {
1500 if (place->order > order)
1507 * greater than the new child.
1509 TAILQ_INSERT_BEFORE(place, child, link);
1512 * The new child's order is greater or equal to the order of
1513 * any existing device. Add the child to the tail of the list.
1515 TAILQ_INSERT_TAIL(&dev->children, child, link);
1519 return (child);
1529 * @param dev the parent device
1530 * @param child the device to delete
1533 * @retval non-zero a unit error code describing the error
1536 device_delete_child(device_t dev, device_t child)
1541 PDEBUG(("%s from %s", DEVICENAME(child), DEVICENAME(dev)));
1544 * Detach child. Ideally this cleans up any grandchild
1547 if ((error = device_detach(child)) != 0)
1551 while ((grandchild = TAILQ_FIRST(&child->children)) != NULL) {
1552 error = device_delete_child(child, grandchild);
1558 if (child->devclass)
1559 devclass_delete_device(child->devclass, child);
1560 if (child->parent)
1561 BUS_CHILD_DELETED(dev, child);
1562 TAILQ_REMOVE(&dev->children, child, link);
1563 TAILQ_REMOVE(&bus_data_devices, child, devlink);
1564 kobj_delete((kobj_t) child, M_BUS);
1575 * finds. If a child device cannot be deleted, this function will
1578 * @param dev the parent device
1581 * @retval non-zero a device would not detach
1586 device_t child;
1593 while ((child = TAILQ_FIRST(&dev->children)) != NULL) {
1594 error = device_delete_child(dev, child);
1596 PDEBUG(("Failed deleting %s", DEVICENAME(child)));
1607 * devices which have @p dev as a parent.
1609 * @param dev the parent device to search
1611 * @c DEVICE_UNIT_ANY, return the first child of @p dev
1622 device_t child;
1629 child = devclass_get_device(dc, unit);
1630 if (child && child->parent == dev)
1631 return (child);
1634 child = devclass_get_device(dc, unit);
1635 if (child && child->parent == dev)
1636 return (child);
1648 if (dev->devclass)
1649 return (devclass_find_driver_internal(dc, dev->devclass->name));
1650 return (TAILQ_FIRST(&dc->drivers));
1659 if (dev->devclass) {
1662 if (!strcmp(dev->devclass->name, dl->driver->name))
1673 device_probe_child(device_t dev, device_t child)
1680 int hasclass = (child->devclass != NULL);
1684 dc = dev->devclass;
1686 panic("device_probe_child: parent device has no devclass");
1691 if (child->state == DS_ALIVE)
1694 for (; dc; dc = dc->parent) {
1695 for (dl = first_matching_driver(dc, child);
1697 dl = next_matching_driver(dc, child, dl)) {
1699 if (dl->pass > bus_current_pass)
1702 PDEBUG(("Trying %s", DRIVERNAME(dl->driver)));
1703 result = device_set_driver(child, dl->driver);
1709 if (device_set_devclass(child,
1710 dl->driver->name) != 0) {
1712 device_get_name(child);
1718 dl->driver->name,
1720 (void)device_set_driver(child, NULL);
1726 resource_int_value(dl->driver->name, child->unit,
1727 "flags", &child->devflags);
1729 result = DEVICE_PROBE(child);
1742 child->devflags = 0;
1744 (void)device_set_devclass(child, NULL);
1750 device_verbose(child);
1758 !(child->flags & DF_FIXEDCLASS)) {
1767 (void)device_set_driver(child, NULL);
1791 result = device_set_driver(child, best->driver);
1794 if (!child->devclass) {
1795 result = device_set_devclass(child, best->driver->name);
1797 (void)device_set_driver(child, NULL);
1801 resource_int_value(best->driver->name, child->unit,
1802 "flags", &child->devflags);
1808 result = DEVICE_PROBE(child);
1811 (void)device_set_devclass(child, NULL);
1812 (void)device_set_driver(child, NULL);
1817 child->state = DS_ALIVE;
1823 * @brief Return the parent of a device
1828 return (dev->parent);
1851 device_t child;
1855 TAILQ_FOREACH(child, &dev->children, link) {
1869 TAILQ_FOREACH(child, &dev->children, link) {
1870 list[count] = child;
1887 return (dev->driver);
1897 return (dev->devclass);
1907 if (dev != NULL && dev->devclass)
1908 return (devclass_get_name(dev->devclass));
1920 return (dev->nameunit);
1929 return (dev->unit);
1938 return (dev->desc);
1947 return (dev->devflags);
1953 return (&dev->sysctl_ctx);
1959 return (dev->sysctl_tree);
2062 if (dev->desc && (dev->flags & DF_DESCMALLOCED)) {
2063 free(dev->desc, M_BUS);
2064 dev->flags &= ~DF_DESCMALLOCED;
2065 dev->desc = NULL;
2069 dev->flags |= DF_DESCMALLOCED;
2070 dev->desc = __DECONST(char *, desc);
2091 * A printf-like version of device_set_desc().
2126 dev->devflags = flags;
2138 return (dev->softc);
2150 if (dev->softc && !(dev->flags & DF_EXTERNALSOFTC))
2151 free(dev->softc, M_BUS_SC);
2152 dev->softc = softc;
2153 if (dev->softc)
2154 dev->flags |= DF_EXTERNALSOFTC;
2156 dev->flags &= ~DF_EXTERNALSOFTC;
2182 if (dev->softc)
2183 dev->flags |= DF_EXTERNALSOFTC;
2185 dev->flags &= ~DF_EXTERNALSOFTC;
2191 * The ivars field is used by the parent device to store per-device
2199 return (dev->ivars);
2209 dev->ivars = ivars;
2218 return (dev->state);
2227 dev->flags |= DF_ENABLED;
2236 dev->flags &= ~DF_ENABLED;
2248 * goes 0->1.
2250 if (refcount_acquire(&dev->busy) == 0 && dev->parent != NULL)
2251 device_busy(dev->parent);
2264 if (refcount_release(&dev->busy) && dev->parent != NULL)
2265 device_unbusy(dev->parent);
2274 dev->flags |= DF_QUIET;
2283 dev->flags |= DF_QUIET_CHILDREN;
2292 dev->flags &= ~DF_QUIET;
2308 return (-1);
2312 return (-1);
2315 return (-1);
2328 * @brief Return non-zero if the DF_QUIET_CHIDLREN flag is set on the device
2333 return ((dev->flags & DF_QUIET_CHILDREN) != 0);
2337 * @brief Return non-zero if the DF_QUIET flag is set on the device
2342 return ((dev->flags & DF_QUIET) != 0);
2346 * @brief Return non-zero if the DF_ENABLED flag is set on the device
2351 return ((dev->flags & DF_ENABLED) != 0);
2355 * @brief Return non-zero if the device was successfully probed
2360 return (dev->state >= DS_ALIVE);
2364 * @brief Return non-zero if the device currently has a driver
2370 return (dev->state >= DS_ATTACHED);
2374 * @brief Return non-zero if the device is currently suspended.
2379 return ((dev->flags & DF_SUSPENDED) != 0);
2393 if (dev->devclass)
2394 devclass_delete_device(dev->devclass, dev);
2398 if (dev->devclass) {
2428 dev->flags |= DF_FIXEDCLASS;
2439 return ((dev->flags & DF_FIXEDCLASS) != 0);
2455 if (dev->state >= DS_ATTACHED)
2458 if (dev->driver == driver)
2461 if (dev->softc && !(dev->flags & DF_EXTERNALSOFTC)) {
2462 free(dev->softc, M_BUS_SC);
2463 dev->softc = NULL;
2467 dev->driver = driver;
2470 if (!(dev->flags & DF_EXTERNALSOFTC) && driver->size > 0) {
2475 dev->softc = malloc_domainset(driver->size, M_BUS_SC,
2477 if (!dev->softc) {
2480 dev->driver = NULL;
2504 * the parent device's devclass. If the device was originally created
2508 * parent devclass, the search continues in the parent of that
2516 * @retval non-zero some other unix error code
2517 * @retval -1 Device already attached
2526 if (dev->state >= DS_ALIVE)
2527 return (-1);
2529 if (!(dev->flags & DF_ENABLED)) {
2534 return (-1);
2536 if ((error = device_probe_child(dev->parent, dev)) != 0) {
2538 !(dev->flags & DF_DONENOMATCH)) {
2559 if (error == -1)
2573 * and queues a notification event for user-based device management
2584 * @retval non-zero some other unix error code
2593 if (resource_disabled(dev->driver->name, dev->unit)) {
2600 dev->state = DS_NOTPRESENT;
2612 device_print_child(dev->parent, dev);
2614 dev->state = DS_ATTACHING;
2617 dev->driver->name, dev->unit, error);
2618 BUS_CHILD_DETACHED(dev->parent, dev);
2635 if (!(dev->flags & DF_FIXEDCLASS))
2636 devclass_delete_device(dev->devclass, dev);
2639 KASSERT(dev->busy == 0, ("attach failed but busy"));
2640 dev->state = DS_NOTPRESENT;
2646 dev->flags |= DF_ATTACHED_ONCE;
2651 attachentropy = (uint16_t)(get_cyclecount() - attachtime);
2654 dev->state = DS_ATTACHED;
2655 dev->flags &= ~DF_DONENOMATCH;
2665 * BUS_CHILD_DETACHED() for the parent of @p dev, queues a
2666 * notification event for user-based device management services and
2669 * @param dev the device to un-initialise
2674 * @retval non-zero some other unix error code
2684 if (dev->busy > 0)
2686 if (dev->state == DS_ATTACHING) {
2690 if (dev->state != DS_ATTACHED)
2704 if (dev->parent)
2705 BUS_CHILD_DETACHED(dev->parent, dev);
2707 if (!(dev->flags & DF_FIXEDCLASS))
2708 devclass_delete_device(dev->devclass, dev);
2711 dev->state = DS_NOTPRESENT;
2729 * @retval non-zero some other unix error code
2735 if (dev->busy > 0)
2737 if (dev->state != DS_ATTACHED)
2754 if (dev->state < DS_ATTACHED)
2763 * device (e.g. to wire a device to a pre-configured unit number).
2771 if (unit == dev->unit)
2774 if (unit < dc->maxunit && dc->devices[unit])
2779 dev->unit = unit;
2806 args->size = sz;
2807 args->memattr = VM_MEMATTR_DEVICE;
2834 MPASS(out->size == sizeof(struct resource_map_request));
2837 bcopy(in, out, imin(in->size, out->size));
2838 start = rman_get_start(r) + out->offset;
2839 if (out->length == 0)
2842 length = out->length;
2843 end = start + length - 1;
2878 if (rle->res)
2896 * @param count XXX end-start+1
2924 * @param count XXX end-start+1
2939 rle->type = type;
2940 rle->rid = rid;
2941 rle->res = NULL;
2942 rle->flags = 0;
2945 if (rle->res)
2948 rle->start = start;
2949 rle->end = end;
2950 rle->count = count;
2964 * @returns Non-zero if the entry is busy, zero otherwise.
2972 if (rle == NULL || rle->res == NULL)
2974 if ((rle->flags & (RLE_RESERVED | RLE_ALLOCATED)) == RLE_RESERVED) {
2975 KASSERT(!(rman_get_flags(rle->res) & RF_ACTIVE),
2993 * @returns Non-zero if the entry is reserved, zero otherwise.
3001 if (rle != NULL && rle->flags & RLE_RESERVED)
3022 if (rle->type == type && rle->rid == rid)
3041 if (rle->res != NULL)
3054 * adding a new child to the bus. The resource is allocated from the
3055 * parent bus when it is reserved. The resource list entry is marked
3064 * the parent bus by calling resource_list_unreserve().
3067 * @param bus the parent device of @p child
3068 * @param child the device for which the resource is being reserved
3071 * @param start hint at the start of the resource range - pass
3073 * @param end hint at the end of the resource range - pass
3075 * @param count hint at the size of range required - pass @c 1
3078 * allocation - see @c RF_XXX flags in
3085 resource_list_reserve(struct resource_list *rl, device_t bus, device_t child,
3089 int passthrough = (device_get_parent(child) != bus);
3099 r = resource_list_alloc(rl, bus, child, type, rid, start, end, count,
3103 rle->flags |= RLE_RESERVED;
3112 * and passing the allocation up to the parent of @p bus. This assumes
3113 * that the first entry of @c device_get_ivars(child) is a struct
3115 * child is a remote descendant of bus by passing the allocation up to
3116 * the parent of bus.
3118 * Typically, a bus driver would store a list of child resources
3119 * somewhere in the child device's ivars (see device_get_ivars()) and
3124 * @param bus the parent device of @p child
3125 * @param child the device which is requesting an allocation
3128 * @param start hint at the start of the resource range - pass
3130 * @param end hint at the end of the resource range - pass
3132 * @param count hint at the size of range required - pass @c 1
3135 * allocation - see @c RF_XXX flags in
3142 resource_list_alloc(struct resource_list *rl, device_t bus, device_t child,
3146 int passthrough = (device_get_parent(child) != bus);
3150 return (BUS_ALLOC_RESOURCE(device_get_parent(bus), child,
3159 if (rle->res) {
3160 if (rle->flags & RLE_RESERVED) {
3161 if (rle->flags & RLE_ALLOCATED)
3164 bus_activate_resource(child, type, *rid,
3165 rle->res) != 0)
3167 rle->flags |= RLE_ALLOCATED;
3168 return (rle->res);
3171 "resource entry %#x type %d for child %s is busy\n", *rid,
3172 type, device_get_nameunit(child));
3177 start = rle->start;
3178 count = ulmax(count, rle->count);
3179 end = ulmax(rle->end, start + count - 1);
3182 rle->res = BUS_ALLOC_RESOURCE(device_get_parent(bus), child,
3188 if (rle->res) {
3189 rle->start = rman_get_start(rle->res);
3190 rle->end = rman_get_end(rle->res);
3191 rle->count = count;
3194 return (rle->res);
3204 * @param bus the parent device of @p child
3205 * @param child the device which is requesting a release
3209 * @retval non-zero a standard unix error code indicating what
3213 resource_list_release(struct resource_list *rl, device_t bus, device_t child,
3217 int passthrough = (device_get_parent(child) != bus);
3221 return (BUS_RELEASE_RESOURCE(device_get_parent(bus), child,
3229 if (!rle->res)
3231 if (rle->flags & RLE_RESERVED) {
3232 if (rle->flags & RLE_ALLOCATED) {
3234 error = bus_deactivate_resource(child, res);
3238 rle->flags &= ~RLE_ALLOCATED;
3244 error = BUS_RELEASE_RESOURCE(device_get_parent(bus), child, res);
3248 rle->res = NULL;
3260 * @param bus the parent device of @p child
3261 * @param child the device whose active resources are being released
3269 device_t child, int type)
3276 if (rle->type != type)
3278 if (rle->res == NULL)
3280 if ((rle->flags & (RLE_RESERVED | RLE_ALLOCATED)) ==
3284 error = resource_list_release(rl, bus, child, rle->res);
3298 * @param bus the parent device of @p child
3299 * @param child the device whose reserved resource is being released
3305 * @retval non-zero a standard unix error code indicating what
3309 resource_list_unreserve(struct resource_list *rl, device_t bus, device_t child,
3313 int passthrough = (device_get_parent(child) != bus);
3323 if (!(rle->flags & RLE_RESERVED))
3325 if (rle->flags & RLE_ALLOCATED)
3327 rle->flags &= ~RLE_RESERVED;
3328 return (resource_list_release(rl, bus, child, rle->res));
3357 if (rle->type == type) {
3363 retval += printf(format, rle->start);
3364 if (rle->count > 1) {
3365 retval += printf("-");
3366 retval += printf(format, rle->start +
3367 rle->count - 1);
3387 if (rle->res)
3388 bus_release_resource(rman_get_device(rle->res),
3389 rle->type, rle->rid, rle->res);
3417 * @brief Ask drivers to add child devices of the given device.
3419 * This function allows drivers for child devices of a bus to identify
3420 * child devices and add them as children of the given device. NB:
3423 * @param dev the parent device
3428 devclass_t dc = dev->devclass;
3431 TAILQ_FOREACH(dl, &dc->drivers, link) {
3435 * never be true. For early-pass drivers they will
3439 * on early-pass buses during BUS_NEW_PASS().
3441 if (dl->pass > bus_current_pass)
3443 DEVICE_IDENTIFY(dl->driver, dev);
3465 * child of the given device using device_probe_and_attach(). If an
3466 * individual child fails to attach this function continues attaching
3469 * @param dev the parent device
3474 device_t child;
3476 TAILQ_FOREACH(child, &dev->children, link) {
3477 device_probe_and_attach(child);
3500 * child fails to detach, this function stops and returns an error.
3502 * @param dev the parent device
3505 * @retval non-zero a device would not detach
3523 * child of the given device using device_detach(). If an individual
3524 * child fails to detach this function stops and returns an error.
3525 * NB: Children that were successfully detached are not re-attached if
3528 * @param dev the parent device
3531 * @retval non-zero a device would not detach
3536 device_t child;
3543 TAILQ_FOREACH_REVERSE(child, &dev->children, device_list, link) {
3544 if ((error = device_detach(child)) != 0)
3561 device_t child;
3567 TAILQ_FOREACH_REVERSE(child, &dev->children, device_list, link) {
3568 device_shutdown(child);
3575 * @brief Default function for suspending a child device.
3580 bus_generic_suspend_child(device_t dev, device_t child)
3584 error = DEVICE_SUSPEND(child);
3587 child->flags |= DF_SUSPENDED;
3590 device_get_nameunit(child), error);
3597 * @brief Default function for resuming a child device.
3602 bus_generic_resume_child(device_t dev, device_t child)
3604 DEVICE_RESUME(child);
3605 child->flags &= ~DF_SUSPENDED;
3623 device_t child;
3628 * Other buses, such as acpi, carefully order their child devices to
3632 TAILQ_FOREACH_REVERSE(child, &dev->children, device_list, link) {
3633 error = BUS_SUSPEND_CHILD(dev, child);
3635 child = TAILQ_NEXT(child, link);
3636 if (child != NULL) {
3637 TAILQ_FOREACH_FROM(child, &dev->children, link)
3638 BUS_RESUME_CHILD(dev, child);
3655 device_t child;
3657 TAILQ_FOREACH(child, &dev->children, link) {
3658 BUS_RESUME_CHILD(dev, child);
3668 * re-attaching or resuming the children after the bus itself was
3669 * reset, and after restoring bus-unique state of children.
3677 device_t child;
3681 TAILQ_FOREACH(child, &dev->children,link) {
3682 BUS_RESET_POST(dev, child);
3684 device_probe_and_attach(child) :
3685 BUS_RESUME_CHILD(dev, child);
3693 bus_helper_reset_prepare_rollback(device_t dev, device_t child, int flags)
3695 child = TAILQ_NEXT(child, link);
3696 if (child == NULL)
3698 TAILQ_FOREACH_FROM(child, &dev->children,link) {
3699 BUS_RESET_POST(dev, child);
3701 device_probe_and_attach(child);
3703 BUS_RESUME_CHILD(dev, child);
3712 * reset, and then save bus-unique state of children that must
3721 device_t child;
3724 if (dev->state != DS_ATTACHED)
3727 TAILQ_FOREACH_REVERSE(child, &dev->children, device_list, link) {
3729 error = device_get_state(child) == DS_ATTACHED ?
3730 device_detach(child) : 0;
3732 error = BUS_SUSPEND_CHILD(dev, child);
3735 error = BUS_RESET_PREPARE(dev, child);
3738 device_probe_and_attach(child);
3740 BUS_RESUME_CHILD(dev, child);
3744 bus_helper_reset_prepare_rollback(dev, child, flags);
3755 * @p child, including its name, unit and description (if any - see
3761 bus_print_child_header(device_t dev, device_t child)
3765 if (device_get_desc(child)) {
3766 retval += device_printf(child, "<%s>", device_get_desc(child));
3768 retval += printf("%s", device_get_nameunit(child));
3778 * @p child, which consists of the string @c " on " followed by the
3784 bus_print_child_footer(device_t dev, device_t child)
3797 bus_print_child_domain(device_t dev, device_t child)
3802 if (BUS_GET_DOMAIN(dev, child, &domain) != 0)
3805 return (printf(" numa-domain %d", domain));
3817 bus_generic_print_child(device_t dev, device_t child)
3821 retval += bus_print_child_header(dev, child);
3822 retval += bus_print_child_domain(dev, child);
3823 retval += bus_print_child_footer(dev, child);
3834 bus_generic_read_ivar(device_t dev, device_t child, int index,
3846 bus_generic_write_ivar(device_t dev, device_t child, int index,
3855 * This simply calls the BUS_GET_PROPERTY of the parent of dev,
3856 * until a non-default implementation is found.
3859 bus_generic_get_property(device_t dev, device_t child, const char *propname,
3863 return (BUS_GET_PROPERTY(device_get_parent(dev), child,
3866 return (-1);
3875 bus_generic_get_resource_list(device_t dev, device_t child)
3885 * and then calls device_probe_and_attach() for each unattached child.
3890 device_t child;
3893 TAILQ_FOREACH(child, &dev->children, link) {
3894 if (child->state == DS_NOTPRESENT)
3895 device_probe_and_attach(child);
3914 device_t child;
3916 dc = dev->devclass;
3917 TAILQ_FOREACH(dl, &dc->drivers, link) {
3918 if (dl->pass == bus_current_pass)
3919 DEVICE_IDENTIFY(dl->driver, dev);
3921 TAILQ_FOREACH(child, &dev->children, link) {
3922 if (child->state >= DS_ATTACHED)
3923 BUS_NEW_PASS(child);
3924 else if (child->state == DS_NOTPRESENT)
3925 device_probe_and_attach(child);
3933 * BUS_SETUP_INTR() method of the parent of @p dev.
3936 bus_generic_setup_intr(device_t dev, device_t child, struct resource *irq,
3941 if (dev->parent)
3942 return (BUS_SETUP_INTR(dev->parent, child, irq, flags,
3951 * BUS_TEARDOWN_INTR() method of the parent of @p dev.
3954 bus_generic_teardown_intr(device_t dev, device_t child, struct resource *irq,
3958 if (dev->parent)
3959 return (BUS_TEARDOWN_INTR(dev->parent, child, irq, cookie));
3967 * BUS_SUSPEND_INTR() method of the parent of @p dev.
3970 bus_generic_suspend_intr(device_t dev, device_t child, struct resource *irq)
3973 if (dev->parent)
3974 return (BUS_SUSPEND_INTR(dev->parent, child, irq));
3982 * BUS_RESUME_INTR() method of the parent of @p dev.
3985 bus_generic_resume_intr(device_t dev, device_t child, struct resource *irq)
3988 if (dev->parent)
3989 return (BUS_RESUME_INTR(dev->parent, child, irq));
3997 * BUS_ADJUST_RESOURCE() method of the parent of @p dev.
4000 bus_generic_adjust_resource(device_t dev, device_t child, struct resource *r,
4004 if (dev->parent)
4005 return (BUS_ADJUST_RESOURCE(dev->parent, child, r, start, end));
4013 * BUS_TRANSLATE_RESOURCE() method of the parent of @p dev. If there is no
4014 * parent, no translation happens.
4020 if (dev->parent)
4021 return (BUS_TRANSLATE_RESOURCE(dev->parent, type, start,
4031 * BUS_ALLOC_RESOURCE() method of the parent of @p dev.
4034 bus_generic_alloc_resource(device_t dev, device_t child, int type, int *rid,
4038 if (dev->parent)
4039 return (BUS_ALLOC_RESOURCE(dev->parent, child, type, rid,
4048 * BUS_RELEASE_RESOURCE() method of the parent of @p dev.
4051 bus_generic_release_resource(device_t dev, device_t child, struct resource *r)
4054 if (dev->parent)
4055 return (BUS_RELEASE_RESOURCE(dev->parent, child, r));
4063 * BUS_ACTIVATE_RESOURCE() method of the parent of @p dev.
4066 bus_generic_activate_resource(device_t dev, device_t child, struct resource *r)
4069 if (dev->parent)
4070 return (BUS_ACTIVATE_RESOURCE(dev->parent, child, r));
4078 * BUS_DEACTIVATE_RESOURCE() method of the parent of @p dev.
4081 bus_generic_deactivate_resource(device_t dev, device_t child,
4085 if (dev->parent)
4086 return (BUS_DEACTIVATE_RESOURCE(dev->parent, child, r));
4094 * BUS_MAP_RESOURCE() method of the parent of @p dev.
4097 bus_generic_map_resource(device_t dev, device_t child, struct resource *r,
4101 if (dev->parent)
4102 return (BUS_MAP_RESOURCE(dev->parent, child, r, args, map));
4110 * BUS_UNMAP_RESOURCE() method of the parent of @p dev.
4113 bus_generic_unmap_resource(device_t dev, device_t child, struct resource *r,
4117 if (dev->parent)
4118 return (BUS_UNMAP_RESOURCE(dev->parent, child, r, map));
4126 * BUS_BIND_INTR() method of the parent of @p dev.
4129 bus_generic_bind_intr(device_t dev, device_t child, struct resource *irq,
4133 if (dev->parent)
4134 return (BUS_BIND_INTR(dev->parent, child, irq, cpu));
4142 * BUS_CONFIG_INTR() method of the parent of @p dev.
4149 if (dev->parent)
4150 return (BUS_CONFIG_INTR(dev->parent, irq, trig, pol));
4158 * BUS_DESCRIBE_INTR() method of the parent of @p dev.
4161 bus_generic_describe_intr(device_t dev, device_t child, struct resource *irq,
4165 if (dev->parent)
4166 return (BUS_DESCRIBE_INTR(dev->parent, child, irq, cookie,
4175 * BUS_GET_CPUS() method of the parent of @p dev.
4178 bus_generic_get_cpus(device_t dev, device_t child, enum cpu_sets op,
4182 if (dev->parent != NULL)
4183 return (BUS_GET_CPUS(dev->parent, child, op, setsize, cpuset));
4191 * BUS_GET_DMA_TAG() method of the parent of @p dev.
4194 bus_generic_get_dma_tag(device_t dev, device_t child)
4197 if (dev->parent != NULL)
4198 return (BUS_GET_DMA_TAG(dev->parent, child));
4206 * BUS_GET_BUS_TAG() method of the parent of @p dev.
4209 bus_generic_get_bus_tag(device_t dev, device_t child)
4212 if (dev->parent != NULL)
4213 return (BUS_GET_BUS_TAG(dev->parent, child));
4226 bus_generic_rl_get_resource(device_t dev, device_t child, int type, int rid,
4232 rl = BUS_GET_RESOURCE_LIST(dev, child);
4241 *startp = rle->start;
4243 *countp = rle->count;
4257 bus_generic_rl_set_resource(device_t dev, device_t child, int type, int rid,
4262 rl = BUS_GET_RESOURCE_LIST(dev, child);
4266 resource_list_add(rl, type, rid, start, (start + count - 1), count);
4280 bus_generic_rl_delete_resource(device_t dev, device_t child, int type, int rid)
4284 rl = BUS_GET_RESOURCE_LIST(dev, child);
4301 bus_generic_rl_release_resource(device_t dev, device_t child,
4306 if (device_get_parent(child) != dev)
4307 return (BUS_RELEASE_RESOURCE(device_get_parent(dev), child, r));
4309 rl = BUS_GET_RESOURCE_LIST(dev, child);
4313 return (resource_list_release(rl, dev, child, r));
4324 bus_generic_rl_alloc_resource(device_t dev, device_t child, int type,
4329 if (device_get_parent(child) != dev)
4330 return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
4333 rl = BUS_GET_RESOURCE_LIST(dev, child);
4337 return (resource_list_alloc(rl, dev, child, type, rid,
4349 bus_generic_rman_alloc_resource(device_t dev, device_t child, int type,
4360 child);
4367 if (bus_activate_resource(child, type, *rid, r) != 0) {
4384 bus_generic_rman_adjust_resource(device_t dev, device_t child,
4404 bus_generic_rman_release_resource(device_t dev, device_t child,
4419 error = bus_deactivate_resource(child, r);
4433 bus_generic_rman_activate_resource(device_t dev, device_t child,
4457 error = BUS_MAP_RESOURCE(dev, child, r, NULL, &map);
4466 error = intr_activate_irq(child, r);
4482 bus_generic_rman_deactivate_resource(device_t dev, device_t child,
4507 BUS_UNMAP_RESOURCE(dev, child, r, &map);
4512 intr_deactivate_irq(child, r);
4523 * BUS_CHILD_PRESENT() method of the parent of @p dev.
4526 bus_generic_child_present(device_t dev, device_t child)
4535 * BUS_GET_DOMAIN() method of the parent of @p dev. If @p dev
4536 * does not have a parent, the function fails with ENOENT.
4539 bus_generic_get_domain(device_t dev, device_t child, int *domain)
4541 if (dev->parent)
4542 return (BUS_GET_DOMAIN(dev->parent, dev, domain));
4551 * a parent and (b) Knows how to supply a FreeBSD locator.
4554 * @param child leaf node to print information about
4559 bus_generic_get_device_path(device_t bus, device_t child, const char *locator,
4563 device_t parent;
4570 * node. That's why we recurse with parent, bus rather than the typical
4571 * parent, child: each spot in the tree is independent of what our child
4574 parent = device_get_parent(bus);
4575 if (parent != NULL && strcmp(locator, BUS_LOCATOR_ACPI) != 0) {
4576 rv = BUS_GET_DEVICE_PATH(parent, bus, locator, sb);
4580 sbuf_printf(sb, "/%s", device_get_nameunit(child));
4606 * resource-management functions. All these really do is hide the
4607 * indirection through the parent's method table, making for slightly
4608 * less-wordy code. In the future, it might make sense for this code
4618 for (i = 0; rs[i].type != -1; i++)
4620 for (i = 0; rs[i].type != -1; i++) {
4637 for (i = 0; rs[i].type != -1; i++)
4649 * parent of @p dev.
4657 if (dev->parent == NULL)
4659 res = BUS_ALLOC_RESOURCE(dev->parent, dev, type, rid, start, end,
4668 * parent of @p dev.
4674 if (dev->parent == NULL)
4676 return (BUS_ADJUST_RESOURCE(dev->parent, dev, r, start, end));
4690 * parent of @p dev.
4696 if (dev->parent == NULL)
4698 return (BUS_TRANSLATE_RESOURCE(dev->parent, type, start, newstart));
4705 * parent of @p dev.
4710 if (dev->parent == NULL)
4712 return (BUS_ACTIVATE_RESOURCE(dev->parent, dev, r));
4725 * parent of @p dev.
4730 if (dev->parent == NULL)
4732 return (BUS_DEACTIVATE_RESOURCE(dev->parent, dev, r));
4745 * parent of @p dev.
4751 if (dev->parent == NULL)
4753 return (BUS_MAP_RESOURCE(dev->parent, dev, r, args, map));
4767 * parent of @p dev.
4772 if (dev->parent == NULL)
4774 return (BUS_UNMAP_RESOURCE(dev->parent, dev, r, map));
4788 * parent of @p dev.
4795 if (dev->parent == NULL)
4797 rv = BUS_RELEASE_RESOURCE(dev->parent, dev, r);
4811 * parent of @p dev.
4819 if (dev->parent == NULL)
4821 error = BUS_SETUP_INTR(dev->parent, dev, r, flags, filter, handler,
4826 device_printf(dev, "[GIANT-LOCKED]\n");
4834 * parent of @p dev.
4839 if (dev->parent == NULL)
4841 return (BUS_TEARDOWN_INTR(dev->parent, dev, r, cookie));
4848 * parent of @p dev.
4853 if (dev->parent == NULL)
4855 return (BUS_SUSPEND_INTR(dev->parent, dev, r));
4862 * parent of @p dev.
4867 if (dev->parent == NULL)
4869 return (BUS_RESUME_INTR(dev->parent, dev, r));
4876 * parent of @p dev.
4881 if (dev->parent == NULL)
4883 return (BUS_BIND_INTR(dev->parent, dev, r, cpu));
4891 * the parent of @p dev.
4900 if (dev->parent == NULL)
4905 return (BUS_DESCRIBE_INTR(dev->parent, dev, irq, cookie, descr));
4912 * parent of @p dev.
4926 * parent of @p dev.
4940 * parent of @p dev and returns the start value.
4960 * parent of @p dev and returns the count value.
4980 * parent of @p dev.
4992 * parent of @p dev.
4995 bus_child_present(device_t child)
4997 return (BUS_CHILD_PRESENT(device_get_parent(child), child));
5003 * This function simply calls the BUS_CHILD_PNPINFO() method of the parent of @p
5007 bus_child_pnpinfo(device_t child, struct sbuf *sb)
5009 device_t parent;
5011 parent = device_get_parent(child);
5012 if (parent == NULL)
5014 return (BUS_CHILD_PNPINFO(parent, child, sb));
5024 bus_generic_child_pnpinfo(device_t dev, device_t child, struct sbuf *sb)
5032 * This function simply calls the BUS_CHILD_LOCATION() method of the parent of
5036 bus_child_location(device_t child, struct sbuf *sb)
5038 device_t parent;
5040 parent = device_get_parent(child);
5041 if (parent == NULL)
5043 return (BUS_CHILD_LOCATION(parent, child, sb));
5053 bus_generic_child_location(device_t dev, device_t child, struct sbuf *sb)
5062 * parent of @p dev.
5067 device_t parent;
5069 parent = device_get_parent(dev);
5070 if (parent == NULL)
5072 return (BUS_GET_CPUS(parent, dev, op, setsize, cpuset));
5079 * parent of @p dev.
5084 device_t parent;
5086 parent = device_get_parent(dev);
5087 if (parent == NULL)
5089 return (BUS_GET_DMA_TAG(parent, dev));
5096 * parent of @p dev.
5101 device_t parent;
5103 parent = device_get_parent(dev);
5104 if (parent == NULL)
5106 return (BUS_GET_BUS_TAG(parent, dev));
5113 * parent of @p dev.
5135 root_print_child(device_t dev, device_t child)
5139 retval += bus_print_child_header(dev, child);
5146 root_setup_intr(device_t dev, device_t child, struct resource *irq, int flags,
5158 * this call long before it gets here. We return -1 so that drivers that
5159 * really care can check vs -1 or some ERRNO returned higher in the food
5163 root_child_present(device_t dev, device_t child)
5165 return (-1);
5169 root_get_cpus(device_t dev, device_t child, enum cpu_sets op, size_t setsize,
5218 root_bus->desc = "System root bus";
5220 root_bus->driver = &root_driver;
5221 root_bus->state = DS_ATTACHED;
5247 * device_probe_and_attach() for each child of the @c root0 device.
5275 bus_devclass = devclass_find_internal(dmd->dmd_busname, NULL, TRUE);
5280 if (dmd->dmd_chainevh)
5281 error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg);
5283 pass = dmd->dmd_pass;
5284 driver = dmd->dmd_driver;
5286 DRIVERNAME(driver), dmd->dmd_busname, pass));
5288 dmd->dmd_devclass);
5293 DRIVERNAME(dmd->dmd_driver),
5294 dmd->dmd_busname));
5296 dmd->dmd_driver);
5298 if (!error && dmd->dmd_chainevh)
5299 error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg);
5303 DRIVERNAME(dmd->dmd_driver),
5304 dmd->dmd_busname));
5306 dmd->dmd_driver);
5308 if (!error && dmd->dmd_chainevh)
5309 error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg);
5366 dev->unit, dev->desc,
5367 (dev->parent? "":"no "),
5368 (TAILQ_EMPTY(&dev->children)? "no ":""),
5369 (dev->flags&DF_ENABLED? "enabled,":"disabled,"),
5370 (dev->flags&DF_FIXEDCLASS? "fixed,":""),
5371 (dev->flags&DF_WILDCARD? "wildcard,":""),
5372 (dev->flags&DF_DESCMALLOCED? "descmalloced,":""),
5373 (dev->flags&DF_SUSPENDED? "suspended,":""),
5374 (dev->ivars? "":"no "),
5375 (dev->softc? "":"no "),
5376 dev->busy));
5387 indentprintf(("Parent:\n"));
5388 print_device_short(dev->parent, indent+1);
5390 print_driver_short(dev->driver, indent+1);
5392 print_devclass_short(dev->devclass, indent+1);
5399 device_t child;
5406 TAILQ_FOREACH(child, &dev->children, link) {
5407 print_device_tree_short(child, indent+1);
5415 device_t child;
5422 TAILQ_FOREACH(child, &dev->children, link) {
5423 print_device_tree(child, indent+1);
5434 driver->name, driver->size));
5452 print_driver(driver->driver, indent);
5462 indentprintf(("devclass %s: max units = %d\n", dc->name, dc->maxunit));
5475 print_driver_list(dc->drivers, indent+1);
5478 for (i = 0; i < dc->maxunit; i++)
5479 if (dc->devices[i])
5480 print_device(dc->devices[i], indent+1);
5508 * User-space access to the device tree.
5533 "bus-related data");
5558 if (index-- == 0)
5568 udev->dv_handle = (uintptr_t)dev;
5569 udev->dv_parent = (uintptr_t)dev->parent;
5570 udev->dv_devflags = dev->devflags;
5571 udev->dv_flags = dev->flags;
5572 udev->dv_state = dev->state;
5573 sbuf_new(&sb, udev->dv_fields, sizeof(udev->dv_fields), SBUF_FIXEDLEN);
5574 if (dev->nameunit != NULL)
5575 sbuf_cat(&sb, dev->nameunit);
5577 if (dev->desc != NULL)
5578 sbuf_cat(&sb, dev->desc);
5580 if (dev->driver != NULL)
5581 sbuf_cat(&sb, dev->driver->name);
5629 if (dev->nameunit != NULL && strcmp(dev->nameunit, name) == 0)
5648 if (memchr(req->dr_name, '\0', sizeof(req->dr_name)) == NULL)
5655 dev = device_lookup_by_name(req->dr_name);
5663 EVENTHANDLER_DIRECT_INVOKE(dev_lookup, req->dr_name, &dev);
5675 for (dc = bus->devclass; dc != NULL; dc = dc->parent) {
5685 device_t child;
5687 if (dev->flags & DF_NEEDNOMATCH &&
5688 dev->state == DS_NOTPRESENT) {
5691 dev->flags &= ~DF_NEEDNOMATCH;
5692 TAILQ_FOREACH(child, &dev->children, link) {
5693 device_gen_nomatch(child);
5711 TAILQ_FOREACH(dl, &dc->drivers, link) {
5712 if (dl->flags & DL_DEFERRED_PROBE) {
5713 devclass_driver_added(dc, dl->driver);
5714 dl->flags &= ~DL_DEFERRED_PROBE;
5720 * We also defer no-match events during a freeze. Walk the tree and
5721 * generate all the pent-up events that are still relevant.
5730 device_t parent;
5734 parent = device_get_parent(dev);
5735 if (parent == NULL) {
5738 error = BUS_GET_DEVICE_PATH(parent, dev, locator, sb);
5807 if (!(req->dr_flags & DEVF_FORCE_DETACH)) {
5826 if (dev->devclass != NULL) {
5831 if (resource_disabled(dev->devclass->name, dev->unit))
5832 resource_unset_value(dev->devclass->name,
5833 dev->unit, "disabled");
5836 if (!(dev->flags & DF_FIXEDCLASS))
5837 devclass_delete_device(dev->devclass, dev);
5847 if (!(req->dr_flags & DEVF_FORCE_DETACH)) {
5857 old = dev->flags;
5858 dev->flags |= DF_FIXEDCLASS;
5861 dev->flags &= ~DF_FIXEDCLASS;
5891 error = copyinstr(req->dr_data, driver, sizeof(driver), NULL);
5898 if (dev->devclass != NULL &&
5899 strcmp(driver, dev->devclass->name) == 0)
5907 if (dev->parent == NULL) {
5911 if (!driver_exists(dev->parent, driver)) {
5923 if (req->dr_flags & DEVF_SET_DRIVER_DETACH)
5931 /* Clear any previously-fixed device class and unit. */
5932 if (dev->flags & DF_FIXEDCLASS)
5933 devclass_delete_device(dev->devclass, dev);
5934 dev->flags |= DF_WILDCARD;
5935 dev->unit = DEVICE_UNIT_ANY;
5941 dev->flags |= DF_FIXEDCLASS;
5946 if (!(dev->flags & DF_FIXEDCLASS)) {
5951 if (req->dr_flags & DEVF_CLEAR_DRIVER_DETACH)
5959 dev->flags &= ~DF_FIXEDCLASS;
5960 dev->flags |= DF_WILDCARD;
5961 devclass_delete_device(dev->devclass, dev);
5972 device_t parent;
5974 parent = device_get_parent(dev);
5975 if (parent == NULL) {
5979 if (!(req->dr_flags & DEVF_FORCE_DELETE)) {
5986 error = device_delete_child(parent, dev);
6004 if ((req->dr_flags & ~(DEVF_RESET_DETACH)) != 0) {
6013 req->dr_flags);
6020 error = copyinstr(req->dr_buffer.buffer, locator,
6029 if (req->dr_buffer.length < len) {
6033 req->dr_buffer.buffer, len);
6035 req->dr_buffer.length = len;
6082 TAILQ_INIT(&dcp->dlc_list);
6092 TAILQ_FOREACH_SAFE(dln, &dcp->dlc_list, dln_link, tdln) {
6103 TAILQ_FOREACH(dln, &dcp->dlc_list, dln_link) {
6104 if (strcmp(locator, dln->dln_locator) == 0)
6120 dln->dln_locator = (char *)(dln + 1);
6121 memcpy(__DECONST(char *, dln->dln_locator), locator, loclen);
6122 dln->dln_path = dln->dln_locator + loclen;
6123 memcpy(__DECONST(char *, dln->dln_path), path, pathlen);
6124 TAILQ_INSERT_HEAD(&dcp->dlc_list, dln, dln_link);
6142 len = cp - at;
6143 if (len > sizeof(locator) - 1) /* Skip too long locator */
6164 if (error != 0 || res == NULL || res->dln_path == NULL)
6167 return (strcmp(res->dln_path, cp) == 0);
6177 LIST_FOREACH(e, &dev->props, link) {
6178 if (strcmp(name, e->name) == 0)
6203 e1->name = name;
6204 e1->val = val;
6205 e1->dtr = dtr;
6206 e1->dtr_ctx = dtr_ctx;
6207 LIST_INSERT_HEAD(&dev->props, e1, link);
6212 if (e->dtr != NULL)
6213 e->dtr(dev, name, e->val, e->dtr_ctx);
6214 e->val = val;
6215 e->dtr = dtr;
6216 e->dtr_ctx = dtr_ctx;
6217 LIST_INSERT_HEAD(&dev->props, e, link);
6231 *valp = e->val;
6246 if (e->dtr != NULL)
6247 e->dtr(dev, e->name, e->val, e->dtr_ctx);
6259 while ((e = LIST_FIRST(&dev->props)) != NULL) {
6260 LIST_REMOVE_HEAD(&dev->props, link);
6261 if (e->dtr != NULL)
6262 e->dtr(dev, e->name, e->val, e->dtr_ctx);
6336 db_printf(" driver: %s\n", DRIVERNAME(dev->driver));
6337 db_printf(" class: %s\n", DEVCLANAME(dev->devclass));
6339 db_printf(" parent: %p\n", dev->parent);
6340 db_printf(" softc: %p\n", dev->softc);
6341 db_printf(" ivars: %p\n", dev->ivars);