From ca2c69c8ef3d518ea6fe03fdc1043cf5f2a11760 Mon Sep 17 00:00:00 2001 From: Nate Lawson Date: Sun, 27 Mar 2005 22:38:28 +0000 Subject: [PATCH] Clean up resources properly if acpi_perf fails to attach. First, change acpi_bus_alloc_gas() to delete the resource it set if alloc fails. Then, change acpi_perf to delete the resource after releasing it if alloc fails. This should make probe and attach both fully restartable if either fails. --- sys/dev/acpica/acpi.c | 10 +++------- sys/dev/acpica/acpi_perf.c | 18 +++++++++++++++++- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c index b2cf5644d8a..ccb18ae7f51 100644 --- a/sys/dev/acpica/acpi.c +++ b/sys/dev/acpica/acpi.c @@ -1119,19 +1119,15 @@ acpi_bus_alloc_gas(device_t dev, int *type, int *rid, ACPI_GENERIC_ADDRESS *gas, if (!ACPI_VALID_ADDRESS(gas->Address) || gas->RegisterBitWidth == 0) return (EINVAL); - /* - * Delete any previous resource before setting the new one. Note this - * will panic if the resource is still allocated but that will reveal - * any driver bugs. - */ - bus_delete_resource(dev, res_type, *rid); bus_set_resource(dev, res_type, *rid, gas->Address, gas->RegisterBitWidth / 8); *res = bus_alloc_resource_any(dev, res_type, rid, RF_ACTIVE); if (*res != NULL) { *type = res_type; error = 0; - } + } else + bus_delete_resource(dev, res_type, *rid); + return (error); } diff --git a/sys/dev/acpica/acpi_perf.c b/sys/dev/acpica/acpi_perf.c index b7cd2e77f93..c5018f8f90c 100644 --- a/sys/dev/acpica/acpi_perf.c +++ b/sys/dev/acpica/acpi_perf.c @@ -196,6 +196,7 @@ acpi_perf_probe(device_t dev) switch (error) { case 0: bus_release_resource(dev, type, rid, res); + bus_delete_resource(dev, type, rid); device_set_desc(dev, "ACPI CPU Frequency Control"); break; case EOPNOTSUPP: @@ -354,8 +355,23 @@ acpi_perf_evaluate(device_t dev) out: if (error) { - if (sc->px_states) + if (sc->px_states) { free(sc->px_states, M_ACPIPERF); + sc->px_states = NULL; + } + if (sc->perf_ctrl) { + bus_release_resource(sc->dev, sc->perf_ctrl_type, 0, + sc->perf_ctrl); + bus_delete_resource(sc->dev, sc->perf_ctrl_type, 0); + sc->perf_ctrl = NULL; + } + if (sc->perf_status) { + bus_release_resource(sc->dev, sc->perf_sts_type, 1, + sc->perf_status); + bus_delete_resource(sc->dev, sc->perf_sts_type, 1); + sc->perf_status = NULL; + } + sc->px_rid = 0; sc->px_count = 0; } if (buf.Pointer)