summaryrefslogtreecommitdiffstats
path: root/sys/dev/iicbus
diff options
context:
space:
mode:
authordumbbell <dumbbell@FreeBSD.org>2016-01-21 08:32:11 +0000
committerdumbbell <dumbbell@FreeBSD.org>2016-01-21 08:32:11 +0000
commitb7a57a081515764692cefcf6df0484602753a804 (patch)
tree0c22d2f646e25b5b7a1cf8f3462a26da05e09cda /sys/dev/iicbus
parent240e29b90365c069e98a7d337b71dc7567c1521e (diff)
downloadFreeBSD-src-b7a57a081515764692cefcf6df0484602753a804.zip
FreeBSD-src-b7a57a081515764692cefcf6df0484602753a804.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 Differential Revision: https://reviews.freebsd.org/D3926
Diffstat (limited to 'sys/dev/iicbus')
-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 7a0c0cb..e377383 100644
--- a/sys/dev/iicbus/iicbus.c
+++ b/sys/dev/iicbus/iicbus.c
@@ -134,6 +134,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