summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/arm/xscale/ixp425/avila_ata.c8
-rw-r--r--sys/dev/ahci/ahci.c10
-rw-r--r--sys/dev/ata/ata-disk.c9
-rw-r--r--sys/dev/ata/ata-pci.c9
-rw-r--r--sys/dev/gpio/gpiobus.c11
-rw-r--r--sys/dev/mvs/mvs_pci.c9
-rw-r--r--sys/dev/mvs/mvs_soc.c9
-rw-r--r--sys/dev/ppbus/ppbconf.c10
-rw-r--r--sys/dev/ppc/ppc.c9
-rw-r--r--sys/dev/siba/siba_core.c12
-rw-r--r--sys/dev/siis/siis.c9
-rw-r--r--sys/dev/usb/usb_util.c25
-rw-r--r--sys/dev/usb/usb_util.h1
-rw-r--r--sys/kern/subr_bus.c33
-rw-r--r--sys/sys/bus.h1
15 files changed, 56 insertions, 109 deletions
diff --git a/sys/arm/xscale/ixp425/avila_ata.c b/sys/arm/xscale/ixp425/avila_ata.c
index 03a534f..7194d03 100644
--- a/sys/arm/xscale/ixp425/avila_ata.c
+++ b/sys/arm/xscale/ixp425/avila_ata.c
@@ -259,17 +259,11 @@ static int
ata_avila_detach(device_t dev)
{
struct ata_avila_softc *sc = device_get_softc(dev);
- device_t *children;
- int nc;
/* XXX quiesce gpio? */
/* detach & delete all children */
- if (device_get_children(dev, &children, &nc) == 0) {
- if (nc > 0)
- device_delete_child(dev, children[0]);
- free(children, M_TEMP);
- }
+ device_delete_all_children(dev);
bus_teardown_intr(dev, sc->sc_irq, sc->sc_ih);
bus_release_resource(dev, SYS_RES_IRQ, sc->sc_rid, sc->sc_irq);
diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c
index 4de14c9..6aa131c 100644
--- a/sys/dev/ahci/ahci.c
+++ b/sys/dev/ahci/ahci.c
@@ -515,15 +515,11 @@ static int
ahci_detach(device_t dev)
{
struct ahci_controller *ctlr = device_get_softc(dev);
- device_t *children;
- int nchildren, i;
+ int i;
/* Detach & delete all children */
- if (!device_get_children(dev, &children, &nchildren)) {
- for (i = 0; i < nchildren; i++)
- device_delete_child(dev, children[i]);
- free(children, M_TEMP);
- }
+ device_delete_all_children(dev);
+
/* Free interrupts. */
for (i = 0; i < ctlr->numirqs; i++) {
if (ctlr->irqs[i].r_irq) {
diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c
index bcaf6c4..c872f62 100644
--- a/sys/dev/ata/ata-disk.c
+++ b/sys/dev/ata/ata-disk.c
@@ -172,8 +172,6 @@ ad_detach(device_t dev)
{
struct ad_softc *adp = device_get_ivars(dev);
struct ata_device *atadev = device_get_softc(dev);
- device_t *children;
- int nchildren, i;
/* check that we have a valid disk to detach */
if (!device_get_ivars(dev))
@@ -183,12 +181,7 @@ ad_detach(device_t dev)
callout_drain(&atadev->spindown_timer);
/* detach & delete all children */
- if (!device_get_children(dev, &children, &nchildren)) {
- for (i = 0; i < nchildren; i++)
- if (children[i])
- device_delete_child(dev, children[i]);
- free(children, M_TEMP);
- }
+ device_delete_all_children(dev);
/* destroy disk from the system so we don't get any further requests */
disk_destroy(adp->disk);
diff --git a/sys/dev/ata/ata-pci.c b/sys/dev/ata/ata-pci.c
index 26b3628..9fcd003 100644
--- a/sys/dev/ata/ata-pci.c
+++ b/sys/dev/ata/ata-pci.c
@@ -136,15 +136,10 @@ int
ata_pci_detach(device_t dev)
{
struct ata_pci_controller *ctlr = device_get_softc(dev);
- device_t *children;
- int nchildren, i;
/* detach & delete all children */
- if (!device_get_children(dev, &children, &nchildren)) {
- for (i = 0; i < nchildren; i++)
- device_delete_child(dev, children[i]);
- free(children, M_TEMP);
- }
+ device_delete_all_children(dev);
+
if (ctlr->r_irq) {
bus_teardown_intr(dev, ctlr->r_irq, ctlr->handle);
bus_release_resource(dev, SYS_RES_IRQ, ctlr->r_irq_rid, ctlr->r_irq);
diff --git a/sys/dev/gpio/gpiobus.c b/sys/dev/gpio/gpiobus.c
index d973694..54644a2 100644
--- a/sys/dev/gpio/gpiobus.c
+++ b/sys/dev/gpio/gpiobus.c
@@ -219,8 +219,7 @@ static int
gpiobus_detach(device_t dev)
{
struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev);
- int err, ndevs, i;
- device_t *devlist;
+ int err;
KASSERT(mtx_initialized(&sc->sc_mtx),
("gpiobus mutex not initialized"));
@@ -228,16 +227,14 @@ gpiobus_detach(device_t dev)
if ((err = bus_generic_detach(dev)) != 0)
return (err);
- if ((err = device_get_children(dev, &devlist, &ndevs)) != 0)
- return (err);
- for (i = 0; i < ndevs; i++)
- device_delete_child(dev, devlist[i]);
+
+ /* detach and delete all children */
+ device_delete_all_children(dev);
if (sc->sc_pins_mapped) {
free(sc->sc_pins_mapped, M_DEVBUF);
sc->sc_pins_mapped = NULL;
}
- free(devlist, M_TEMP);
return (0);
}
diff --git a/sys/dev/mvs/mvs_pci.c b/sys/dev/mvs/mvs_pci.c
index e2e37da..36dd93d 100644
--- a/sys/dev/mvs/mvs_pci.c
+++ b/sys/dev/mvs/mvs_pci.c
@@ -177,15 +177,10 @@ static int
mvs_detach(device_t dev)
{
struct mvs_controller *ctlr = device_get_softc(dev);
- device_t *children;
- int nchildren, i;
/* Detach & delete all children */
- if (!device_get_children(dev, &children, &nchildren)) {
- for (i = 0; i < nchildren; i++)
- device_delete_child(dev, children[i]);
- free(children, M_TEMP);
- }
+ device_delete_all_children(dev);
+
/* Free interrupt. */
if (ctlr->irq.r_irq) {
bus_teardown_intr(dev, ctlr->irq.r_irq,
diff --git a/sys/dev/mvs/mvs_soc.c b/sys/dev/mvs/mvs_soc.c
index 5c1116c..670bfec 100644
--- a/sys/dev/mvs/mvs_soc.c
+++ b/sys/dev/mvs/mvs_soc.c
@@ -173,15 +173,10 @@ static int
mvs_detach(device_t dev)
{
struct mvs_controller *ctlr = device_get_softc(dev);
- device_t *children;
- int nchildren, i;
/* Detach & delete all children */
- if (!device_get_children(dev, &children, &nchildren)) {
- for (i = 0; i < nchildren; i++)
- device_delete_child(dev, children[i]);
- free(children, M_TEMP);
- }
+ device_delete_all_children(dev);
+
/* Free interrupt. */
if (ctlr->irq.r_irq) {
bus_teardown_intr(dev, ctlr->irq.r_irq,
diff --git a/sys/dev/ppbus/ppbconf.c b/sys/dev/ppbus/ppbconf.c
index 9e21c67..858e5b2 100644
--- a/sys/dev/ppbus/ppbconf.c
+++ b/sys/dev/ppbus/ppbconf.c
@@ -422,20 +422,14 @@ ppbus_attach(device_t dev)
static int
ppbus_detach(device_t dev)
{
- device_t *children;
- int error, nchildren, i;
+ int error;
error = bus_generic_detach(dev);
if (error)
return (error);
/* detach & delete all children */
- if (!device_get_children(dev, &children, &nchildren)) {
- for (i = 0; i < nchildren; i++)
- if (children[i])
- device_delete_child(dev, children[i]);
- free(children, M_TEMP);
- }
+ device_delete_all_children(dev);
return (0);
}
diff --git a/sys/dev/ppc/ppc.c b/sys/dev/ppc/ppc.c
index 1322a33..ef505d8 100644
--- a/sys/dev/ppc/ppc.c
+++ b/sys/dev/ppc/ppc.c
@@ -1851,20 +1851,13 @@ int
ppc_detach(device_t dev)
{
struct ppc_data *ppc = DEVTOSOFTC(dev);
- device_t *children;
- int nchildren, i;
if (ppc->res_irq == 0) {
return (ENXIO);
}
/* detach & delete all children */
- if (!device_get_children(dev, &children, &nchildren)) {
- for (i = 0; i < nchildren; i++)
- if (children[i])
- device_delete_child(dev, children[i]);
- free(children, M_TEMP);
- }
+ device_delete_all_children(dev);
if (ppc->res_irq != 0) {
bus_teardown_intr(dev, ppc->res_irq, ppc->intr_cookie);
diff --git a/sys/dev/siba/siba_core.c b/sys/dev/siba/siba_core.c
index 2b1a84f..61652ad 100644
--- a/sys/dev/siba/siba_core.c
+++ b/sys/dev/siba/siba_core.c
@@ -214,16 +214,8 @@ siba_core_attach(struct siba_softc *siba)
int
siba_core_detach(struct siba_softc *siba)
{
- device_t *devlistp;
- int devcnt, error = 0, i;
-
- error = device_get_children(siba->siba_dev, &devlistp, &devcnt);
- if (error != 0)
- return (0);
-
- for ( i = 0 ; i < devcnt ; i++)
- device_delete_child(siba->siba_dev, devlistp[i]);
- free(devlistp, M_TEMP);
+ /* detach & delete all children */
+ device_delete_all_children(siba->siba_dev);
return (0);
}
diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c
index 97b2489..40c17cb 100644
--- a/sys/dev/siis/siis.c
+++ b/sys/dev/siis/siis.c
@@ -205,15 +205,10 @@ static int
siis_detach(device_t dev)
{
struct siis_controller *ctlr = device_get_softc(dev);
- device_t *children;
- int nchildren, i;
/* Detach & delete all children */
- if (!device_get_children(dev, &children, &nchildren)) {
- for (i = 0; i < nchildren; i++)
- device_delete_child(dev, children[i]);
- free(children, M_TEMP);
- }
+ device_delete_all_children(dev);
+
/* Free interrupts. */
if (ctlr->irq.r_irq) {
bus_teardown_intr(dev, ctlr->irq.r_irq,
diff --git a/sys/dev/usb/usb_util.c b/sys/dev/usb/usb_util.c
index 1c357a3..a9b1d6f 100644
--- a/sys/dev/usb/usb_util.c
+++ b/sys/dev/usb/usb_util.c
@@ -58,31 +58,6 @@
#include <dev/usb/usb_bus.h>
/*------------------------------------------------------------------------*
- * device_delete_all_children - delete all children of a device
- *------------------------------------------------------------------------*/
-#ifndef device_delete_all_children
-int
-device_delete_all_children(device_t dev)
-{
- device_t *devlist;
- int devcount;
- int error;
-
- error = device_get_children(dev, &devlist, &devcount);
- if (error == 0) {
- while (devcount-- > 0) {
- error = device_delete_child(dev, devlist[devcount]);
- if (error) {
- break;
- }
- }
- free(devlist, M_TEMP);
- }
- return (error);
-}
-#endif
-
-/*------------------------------------------------------------------------*
* device_set_usb_desc
*
* This function can be called at probe or attach to set the USB
diff --git a/sys/dev/usb/usb_util.h b/sys/dev/usb/usb_util.h
index 35abedd..7e52404 100644
--- a/sys/dev/usb/usb_util.h
+++ b/sys/dev/usb/usb_util.h
@@ -27,7 +27,6 @@
#ifndef _USB_UTIL_H_
#define _USB_UTIL_H_
-int device_delete_all_children(device_t dev);
uint8_t usb_make_str_desc(void *ptr, uint16_t max_len, const char *s);
void usb_printbcd(char *p, uint16_t p_len, uint16_t bcd);
void usb_trim_spaces(char *p);
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
index 4a36a8b..c337c78 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -1881,6 +1881,39 @@ device_delete_child(device_t dev, device_t child)
}
/**
+ * @brief Delete all children devices of the given device, if any.
+ *
+ * This function deletes all children devices of the given device, if
+ * any, using the device_delete_child() function for each device it
+ * finds. If a child device cannot be deleted, this function will
+ * return an error code.
+ *
+ * @param dev the parent device
+ *
+ * @retval 0 success
+ * @retval non-zero a device would not detach
+ */
+int
+device_delete_all_children(device_t dev)
+{
+ device_t child;
+ int error;
+
+ PDEBUG(("Deleting all children of %s", DEVICENAME(dev)));
+
+ error = 0;
+
+ while ( (child = TAILQ_FIRST(&dev->children)) ) {
+ error = device_delete_child(dev, child);
+ if (error) {
+ PDEBUG(("Failed deleting %s", DEVICENAME(child)));
+ break;
+ }
+ }
+ return (error);
+}
+
+/**
* @brief Find a device given a unit number
*
* This is similar to devclass_get_devices() but only searches for
diff --git a/sys/sys/bus.h b/sys/sys/bus.h
index 5dc92df..25dcbce 100644
--- a/sys/sys/bus.h
+++ b/sys/sys/bus.h
@@ -424,6 +424,7 @@ device_t device_add_child_ordered(device_t dev, u_int order,
const char *name, int unit);
void device_busy(device_t dev);
int device_delete_child(device_t dev, device_t child);
+int device_delete_all_children(device_t dev);
int device_attach(device_t dev);
int device_detach(device_t dev);
void device_disable(device_t dev);
OpenPOWER on IntegriCloud