From a2f51f57d195d45982aebd43255c063c65cf151c Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Thu, 8 Sep 2016 12:27:34 +0000 Subject: [PATCH] intpm: better clean up resources after a failed attachment bus_generic_detach() fails when called from attach method thus preventing further clean up actions. MFC after: 1 week --- sys/dev/intpm/intpm.c | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/sys/dev/intpm/intpm.c b/sys/dev/intpm/intpm.c index c520d8927fb..3a5054ff1a6 100644 --- a/sys/dev/intpm/intpm.c +++ b/sys/dev/intpm/intpm.c @@ -199,6 +199,23 @@ sb8xx_attach(device_t dev) return (0); } +static void +intsmb_release_resources(device_t dev) +{ + struct intsmb_softc *sc = device_get_softc(dev); + + if (sc->smbus) + device_delete_child(dev, sc->smbus); + if (sc->irq_hand) + bus_teardown_intr(dev, sc->irq_res, sc->irq_hand); + if (sc->irq_res) + bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res); + if (sc->io_res) + bus_release_resource(dev, SYS_RES_IOPORT, sc->io_rid, + sc->io_res); + mtx_destroy(&sc->lock); +} + static int intsmb_attach(device_t dev) { @@ -311,12 +328,15 @@ no_intr: sc->isbusy = 0; sc->smbus = device_add_child(dev, "smbus", -1); if (sc->smbus == NULL) { + device_printf(dev, "failed to add smbus child\n"); error = ENXIO; goto fail; } error = device_probe_and_attach(sc->smbus); - if (error) + if (error) { + device_printf(dev, "failed to probe+attach smbus child\n"); goto fail; + } #ifdef ENABLE_ALART /* Enable Arart */ @@ -325,30 +345,22 @@ no_intr: return (0); fail: - intsmb_detach(dev); + intsmb_release_resources(dev); return (error); } static int intsmb_detach(device_t dev) { - struct intsmb_softc *sc = device_get_softc(dev); int error; error = bus_generic_detach(dev); - if (error) + if (error) { + device_printf(dev, "bus detach failed\n"); return (error); + } - if (sc->smbus) - device_delete_child(dev, sc->smbus); - if (sc->irq_hand) - bus_teardown_intr(dev, sc->irq_res, sc->irq_hand); - if (sc->irq_res) - bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq_res); - if (sc->io_res) - bus_release_resource(dev, SYS_RES_IOPORT, sc->io_rid, - sc->io_res); - mtx_destroy(&sc->lock); + intsmb_release_resources(dev); return (0); }