diff options
author | Luiz Otavio O Souza <loos@FreeBSD.org> | 2015-08-17 16:51:37 +0000 |
---|---|---|
committer | Luiz Otavio O Souza <loos@FreeBSD.org> | 2015-08-17 16:51:37 +0000 |
commit | 978cdbedcdbf5dc067ce389771c5c18572d1319f (patch) | |
tree | 1a3a9d68b8e9a45cd707dd6b3c9908585f3762a1 /sys/dev/gpio/gpiobus.c | |
parent | edcf7fbf595d66836eccafa5e612cfbad9025bfb (diff) | |
download | src-978cdbedcdbf5dc067ce389771c5c18572d1319f.tar.gz src-978cdbedcdbf5dc067ce389771c5c18572d1319f.zip |
Fix a few bugs when gpiobus is detaching:
- Detach the gpiobus and the gpioc devices from the GPIO controller.
- Fix the leak of gpiobus IRQ rman(9) region descriptor.
- Fix the leak of child ivars and IRQ resource list.
While here return NULL (instead of 0) for a device_t that fails to allocate
the ivar memory.
Tested with gpiobus built as a module.
Sponsored by: Rubicon Communications (Netgate)
Notes
Notes:
svn path=/head/; revision=286845
Diffstat (limited to 'sys/dev/gpio/gpiobus.c')
-rw-r--r-- | sys/dev/gpio/gpiobus.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/sys/dev/gpio/gpiobus.c b/sys/dev/gpio/gpiobus.c index e741d288dbe9..6cafdafe9c61 100644 --- a/sys/dev/gpio/gpiobus.c +++ b/sys/dev/gpio/gpiobus.c @@ -155,12 +155,16 @@ gpiobus_attach_bus(device_t dev) int gpiobus_detach_bus(device_t dev) { + int err; #ifdef FDT ofw_gpiobus_unregister_provider(dev); #endif + err = bus_generic_detach(dev); + if (err != 0) + return (err); - return (bus_generic_detach(dev)); + return (device_delete_children(dev)); } int @@ -338,11 +342,14 @@ gpiobus_detach(device_t dev) if ((err = device_get_children(dev, &devlist, &ndevs)) != 0) return (err); for (i = 0; i < ndevs; i++) { - device_delete_child(dev, devlist[i]); devi = GPIOBUS_IVAR(devlist[i]); gpiobus_free_ivars(devi); + resource_list_free(&devi->rl); + free(devi, M_DEVBUF); + device_delete_child(dev, devlist[i]); } free(devlist, M_TEMP); + rman_fini(&sc->sc_intr_rman); if (sc->sc_pins) { for (i = 0; i < sc->sc_npins; i++) { if (sc->sc_pins[i].name != NULL) @@ -442,7 +449,7 @@ gpiobus_add_child(device_t dev, u_int order, const char *name, int unit) devi = malloc(sizeof(struct gpiobus_ivar), M_DEVBUF, M_NOWAIT | M_ZERO); if (devi == NULL) { device_delete_child(dev, child); - return (0); + return (NULL); } resource_list_init(&devi->rl); device_set_ivars(child, devi); @@ -461,8 +468,11 @@ gpiobus_hinted_child(device_t bus, const char *dname, int dunit) child = BUS_ADD_CHILD(bus, 0, dname, dunit); devi = GPIOBUS_IVAR(child); resource_int_value(dname, dunit, "pins", &pins); - if (gpiobus_parse_pins(sc, child, pins)) + if (gpiobus_parse_pins(sc, child, pins)) { + resource_list_free(&devi->rl); + free(devi, M_DEVBUF); device_delete_child(bus, child); + } if (resource_int_value(dname, dunit, "irq", &irq) == 0) { if (bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1) != 0) device_printf(bus, |