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
This commit is contained in:
parent
c47117f43a
commit
a2f51f57d1
@ -199,6 +199,23 @@ sb8xx_attach(device_t dev)
|
|||||||
return (0);
|
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
|
static int
|
||||||
intsmb_attach(device_t dev)
|
intsmb_attach(device_t dev)
|
||||||
{
|
{
|
||||||
@ -311,12 +328,15 @@ no_intr:
|
|||||||
sc->isbusy = 0;
|
sc->isbusy = 0;
|
||||||
sc->smbus = device_add_child(dev, "smbus", -1);
|
sc->smbus = device_add_child(dev, "smbus", -1);
|
||||||
if (sc->smbus == NULL) {
|
if (sc->smbus == NULL) {
|
||||||
|
device_printf(dev, "failed to add smbus child\n");
|
||||||
error = ENXIO;
|
error = ENXIO;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
error = device_probe_and_attach(sc->smbus);
|
error = device_probe_and_attach(sc->smbus);
|
||||||
if (error)
|
if (error) {
|
||||||
|
device_printf(dev, "failed to probe+attach smbus child\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_ALART
|
#ifdef ENABLE_ALART
|
||||||
/* Enable Arart */
|
/* Enable Arart */
|
||||||
@ -325,30 +345,22 @@ no_intr:
|
|||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
intsmb_detach(dev);
|
intsmb_release_resources(dev);
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
intsmb_detach(device_t dev)
|
intsmb_detach(device_t dev)
|
||||||
{
|
{
|
||||||
struct intsmb_softc *sc = device_get_softc(dev);
|
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
error = bus_generic_detach(dev);
|
error = bus_generic_detach(dev);
|
||||||
if (error)
|
if (error) {
|
||||||
|
device_printf(dev, "bus detach failed\n");
|
||||||
return (error);
|
return (error);
|
||||||
|
}
|
||||||
|
|
||||||
if (sc->smbus)
|
intsmb_release_resources(dev);
|
||||||
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);
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user