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:
parent
76a869385c
commit
11bcf702f4
@ -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);
|
||||||
|
@ -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) {
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
*
|
*
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
*
|
*
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user