summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordumbbell <dumbbell@FreeBSD.org>2015-10-20 19:52:59 +0000
committerdumbbell <dumbbell@FreeBSD.org>2015-10-20 19:52:59 +0000
commitfff41eb460e1fb0d65ac2f413911ce6460ca8127 (patch)
treefd729bbc0f2aacb48e993bcd34b183ddc5445e8e
parent5807c0b063023542925bc5d870e1227559e0db26 (diff)
downloadFreeBSD-src-fff41eb460e1fb0d65ac2f413911ce6460ca8127.zip
FreeBSD-src-fff41eb460e1fb0d65ac2f413911ce6460ca8127.tar.gz
iicbus: Use device_delete_children() instead of explicit child removal
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
-rw-r--r--sys/dev/iicbus/iicbb.c17
-rw-r--r--sys/dev/iicbus/iicbus.c1
-rw-r--r--sys/dev/iicbus/iicoc.c1
-rw-r--r--sys/dev/iicbus/iicsmb.c6
4 files changed, 6 insertions, 19 deletions
diff --git a/sys/dev/iicbus/iicbb.c b/sys/dev/iicbus/iicbb.c
index 977d52a..ed1d7b8 100644
--- a/sys/dev/iicbus/iicbb.c
+++ b/sys/dev/iicbus/iicbb.c
@@ -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);
}
diff --git a/sys/dev/iicbus/iicbus.c b/sys/dev/iicbus/iicbus.c
index 4ee480e..df29b09 100644
--- a/sys/dev/iicbus/iicbus.c
+++ b/sys/dev/iicbus/iicbus.c
@@ -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);
}
diff --git a/sys/dev/iicbus/iicoc.c b/sys/dev/iicbus/iicoc.c
index 45f1692..c55d6fe 100644
--- a/sys/dev/iicbus/iicoc.c
+++ b/sys/dev/iicbus/iicoc.c
@@ -229,6 +229,7 @@ static int
iicoc_detach(device_t dev)
{
bus_generic_detach(dev);
+ device_delete_children(dev);
return (0);
}
diff --git a/sys/dev/iicbus/iicsmb.c b/sys/dev/iicbus/iicsmb.c
index 27f1d2b..d8f35c6 100644
--- a/sys/dev/iicbus/iicsmb.c
+++ b/sys/dev/iicbus/iicsmb.c
@@ -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);
OpenPOWER on IntegriCloud