]> xenbits.xensource.com Git - people/julieng/freebsd.git/commitdiff
iicbus: Use device_delete_children() instead of explicit child removal
authordumbbell <dumbbell@FreeBSD.org>
Tue, 20 Oct 2015 19:52:59 +0000 (19:52 +0000)
committerdumbbell <dumbbell@FreeBSD.org>
Tue, 20 Oct 2015 19:52:59 +0000 (19:52 +0000)
If the bus is detached and deleted by a call to device_delete_child() or
device_delete_children() on a device higher in the tree, I²C children
were already detached and deleted. So the device_t pointer stored in sc
points to freed memory: we must not try to delete it again.

By using device_delete_children(), we let subr_bus.c figure out if there
are children to take care of.

While here, make sure iicbus_detach() and iicoc_detach() call
device_delete_children() too, to be safe.

Reviewed by: jhb, imp
Approved by: jhb, imp
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D3926

sys/dev/iicbus/iicbb.c
sys/dev/iicbus/iicbus.c
sys/dev/iicbus/iicoc.c
sys/dev/iicbus/iicsmb.c

index 977d52a01249524c95ea53f7e8552046b08531c6..ed1d7b846d315c17b1a40af5e066bb56caefbe3e 100644 (file)
@@ -149,22 +149,9 @@ iicbb_attach(device_t dev)
 static int
 iicbb_detach(device_t dev)
 {
-       struct iicbb_softc *sc = (struct iicbb_softc *)device_get_softc(dev);
-       device_t child;
-
-       /*
-        * We need to save child because the detach indirectly causes
-        * sc->iicbus to be zeroed.  Since we added the device
-        * unconditionally in iicbb_attach, we need to make sure we
-        * delete it here.  See iicbb_child_detached.  We need that
-        * callback in case newbus detached our children w/o detaching
-        * us (say iicbus is a module and unloaded w/o iicbb being
-        * unloaded).
-        */
-       child = sc->iicbus;
+
        bus_generic_detach(dev);
-       if (child)
-               device_delete_child(dev, child);
+       device_delete_children(dev);
 
        return (0);
 }
index 4ee480e677e62cce4cb82a24465302d1bc51b704..df29b09b4c06af3038f0f9fd96066737718e1363 100644 (file)
@@ -135,6 +135,7 @@ iicbus_detach(device_t dev)
 
        iicbus_reset(dev, IIC_FASTEST, 0, NULL);
        bus_generic_detach(dev);
+       device_delete_children(dev);
        mtx_destroy(&sc->lock);
        return (0);
 }
index 45f1692fa479d28094285742a963c465af3e7671..c55d6fe4dc897ad6f97396a4ded097f65d1d01dd 100644 (file)
@@ -229,6 +229,7 @@ static int
 iicoc_detach(device_t dev)
 {
        bus_generic_detach(dev);
+       device_delete_children(dev);
 
        return (0);
 }
index 27f1d2b055295881d121d5300dc184df09feefbe..d8f35c6e3baf670f5113b156f7142a0a7c03a837 100644 (file)
@@ -167,11 +167,9 @@ static int
 iicsmb_detach(device_t dev)
 {
        struct iicsmb_softc *sc = (struct iicsmb_softc *)device_get_softc(dev);
-       
+
        bus_generic_detach(dev);
-       if (sc->smbus) {
-               device_delete_child(dev, sc->smbus);
-       }
+       device_delete_children(dev);
        mtx_destroy(&sc->lock);
 
        return (0);