aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2025-01-02 18:21:02 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2025-01-02 18:21:30 +0000
commitb196276c20b577b364372f1aa1a646b9ce34bf5c (patch)
tree7cd0937a7495a49e682531df1bffb49e6aed48ad
parent28f5e880e8b28d77cf1a4eb6ce2a766d3c5a3926 (diff)
bus_generic_detach: Delete children after detaching them
This provides better semantics as a standalone DEVMETHOD for device_attach as bus drivers should remove child devices they created as part of detach cleanup. The implementation calls bus_detach_children() first to permit child devices an opportunity to veto the detach operation. If that succeeds, device_delete_children() is used to delete the child devices. This requires fixing various drivers that were deleting devices explicitly (via a device_t pointer cached in the softc) after calling bus_generic_detach to stop doing that and just rely on bus_generic_detach to remove child devices. Reviewed by: imp Differential Revision: https://reviews.freebsd.org/D47959
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_bsc.c2
-rw-r--r--sys/arm/freescale/imx/imx_i2c.c3
-rw-r--r--sys/arm/freescale/imx/imx_spi.c3
-rw-r--r--sys/arm/mv/a37x0_iic.c2
-rw-r--r--sys/arm/nvidia/tegra_i2c.c2
-rw-r--r--sys/arm/ti/am335x/am335x_ehrpwm.c3
-rw-r--r--sys/arm/ti/cpsw/if_cpsw.c10
-rw-r--r--sys/arm/ti/ti_i2c.c4
-rw-r--r--sys/arm/xilinx/zy7_qspi.c4
-rw-r--r--sys/arm/xilinx/zy7_spi.c4
-rw-r--r--sys/dev/bce/if_bce.c1
-rw-r--r--sys/dev/bfe/if_bfe.c2
-rw-r--r--sys/dev/bge/if_bge.c1
-rw-r--r--sys/dev/bhnd/bhndb/bhndb.c4
-rw-r--r--sys/dev/bhnd/cores/chipc/chipc.c3
-rw-r--r--sys/dev/cxgbe/t4_main.c2
-rw-r--r--sys/dev/dpaa2/dpaa2_mc.c2
-rw-r--r--sys/dev/etherswitch/felix/felix.c2
-rw-r--r--sys/dev/firewire/fwohci_pci.c5
-rw-r--r--sys/dev/glxiic/glxiic.c7
-rw-r--r--sys/dev/ichiic/ig4_iic.c10
-rw-r--r--sys/dev/ichsmb/ichsmb.c1
-rw-r--r--sys/dev/iicbus/controller/cadence/cdnc_i2c.c7
-rw-r--r--sys/dev/iicbus/controller/rockchip/rk_i2c.c4
-rw-r--r--sys/dev/iicbus/controller/twsi/twsi.c4
-rw-r--r--sys/dev/iicbus/controller/vybrid/vf_i2c.c6
-rw-r--r--sys/dev/ismt/ismt.c2
-rw-r--r--sys/dev/lge/if_lge.c1
-rw-r--r--sys/dev/ow/ow.c13
-rw-r--r--sys/dev/pcf/pcf_isa.c3
-rw-r--r--sys/dev/pwm/controller/allwinner/aw_pwm.c3
-rw-r--r--sys/dev/qcom_qup/qcom_spi.c2
-rw-r--r--sys/dev/smbus/smbus.c1
-rw-r--r--sys/dev/sound/pci/fm801.c6
-rw-r--r--sys/dev/spibus/controller/allwinner/aw_spi.c2
-rw-r--r--sys/dev/spibus/controller/rockchip/rk_spi.c2
-rw-r--r--sys/dev/viapm/viapm.c6
-rw-r--r--sys/dev/vnic/thunder_mdio.c1
-rw-r--r--sys/kern/subr_bus.c11
-rw-r--r--sys/sys/param.h2
40 files changed, 19 insertions, 134 deletions
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_bsc.c b/sys/arm/broadcom/bcm2835/bcm2835_bsc.c
index c7de4df0e8fb..a4cbef7d528f 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_bsc.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_bsc.c
@@ -361,8 +361,6 @@ bcm_bsc_detach(device_t dev)
bus_generic_detach(dev);
sc = device_get_softc(dev);
- if (sc->sc_iicbus != NULL)
- device_delete_child(dev, sc->sc_iicbus);
mtx_destroy(&sc->sc_mtx);
if (sc->sc_intrhand)
bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intrhand);
diff --git a/sys/arm/freescale/imx/imx_i2c.c b/sys/arm/freescale/imx/imx_i2c.c
index c1d5c8c974a8..3190ec294ab4 100644
--- a/sys/arm/freescale/imx/imx_i2c.c
+++ b/sys/arm/freescale/imx/imx_i2c.c
@@ -494,9 +494,6 @@ i2c_detach(device_t dev)
return (error);
}
- if (sc->iicbus != NULL)
- device_delete_child(dev, sc->iicbus);
-
/* Release bus-recover pins; gpio_pin_release() handles NULL args. */
gpio_pin_release(sc->rb_sclpin);
gpio_pin_release(sc->rb_sdapin);
diff --git a/sys/arm/freescale/imx/imx_spi.c b/sys/arm/freescale/imx/imx_spi.c
index 53d9f739b97c..dac42a800e9e 100644
--- a/sys/arm/freescale/imx/imx_spi.c
+++ b/sys/arm/freescale/imx/imx_spi.c
@@ -473,9 +473,6 @@ spi_detach(device_t dev)
if ((error = bus_generic_detach(sc->dev)) != 0)
return (error);
- if (sc->spibus != NULL)
- device_delete_child(dev, sc->spibus);
-
for (idx = 0; idx < nitems(sc->cspins); ++idx) {
if (sc->cspins[idx] != NULL)
gpio_pin_release(sc->cspins[idx]);
diff --git a/sys/arm/mv/a37x0_iic.c b/sys/arm/mv/a37x0_iic.c
index f9a71b97240a..7d71cac23a40 100644
--- a/sys/arm/mv/a37x0_iic.c
+++ b/sys/arm/mv/a37x0_iic.c
@@ -249,8 +249,6 @@ a37x0_iic_detach(device_t dev)
bus_generic_detach(dev);
sc = device_get_softc(dev);
- if (sc->sc_iicbus != NULL)
- device_delete_child(dev, sc->sc_iicbus);
mtx_destroy(&sc->sc_mtx);
if (sc->sc_intrhand)
bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intrhand);
diff --git a/sys/arm/nvidia/tegra_i2c.c b/sys/arm/nvidia/tegra_i2c.c
index bed1bf0ed7e3..6c4d20cb78ff 100644
--- a/sys/arm/nvidia/tegra_i2c.c
+++ b/sys/arm/nvidia/tegra_i2c.c
@@ -757,8 +757,6 @@ tegra_i2c_detach(device_t dev)
bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res);
LOCK_DESTROY(sc);
- if (sc->iicbus)
- device_delete_child(dev, sc->iicbus);
return (0);
}
diff --git a/sys/arm/ti/am335x/am335x_ehrpwm.c b/sys/arm/ti/am335x/am335x_ehrpwm.c
index 95301f9cfed3..59ef0931439d 100644
--- a/sys/arm/ti/am335x/am335x_ehrpwm.c
+++ b/sys/arm/ti/am335x/am335x_ehrpwm.c
@@ -542,9 +542,6 @@ am335x_ehrpwm_detach(device_t dev)
PWM_LOCK(sc);
- if (sc->sc_busdev != NULL)
- device_delete_child(dev, sc->sc_busdev);
-
if (sc->sc_mem_res)
bus_release_resource(dev, SYS_RES_MEMORY,
sc->sc_mem_rid, sc->sc_mem_res);
diff --git a/sys/arm/ti/cpsw/if_cpsw.c b/sys/arm/ti/cpsw/if_cpsw.c
index 732b5a81857a..674a7ed8575a 100644
--- a/sys/arm/ti/cpsw/if_cpsw.c
+++ b/sys/arm/ti/cpsw/if_cpsw.c
@@ -923,13 +923,11 @@ cpsw_detach(device_t dev)
struct cpsw_softc *sc;
int error, i;
- bus_generic_detach(dev);
- sc = device_get_softc(dev);
+ error = bus_generic_detach(dev);
+ if (error != 0)
+ return (error);
- for (i = 0; i < CPSW_PORTS; i++) {
- if (sc->port[i].dev)
- device_delete_child(dev, sc->port[i].dev);
- }
+ sc = device_get_softc(dev);
if (device_is_attached(dev)) {
callout_stop(&sc->watchdog.callout);
diff --git a/sys/arm/ti/ti_i2c.c b/sys/arm/ti/ti_i2c.c
index a6c397a87e8b..e2f114505015 100644
--- a/sys/arm/ti/ti_i2c.c
+++ b/sys/arm/ti/ti_i2c.c
@@ -913,10 +913,6 @@ ti_i2c_detach(device_t dev)
return (rv);
}
- if (sc->sc_iicbus &&
- (rv = device_delete_child(dev, sc->sc_iicbus)) != 0)
- return (rv);
-
ti_i2c_deactivate(dev);
TI_I2C_LOCK_DESTROY(sc);
diff --git a/sys/arm/xilinx/zy7_qspi.c b/sys/arm/xilinx/zy7_qspi.c
index c033fd29a7db..53559571f7db 100644
--- a/sys/arm/xilinx/zy7_qspi.c
+++ b/sys/arm/xilinx/zy7_qspi.c
@@ -616,10 +616,6 @@ zy7_qspi_detach(device_t dev)
if (device_is_attached(dev))
bus_generic_detach(dev);
- /* Delete child bus. */
- if (sc->child)
- device_delete_child(dev, sc->child);
-
/* Disable hardware. */
if (sc->mem_res != NULL) {
/* Disable SPI. */
diff --git a/sys/arm/xilinx/zy7_spi.c b/sys/arm/xilinx/zy7_spi.c
index a24ce542a860..d032deabf8b7 100644
--- a/sys/arm/xilinx/zy7_spi.c
+++ b/sys/arm/xilinx/zy7_spi.c
@@ -452,10 +452,6 @@ zy7_spi_detach(device_t dev)
if (device_is_attached(dev))
bus_generic_detach(dev);
- /* Delete child bus. */
- if (sc->child)
- device_delete_child(dev, sc->child);
-
/* Disable hardware. */
if (sc->mem_res != NULL) {
/* Disable SPI. */
diff --git a/sys/dev/bce/if_bce.c b/sys/dev/bce/if_bce.c
index 226fca16ac28..73af49015e52 100644
--- a/sys/dev/bce/if_bce.c
+++ b/sys/dev/bce/if_bce.c
@@ -1544,7 +1544,6 @@ bce_detach(device_t dev)
ifmedia_removeall(&sc->bce_ifmedia);
else {
bus_generic_detach(dev);
- device_delete_child(dev, sc->bce_miibus);
}
/* Release all remaining resources. */
diff --git a/sys/dev/bfe/if_bfe.c b/sys/dev/bfe/if_bfe.c
index 817c867862d0..2fb6938fbdc5 100644
--- a/sys/dev/bfe/if_bfe.c
+++ b/sys/dev/bfe/if_bfe.c
@@ -551,8 +551,6 @@ bfe_detach(device_t dev)
BFE_UNLOCK(sc);
bus_generic_detach(dev);
- if (sc->bfe_miibus != NULL)
- device_delete_child(dev, sc->bfe_miibus);
bfe_release_resources(sc);
bfe_dma_free(sc);
diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
index 6c3301b1473a..cf3084f9b768 100644
--- a/sys/dev/bge/if_bge.c
+++ b/sys/dev/bge/if_bge.c
@@ -3949,7 +3949,6 @@ bge_detach(device_t dev)
ifmedia_removeall(&sc->bge_ifmedia);
else if (sc->bge_miibus != NULL) {
bus_generic_detach(dev);
- device_delete_child(dev, sc->bge_miibus);
}
bge_release_resources(sc);
diff --git a/sys/dev/bhnd/bhndb/bhndb.c b/sys/dev/bhnd/bhndb/bhndb.c
index 511beae0cc25..f9d56a9b9226 100644
--- a/sys/dev/bhnd/bhndb/bhndb.c
+++ b/sys/dev/bhnd/bhndb/bhndb.c
@@ -624,10 +624,6 @@ bhndb_generic_detach(device_t dev)
if ((error = bus_generic_detach(dev)))
return (error);
- /* Delete children */
- if ((error = device_delete_children(dev)))
- return (error);
-
/* Clean up our service registry */
if ((error = bhnd_service_registry_fini(&sc->services)))
return (error);
diff --git a/sys/dev/bhnd/cores/chipc/chipc.c b/sys/dev/bhnd/cores/chipc/chipc.c
index 09ca4d8884e6..24697a8f0b17 100644
--- a/sys/dev/bhnd/cores/chipc/chipc.c
+++ b/sys/dev/bhnd/cores/chipc/chipc.c
@@ -244,9 +244,6 @@ chipc_detach(device_t dev)
if ((error = bus_generic_detach(dev)))
return (error);
- if ((error = device_delete_children(dev)))
- return (error);
-
if ((error = bhnd_deregister_provider(dev, BHND_SERVICE_ANY)))
return (error);
diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c
index 755fd19a3c9c..024c97dcb78c 100644
--- a/sys/dev/cxgbe/t4_main.c
+++ b/sys/dev/cxgbe/t4_main.c
@@ -1807,8 +1807,6 @@ t4_detach_common(device_t dev)
pi = sc->port[i];
if (pi) {
t4_free_vi(sc, sc->mbox, sc->pf, 0, pi->vi[0].viid);
- if (pi->dev)
- device_delete_child(dev, pi->dev);
mtx_destroy(&pi->pi_lock);
free(pi->vi, M_CXGBE);
diff --git a/sys/dev/dpaa2/dpaa2_mc.c b/sys/dev/dpaa2/dpaa2_mc.c
index 1d0275127ced..c84b22d1d74d 100644
--- a/sys/dev/dpaa2/dpaa2_mc.c
+++ b/sys/dev/dpaa2/dpaa2_mc.c
@@ -286,8 +286,6 @@ dpaa2_mc_detach(device_t dev)
return (error);
sc = device_get_softc(dev);
- if (sc->rcdev)
- device_delete_child(dev, sc->rcdev);
bus_release_resources(dev, dpaa2_mc_spec, sc->res);
dinfo = device_get_ivars(dev);
diff --git a/sys/dev/etherswitch/felix/felix.c b/sys/dev/etherswitch/felix/felix.c
index 622cf3bca140..b6fb8cbb67c8 100644
--- a/sys/dev/etherswitch/felix/felix.c
+++ b/sys/dev/etherswitch/felix/felix.c
@@ -497,8 +497,6 @@ felix_detach(device_t dev)
felix_setup(sc);
for (i = 0; i < sc->info.es_nports; i++) {
- if (sc->ports[i].miibus != NULL)
- device_delete_child(dev, sc->ports[i].miibus);
if (sc->ports[i].ifp != NULL)
if_free(sc->ports[i].ifp);
if (sc->ports[i].ifname != NULL)
diff --git a/sys/dev/firewire/fwohci_pci.c b/sys/dev/firewire/fwohci_pci.c
index 591503728093..a6f9f50701f0 100644
--- a/sys/dev/firewire/fwohci_pci.c
+++ b/sys/dev/firewire/fwohci_pci.c
@@ -333,11 +333,6 @@ fwohci_pci_detach(device_t self)
bus_generic_detach(self);
- if (sc->fc.bdev) {
- device_delete_child(self, sc->fc.bdev);
- sc->fc.bdev = NULL;
- }
-
/* disable interrupts that might have been switched on */
if (sc->bst && sc->bsh)
bus_space_write_4(sc->bst, sc->bsh,
diff --git a/sys/dev/glxiic/glxiic.c b/sys/dev/glxiic/glxiic.c
index 5dfea9acbe4a..ddaa77b6b73c 100644
--- a/sys/dev/glxiic/glxiic.c
+++ b/sys/dev/glxiic/glxiic.c
@@ -451,11 +451,8 @@ glxiic_detach(device_t dev)
error = bus_generic_detach(dev);
if (error != 0)
- goto out;
- if (sc->iicbus != NULL)
- error = device_delete_child(dev, sc->iicbus);
+ return (error);
-out:
callout_drain(&sc->callout);
if (sc->smb_res != NULL) {
@@ -479,7 +476,7 @@ out:
GLXIIC_LOCK_DESTROY(sc);
- return (error);
+ return (0);
}
static uint8_t
diff --git a/sys/dev/ichiic/ig4_iic.c b/sys/dev/ichiic/ig4_iic.c
index 806b406af326..c9346ff12350 100644
--- a/sys/dev/ichiic/ig4_iic.c
+++ b/sys/dev/ichiic/ig4_iic.c
@@ -1080,13 +1080,9 @@ ig4iic_detach(ig4iic_softc_t *sc)
{
int error;
- if (device_is_attached(sc->dev)) {
- error = bus_generic_detach(sc->dev);
- if (error)
- return (error);
- }
- if (sc->iicbus)
- device_delete_child(sc->dev, sc->iicbus);
+ error = bus_generic_detach(sc->dev);
+ if (error)
+ return (error);
if (sc->intr_handle)
bus_teardown_intr(sc->dev, sc->intr_res, sc->intr_handle);
diff --git a/sys/dev/ichsmb/ichsmb.c b/sys/dev/ichsmb/ichsmb.c
index 063fbf66a75a..28503b9e574d 100644
--- a/sys/dev/ichsmb/ichsmb.c
+++ b/sys/dev/ichsmb/ichsmb.c
@@ -696,7 +696,6 @@ ichsmb_detach(device_t dev)
error = bus_generic_detach(dev);
if (error)
return (error);
- device_delete_child(dev, sc->smb);
ichsmb_release_resources(sc);
mtx_destroy(&sc->mutex);
diff --git a/sys/dev/iicbus/controller/cadence/cdnc_i2c.c b/sys/dev/iicbus/controller/cadence/cdnc_i2c.c
index 3bed24c36070..bf1f88ec9ca5 100644
--- a/sys/dev/iicbus/controller/cadence/cdnc_i2c.c
+++ b/sys/dev/iicbus/controller/cadence/cdnc_i2c.c
@@ -626,18 +626,13 @@ cdnc_i2c_detach(device_t dev)
{
struct cdnc_i2c_softc *sc = device_get_softc(dev);
- if (device_is_attached(dev))
- bus_generic_detach(dev);
+ bus_generic_detach(dev);
if (sc->ref_clk != NULL) {
clk_release(sc->ref_clk);
sc->ref_clk = NULL;
}
- /* Delete iic bus. */
- if (sc->iicbus)
- device_delete_child(dev, sc->iicbus);
-
/* Disable hardware. */
if (sc->mem_res != NULL) {
sc->cfg_reg_shadow = 0;
diff --git a/sys/dev/iicbus/controller/rockchip/rk_i2c.c b/sys/dev/iicbus/controller/rockchip/rk_i2c.c
index 0ef65d1121f5..9317adbcfd98 100644
--- a/sys/dev/iicbus/controller/rockchip/rk_i2c.c
+++ b/sys/dev/iicbus/controller/rockchip/rk_i2c.c
@@ -686,10 +686,6 @@ rk_i2c_detach(device_t dev)
if ((error = bus_generic_detach(dev)) != 0)
return (error);
- if (sc->iicbus != NULL)
- if ((error = device_delete_child(dev, sc->iicbus)) != 0)
- return (error);
-
if (sc->sclk != NULL)
clk_release(sc->sclk);
if (sc->pclk != NULL)
diff --git a/sys/dev/iicbus/controller/twsi/twsi.c b/sys/dev/iicbus/controller/twsi/twsi.c
index 20d39aa7d93b..b5aefbae7d7e 100644
--- a/sys/dev/iicbus/controller/twsi/twsi.c
+++ b/sys/dev/iicbus/controller/twsi/twsi.c
@@ -835,10 +835,6 @@ twsi_detach(device_t dev)
if ((rv = bus_generic_detach(dev)) != 0)
return (rv);
- if (sc->iicbus != NULL)
- if ((rv = device_delete_child(dev, sc->iicbus)) != 0)
- return (rv);
-
if (sc->intrhand != NULL)
bus_teardown_intr(sc->dev, sc->res[1], sc->intrhand);
diff --git a/sys/dev/iicbus/controller/vybrid/vf_i2c.c b/sys/dev/iicbus/controller/vybrid/vf_i2c.c
index f6d0eb4c2c59..4735a95cf5cd 100644
--- a/sys/dev/iicbus/controller/vybrid/vf_i2c.c
+++ b/sys/dev/iicbus/controller/vybrid/vf_i2c.c
@@ -213,12 +213,6 @@ i2c_detach(device_t dev)
return (error);
}
- error = device_delete_child(dev, sc->iicbus);
- if (error != 0) {
- device_printf(dev, "could not delete iicbus child.\n");
- return (error);
- }
-
mtx_lock(&sc->mutex);
if (sc->freq == 0) {
diff --git a/sys/dev/ismt/ismt.c b/sys/dev/ismt/ismt.c
index 650353c75e9f..4aea93d1f435 100644
--- a/sys/dev/ismt/ismt.c
+++ b/sys/dev/ismt/ismt.c
@@ -532,8 +532,6 @@ ismt_detach(device_t dev)
if (error)
return (error);
- device_delete_child(dev, sc->smbdev);
-
if (sc->intr_handle != NULL) {
bus_teardown_intr(dev, sc->intr_res, sc->intr_handle);
sc->intr_handle = NULL;
diff --git a/sys/dev/lge/if_lge.c b/sys/dev/lge/if_lge.c
index 7542b17e19eb..c5cfafc0bd22 100644
--- a/sys/dev/lge/if_lge.c
+++ b/sys/dev/lge/if_lge.c
@@ -583,7 +583,6 @@ lge_detach(device_t dev)
ether_ifdetach(ifp);
bus_generic_detach(dev);
- device_delete_child(dev, sc->lge_miibus);
bus_teardown_intr(dev, sc->lge_irq, sc->lge_intrhand);
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->lge_irq);
diff --git a/sys/dev/ow/ow.c b/sys/dev/ow/ow.c
index 9cbd05cd88b1..0325e6b324c8 100644
--- a/sys/dev/ow/ow.c
+++ b/sys/dev/ow/ow.c
@@ -565,8 +565,6 @@ ow_attach(device_t ndev)
static int
ow_detach(device_t ndev)
{
- device_t *children, child;
- int nkid, i;
struct ow_softc *sc;
sc = device_get_softc(ndev);
@@ -576,17 +574,6 @@ ow_detach(device_t ndev)
*/
bus_generic_detach(ndev);
- /*
- * We delete all the children, and free up the ivars
- */
- if (device_get_children(ndev, &children, &nkid) != 0)
- return ENOMEM;
- for (i = 0; i < nkid; i++) {
- child = children[i];
- device_delete_child(ndev, child);
- }
- free(children, M_TEMP);
-
OW_LOCK_DESTROY(sc);
return 0;
}
diff --git a/sys/dev/pcf/pcf_isa.c b/sys/dev/pcf/pcf_isa.c
index 190554258c3a..f86caed87e6a 100644
--- a/sys/dev/pcf/pcf_isa.c
+++ b/sys/dev/pcf/pcf_isa.c
@@ -192,9 +192,6 @@ pcf_isa_detach(device_t dev)
if ((rv = bus_generic_detach(dev)) != 0)
return (rv);
- if ((rv = device_delete_child(dev, sc->iicbus)) != 0)
- return (rv);
-
if (sc->res_irq != 0) {
bus_teardown_intr(dev, sc->res_irq, sc->intr_cookie);
bus_release_resource(dev, SYS_RES_IRQ, sc->rid_irq, sc->res_irq);
diff --git a/sys/dev/pwm/controller/allwinner/aw_pwm.c b/sys/dev/pwm/controller/allwinner/aw_pwm.c
index 0f505957bb1a..117f3ae17e1b 100644
--- a/sys/dev/pwm/controller/allwinner/aw_pwm.c
+++ b/sys/dev/pwm/controller/allwinner/aw_pwm.c
@@ -211,9 +211,6 @@ aw_pwm_detach(device_t dev)
return (error);
}
- if (sc->busdev != NULL)
- device_delete_child(dev, sc->busdev);
-
if (sc->res != NULL)
bus_release_resources(dev, aw_pwm_spec, &sc->res);
diff --git a/sys/dev/qcom_qup/qcom_spi.c b/sys/dev/qcom_qup/qcom_spi.c
index d3f38dee041f..88341b4d2083 100644
--- a/sys/dev/qcom_qup/qcom_spi.c
+++ b/sys/dev/qcom_qup/qcom_spi.c
@@ -840,8 +840,6 @@ qcom_spi_detach(device_t dev)
int i;
bus_generic_detach(sc->sc_dev);
- if (sc->spibus != NULL)
- device_delete_child(dev, sc->spibus);
if (sc->sc_irq_h)
bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_irq_h);
diff --git a/sys/dev/smbus/smbus.c b/sys/dev/smbus/smbus.c
index 28d1a16e8c96..9a37c482654b 100644
--- a/sys/dev/smbus/smbus.c
+++ b/sys/dev/smbus/smbus.c
@@ -83,7 +83,6 @@ smbus_detach(device_t dev)
error = bus_generic_detach(dev);
if (error)
return (error);
- device_delete_children(dev);
mtx_destroy(&sc->lock);
return (0);
diff --git a/sys/dev/sound/pci/fm801.c b/sys/dev/sound/pci/fm801.c
index 72a476708aa7..3537c7807ded 100644
--- a/sys/dev/sound/pci/fm801.c
+++ b/sys/dev/sound/pci/fm801.c
@@ -676,12 +676,6 @@ fm801_pci_detach(device_t dev)
r = bus_generic_detach(dev);
if (r)
return r;
- if (fm801->radio != NULL) {
- r = device_delete_child(dev, fm801->radio);
- if (r)
- return r;
- fm801->radio = NULL;
- }
r = pcm_unregister(dev);
if (r)
diff --git a/sys/dev/spibus/controller/allwinner/aw_spi.c b/sys/dev/spibus/controller/allwinner/aw_spi.c
index e17152b054d7..34461ab2ba9c 100644
--- a/sys/dev/spibus/controller/allwinner/aw_spi.c
+++ b/sys/dev/spibus/controller/allwinner/aw_spi.c
@@ -253,8 +253,6 @@ aw_spi_detach(device_t dev)
sc = device_get_softc(dev);
bus_generic_detach(sc->dev);
- if (sc->spibus != NULL)
- device_delete_child(dev, sc->spibus);
if (sc->clk_mod != NULL)
clk_release(sc->clk_mod);
diff --git a/sys/dev/spibus/controller/rockchip/rk_spi.c b/sys/dev/spibus/controller/rockchip/rk_spi.c
index 2c8093c6dc82..db650763f6e1 100644
--- a/sys/dev/spibus/controller/rockchip/rk_spi.c
+++ b/sys/dev/spibus/controller/rockchip/rk_spi.c
@@ -354,8 +354,6 @@ rk_spi_detach(device_t dev)
sc = device_get_softc(dev);
bus_generic_detach(sc->dev);
- if (sc->spibus != NULL)
- device_delete_child(dev, sc->spibus);
if (sc->clk_spi != NULL)
clk_release(sc->clk_spi);
diff --git a/sys/dev/viapm/viapm.c b/sys/dev/viapm/viapm.c
index b19ad478a3ff..36c33422d5b3 100644
--- a/sys/dev/viapm/viapm.c
+++ b/sys/dev/viapm/viapm.c
@@ -444,9 +444,6 @@ viapm_586b_detach(device_t dev)
struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
bus_generic_detach(dev);
- if (viapm->iicbb) {
- device_delete_child(dev, viapm->iicbb);
- }
if (viapm->iores)
bus_release_resource(dev, SYS_RES_IOPORT, viapm->iorid,
@@ -462,9 +459,6 @@ viapm_pro_detach(device_t dev)
struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
bus_generic_detach(dev);
- if (viapm->smbus) {
- device_delete_child(dev, viapm->smbus);
- }
bus_release_resource(dev, SYS_RES_IOPORT, viapm->iorid, viapm->iores);
diff --git a/sys/dev/vnic/thunder_mdio.c b/sys/dev/vnic/thunder_mdio.c
index 4545fe6658f5..a98e6aff05fd 100644
--- a/sys/dev/vnic/thunder_mdio.c
+++ b/sys/dev/vnic/thunder_mdio.c
@@ -494,7 +494,6 @@ thunder_mdio_phy_disconnect(device_t dev, int lmacid, int phy)
/* Detach miibus */
bus_generic_detach(dev);
- device_delete_child(dev, pd->miibus);
/* Free fake ifnet */
if_free(pd->ifp);
/* Free memory under phy descriptor */
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
index 1d04ea496f08..0df0b883a32d 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -3496,8 +3496,13 @@ bus_delayed_attach_children(device_t dev)
* @brief Helper function for implementing DEVICE_DETACH()
*
* This function can be used to help implement the DEVICE_DETACH() for
- * a bus. It calls device_detach() for each of the device's
- * children.
+ * a bus. It detaches and deletes all children. If an individual
+ * child fails to detach, this function stops and returns an error.
+ *
+ * @param dev the parent device
+ *
+ * @retval 0 success
+ * @retval non-zero a device would not detach
*/
int
bus_generic_detach(device_t dev)
@@ -3508,7 +3513,7 @@ bus_generic_detach(device_t dev)
if (error != 0)
return (error);
- return (0);
+ return (device_delete_children(dev));
}
/**
diff --git a/sys/sys/param.h b/sys/sys/param.h
index f675dd024ee0..d2aad1ff98a1 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -73,7 +73,7 @@
* cannot include sys/param.h and should only be updated here.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 1500029
+#define __FreeBSD_version 1500030
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,