Move the device_delete_all_children() function from usb_util.c

to kern/subr_bus.c. Simplify this function so that it no longer
depends on malloc() to execute. Identify a few other places where
it makes sense to use device_delete_all_children().

MFC after:	1 week
This commit is contained in:
Hans Petter Selasky 2011-11-19 10:11:50 +00:00
parent 76a869385c
commit 11bcf702f4
15 changed files with 56 additions and 109 deletions

View File

@ -259,17 +259,11 @@ static int
ata_avila_detach(device_t dev) ata_avila_detach(device_t dev)
{ {
struct ata_avila_softc *sc = device_get_softc(dev); struct ata_avila_softc *sc = device_get_softc(dev);
device_t *children;
int nc;
/* XXX quiesce gpio? */ /* XXX quiesce gpio? */
/* detach & delete all children */ /* detach & delete all children */
if (device_get_children(dev, &children, &nc) == 0) { device_delete_all_children(dev);
if (nc > 0)
device_delete_child(dev, children[0]);
free(children, M_TEMP);
}
bus_teardown_intr(dev, sc->sc_irq, sc->sc_ih); bus_teardown_intr(dev, sc->sc_irq, sc->sc_ih);
bus_release_resource(dev, SYS_RES_IRQ, sc->sc_rid, sc->sc_irq); bus_release_resource(dev, SYS_RES_IRQ, sc->sc_rid, sc->sc_irq);

View File

@ -515,15 +515,11 @@ static int
ahci_detach(device_t dev) ahci_detach(device_t dev)
{ {
struct ahci_controller *ctlr = device_get_softc(dev); struct ahci_controller *ctlr = device_get_softc(dev);
device_t *children; int i;
int nchildren, i;
/* Detach & delete all children */ /* Detach & delete all children */
if (!device_get_children(dev, &children, &nchildren)) { device_delete_all_children(dev);
for (i = 0; i < nchildren; i++)
device_delete_child(dev, children[i]);
free(children, M_TEMP);
}
/* Free interrupts. */ /* Free interrupts. */
for (i = 0; i < ctlr->numirqs; i++) { for (i = 0; i < ctlr->numirqs; i++) {
if (ctlr->irqs[i].r_irq) { if (ctlr->irqs[i].r_irq) {

View File

@ -172,8 +172,6 @@ ad_detach(device_t dev)
{ {
struct ad_softc *adp = device_get_ivars(dev); struct ad_softc *adp = device_get_ivars(dev);
struct ata_device *atadev = device_get_softc(dev); struct ata_device *atadev = device_get_softc(dev);
device_t *children;
int nchildren, i;
/* check that we have a valid disk to detach */ /* check that we have a valid disk to detach */
if (!device_get_ivars(dev)) if (!device_get_ivars(dev))
@ -183,12 +181,7 @@ ad_detach(device_t dev)
callout_drain(&atadev->spindown_timer); callout_drain(&atadev->spindown_timer);
/* detach & delete all children */ /* detach & delete all children */
if (!device_get_children(dev, &children, &nchildren)) { device_delete_all_children(dev);
for (i = 0; i < nchildren; i++)
if (children[i])
device_delete_child(dev, children[i]);
free(children, M_TEMP);
}
/* destroy disk from the system so we don't get any further requests */ /* destroy disk from the system so we don't get any further requests */
disk_destroy(adp->disk); disk_destroy(adp->disk);

View File

@ -136,15 +136,10 @@ int
ata_pci_detach(device_t dev) ata_pci_detach(device_t dev)
{ {
struct ata_pci_controller *ctlr = device_get_softc(dev); struct ata_pci_controller *ctlr = device_get_softc(dev);
device_t *children;
int nchildren, i;
/* detach & delete all children */ /* detach & delete all children */
if (!device_get_children(dev, &children, &nchildren)) { device_delete_all_children(dev);
for (i = 0; i < nchildren; i++)
device_delete_child(dev, children[i]);
free(children, M_TEMP);
}
if (ctlr->r_irq) { if (ctlr->r_irq) {
bus_teardown_intr(dev, ctlr->r_irq, ctlr->handle); bus_teardown_intr(dev, ctlr->r_irq, ctlr->handle);
bus_release_resource(dev, SYS_RES_IRQ, ctlr->r_irq_rid, ctlr->r_irq); bus_release_resource(dev, SYS_RES_IRQ, ctlr->r_irq_rid, ctlr->r_irq);

View File

@ -219,8 +219,7 @@ static int
gpiobus_detach(device_t dev) gpiobus_detach(device_t dev)
{ {
struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev); struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev);
int err, ndevs, i; int err;
device_t *devlist;
KASSERT(mtx_initialized(&sc->sc_mtx), KASSERT(mtx_initialized(&sc->sc_mtx),
("gpiobus mutex not initialized")); ("gpiobus mutex not initialized"));
@ -228,16 +227,14 @@ gpiobus_detach(device_t dev)
if ((err = bus_generic_detach(dev)) != 0) if ((err = bus_generic_detach(dev)) != 0)
return (err); return (err);
if ((err = device_get_children(dev, &devlist, &ndevs)) != 0)
return (err); /* detach and delete all children */
for (i = 0; i < ndevs; i++) device_delete_all_children(dev);
device_delete_child(dev, devlist[i]);
if (sc->sc_pins_mapped) { if (sc->sc_pins_mapped) {
free(sc->sc_pins_mapped, M_DEVBUF); free(sc->sc_pins_mapped, M_DEVBUF);
sc->sc_pins_mapped = NULL; sc->sc_pins_mapped = NULL;
} }
free(devlist, M_TEMP);
return (0); return (0);
} }

View File

@ -177,15 +177,10 @@ static int
mvs_detach(device_t dev) mvs_detach(device_t dev)
{ {
struct mvs_controller *ctlr = device_get_softc(dev); struct mvs_controller *ctlr = device_get_softc(dev);
device_t *children;
int nchildren, i;
/* Detach & delete all children */ /* Detach & delete all children */
if (!device_get_children(dev, &children, &nchildren)) { device_delete_all_children(dev);
for (i = 0; i < nchildren; i++)
device_delete_child(dev, children[i]);
free(children, M_TEMP);
}
/* Free interrupt. */ /* Free interrupt. */
if (ctlr->irq.r_irq) { if (ctlr->irq.r_irq) {
bus_teardown_intr(dev, ctlr->irq.r_irq, bus_teardown_intr(dev, ctlr->irq.r_irq,

View File

@ -173,15 +173,10 @@ static int
mvs_detach(device_t dev) mvs_detach(device_t dev)
{ {
struct mvs_controller *ctlr = device_get_softc(dev); struct mvs_controller *ctlr = device_get_softc(dev);
device_t *children;
int nchildren, i;
/* Detach & delete all children */ /* Detach & delete all children */
if (!device_get_children(dev, &children, &nchildren)) { device_delete_all_children(dev);
for (i = 0; i < nchildren; i++)
device_delete_child(dev, children[i]);
free(children, M_TEMP);
}
/* Free interrupt. */ /* Free interrupt. */
if (ctlr->irq.r_irq) { if (ctlr->irq.r_irq) {
bus_teardown_intr(dev, ctlr->irq.r_irq, bus_teardown_intr(dev, ctlr->irq.r_irq,

View File

@ -422,20 +422,14 @@ ppbus_attach(device_t dev)
static int static int
ppbus_detach(device_t dev) ppbus_detach(device_t dev)
{ {
device_t *children; int error;
int error, nchildren, i;
error = bus_generic_detach(dev); error = bus_generic_detach(dev);
if (error) if (error)
return (error); return (error);
/* detach & delete all children */ /* detach & delete all children */
if (!device_get_children(dev, &children, &nchildren)) { device_delete_all_children(dev);
for (i = 0; i < nchildren; i++)
if (children[i])
device_delete_child(dev, children[i]);
free(children, M_TEMP);
}
return (0); return (0);
} }

View File

@ -1851,20 +1851,13 @@ int
ppc_detach(device_t dev) ppc_detach(device_t dev)
{ {
struct ppc_data *ppc = DEVTOSOFTC(dev); struct ppc_data *ppc = DEVTOSOFTC(dev);
device_t *children;
int nchildren, i;
if (ppc->res_irq == 0) { if (ppc->res_irq == 0) {
return (ENXIO); return (ENXIO);
} }
/* detach & delete all children */ /* detach & delete all children */
if (!device_get_children(dev, &children, &nchildren)) { device_delete_all_children(dev);
for (i = 0; i < nchildren; i++)
if (children[i])
device_delete_child(dev, children[i]);
free(children, M_TEMP);
}
if (ppc->res_irq != 0) { if (ppc->res_irq != 0) {
bus_teardown_intr(dev, ppc->res_irq, ppc->intr_cookie); bus_teardown_intr(dev, ppc->res_irq, ppc->intr_cookie);

View File

@ -214,16 +214,8 @@ siba_core_attach(struct siba_softc *siba)
int int
siba_core_detach(struct siba_softc *siba) siba_core_detach(struct siba_softc *siba)
{ {
device_t *devlistp; /* detach & delete all children */
int devcnt, error = 0, i; device_delete_all_children(siba->siba_dev);
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);
return (0); return (0);
} }

View File

@ -205,15 +205,10 @@ static int
siis_detach(device_t dev) siis_detach(device_t dev)
{ {
struct siis_controller *ctlr = device_get_softc(dev); struct siis_controller *ctlr = device_get_softc(dev);
device_t *children;
int nchildren, i;
/* Detach & delete all children */ /* Detach & delete all children */
if (!device_get_children(dev, &children, &nchildren)) { device_delete_all_children(dev);
for (i = 0; i < nchildren; i++)
device_delete_child(dev, children[i]);
free(children, M_TEMP);
}
/* Free interrupts. */ /* Free interrupts. */
if (ctlr->irq.r_irq) { if (ctlr->irq.r_irq) {
bus_teardown_intr(dev, ctlr->irq.r_irq, bus_teardown_intr(dev, ctlr->irq.r_irq,

View File

@ -57,31 +57,6 @@
#include <dev/usb/usb_controller.h> #include <dev/usb/usb_controller.h>
#include <dev/usb/usb_bus.h> #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 * device_set_usb_desc
* *

View File

@ -27,7 +27,6 @@
#ifndef _USB_UTIL_H_ #ifndef _USB_UTIL_H_
#define _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); 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_printbcd(char *p, uint16_t p_len, uint16_t bcd);
void usb_trim_spaces(char *p); void usb_trim_spaces(char *p);

View File

@ -1880,6 +1880,39 @@ device_delete_child(device_t dev, device_t child)
return (0); return (0);
} }
/**
* @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 * @brief Find a device given a unit number
* *

View File

@ -424,6 +424,7 @@ device_t device_add_child_ordered(device_t dev, u_int order,
const char *name, int unit); const char *name, int unit);
void device_busy(device_t dev); void device_busy(device_t dev);
int device_delete_child(device_t dev, device_t child); 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_attach(device_t dev);
int device_detach(device_t dev); int device_detach(device_t dev);
void device_disable(device_t dev); void device_disable(device_t dev);