Index: sys/kern/subr_bus.c =================================================================== --- sys/kern/subr_bus.c +++ sys/kern/subr_bus.c @@ -1928,6 +1928,45 @@ return (child); } +static int +device_detach_family(device_t dev) +{ + device_t child; + int error; + + PDEBUG(("%s", DEVICENAME(dev))); + + /* detach children first */ + TAILQ_FOREACH(child, &dev->children, link) { + error = device_detach_family(child); + if (error) + goto done; + } + error = device_detach(dev); +done: + return (error); +} + +static void +device_delete_family(device_t parent, device_t dev) +{ + device_t child; + + PDEBUG(("%s from %s", DEVICENAME(dev), DEVICENAME(parent))); + + /* delete children first */ + while ((child = TAILQ_FIRST(&dev->children)) != NULL) + device_delete_family(dev, child); + + if (dev->devclass) + devclass_delete_device(dev->devclass, dev); + if (dev->parent) + BUS_CHILD_DELETED(parent, dev); + TAILQ_REMOVE(&parent->children, dev, link); + TAILQ_REMOVE(&bus_data_devices, dev, devlink); + kobj_delete((kobj_t) dev, M_BUS); +} + /** * @brief Delete a device * @@ -1945,28 +1984,16 @@ device_delete_child(device_t dev, device_t child) { int error; - device_t grandchild; PDEBUG(("%s from %s", DEVICENAME(child), DEVICENAME(dev))); - /* remove children first */ - while ((grandchild = TAILQ_FIRST(&child->children)) != NULL) { - error = device_delete_child(child, grandchild); - if (error) - return (error); - } - - if ((error = device_detach(child)) != 0) + error = device_detach_family(child); + if (error) return (error); - if (child->devclass) - devclass_delete_device(child->devclass, child); - if (child->parent) - BUS_CHILD_DELETED(dev, child); - TAILQ_REMOVE(&dev->children, child, link); - TAILQ_REMOVE(&bus_data_devices, child, devlink); - kobj_delete((kobj_t) child, M_BUS); + device_delete_family(dev, child); bus_data_generation_update(); + return (0); }