DF-4261 / fix.diff
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | --- sys/dev/acpica/acpi_cpu_pstate.c.orig +++ sys/dev/acpica/acpi_cpu_pstate.c @@ -511,6 +511,7 @@ /* Save and try allocating status register */ error = acpi_pst_alloc_resource(dev, obj, 1, &sc->pst_sreg); if (error) { + acpi_pst_release_resource(dev, &sc->pst_creg); AcpiOsFree(obj); return error; } @@ -544,14 +545,16 @@ } device_printf(dev, "Can't get _PSS package - %s\n", AcpiFormatException(status)); - return ENXIO; + error = ENXIO; + goto failed; } obj = (ACPI_OBJECT *)buf.Pointer; if (!ACPI_PKG_VALID(obj, 1)) { device_printf(dev, "Invalid _PSS package\n"); AcpiOsFree(obj); - return ENXIO; + error = ENXIO; + goto failed; } /* Don't create too many P-States */ @@ -571,7 +574,8 @@ device_printf(dev, "Inconsistent # of P-States " "cross Processor objects\n"); AcpiOsFree(obj); - return ENXIO; + error = ENXIO; + goto failed; } /* @@ -591,7 +595,8 @@ device_printf(dev, "Invalud _PSS P%d\n", i); AcpiOsFree(obj); kfree(pstate, M_TEMP); - return ENXIO; + error = ENXIO; + goto failed; } for (j = 0; j < ACPI_PSS_PX_NENTRY; ++j) { if (acpi_PkgInt32(pkg, j, ptr[j]) != 0) { @@ -599,7 +604,8 @@ "_PSS P%d %dth entry\n", i, j); AcpiOsFree(obj); kfree(pstate, M_TEMP); - return ENXIO; + error = ENXIO; + goto failed; } } if (p->st_freq & 0x80000000) { @@ -607,7 +613,8 @@ i, p->st_freq); AcpiOsFree(obj); kfree(pstate, M_TEMP); - return ENXIO; + error = ENXIO; + goto failed; } } @@ -687,7 +694,7 @@ */ error = acpi_pst_eval_ppc(sc, &sstart); if (error && error != ENOENT) - return error; + goto failed; else if (!error) sc->pst_flags |= ACPI_PST_FLAG_PPC; proc_ppc: @@ -733,7 +740,7 @@ */ error = acpi_pst_eval_pdl(sc, &scount); if (error && error != ENOENT) - return error; + goto failed; else if (!error) sc->pst_flags |= ACPI_PST_FLAG_PDL; proc_pdl: @@ -810,6 +817,11 @@ sc->pst_parent->cpu_pst_notify = acpi_pst_notify; return 0; + +failed: + acpi_pst_release_resource(dev, &sc->pst_creg); + acpi_pst_release_resource(dev, &sc->pst_sreg); + return error; } static struct acpi_pst_domain * @@ -1518,6 +1530,29 @@ } static void +acpi_pst_release_resource(device_t dev, struct acpi_pst_res *res) +{ + int type; + + if (res->pr_res == NULL) + return; + + switch (res->pr_gas.SpaceId) { + case ACPI_ADR_SPACE_SYSTEM_MEMORY: + type = SYS_RES_MEMORY; + break; + case ACPI_ADR_SPACE_SYSTEM_IO: + type = SYS_RES_IOPORT; + break; + default: + return; + } + bus_release_resource(dev, type, res->pr_rid, res->pr_res); + res->pr_res = NULL; + res->pr_rid = 0; +} + +static void acpi_pst_domain_check_nproc(device_t dev, struct acpi_pst_domain *dom) { struct acpi_pst_softc *pst; |