svn commit: r326452 - head/sys/dev/bhnd/cores/pmu
Landon J. Fuller
landonf at FreeBSD.org
Sat Dec 2 01:10:46 UTC 2017
Author: landonf
Date: Sat Dec 2 01:10:45 2017
New Revision: 326452
URL: https://svnweb.freebsd.org/changeset/base/326452
Log:
bhnd_pmu(4): Do not leak our chipc provider reference or clkctl state in
failure paths of bhnd_pmu_attach()
Approved by: adrian (mentor, implicit)
Sponsored by: The FreeBSD Foundation
Modified:
head/sys/dev/bhnd/cores/pmu/bhnd_pmu.c
Modified: head/sys/dev/bhnd/cores/pmu/bhnd_pmu.c
==============================================================================
--- head/sys/dev/bhnd/cores/pmu/bhnd_pmu.c Sat Dec 2 01:07:41 2017 (r326451)
+++ head/sys/dev/bhnd/cores/pmu/bhnd_pmu.c Sat Dec 2 01:10:45 2017 (r326452)
@@ -133,33 +133,14 @@ bhnd_pmu_attach(device_t dev, struct bhnd_resource *re
return (ENXIO);
}
- /* Allocate our own core clkctl state directly; we use this to wait on
- * PMU state transitions, avoiding a cyclic dependency between bhnd(4)'s
- * clkctl handling and registration of this device as a PMU */
- sc->clkctl = bhnd_alloc_core_clkctl(core, dev, sc->res, BHND_CLK_CTL_ST,
- BHND_PMU_MAX_TRANSITION_DLY);
- if (sc->clkctl == NULL) {
- device_printf(sc->dev, "failed to allocate clkctl for %s\n",
- device_get_nameunit(core));
- return (ENOMEM);
- }
-
/* Fetch chip and board info */
sc->cid = *bhnd_get_chipid(core);
-
if ((error = bhnd_read_board_info(core, &sc->board))) {
device_printf(sc->dev, "error fetching board info: %d\n",
error);
return (ENXIO);
}
- /* Locate ChipCommon device */
- sc->chipc_dev = bhnd_retain_provider(dev, BHND_SERVICE_CHIPC);
- if (sc->chipc_dev == NULL) {
- device_printf(sc->dev, "chipcommon device not found\n");
- return (ENXIO);
- }
-
/* Initialize query state */
error = bhnd_pmu_query_init(&sc->query, dev, sc->cid, &bhnd_pmu_res_io,
sc);
@@ -170,6 +151,26 @@ bhnd_pmu_attach(device_t dev, struct bhnd_resource *re
BPMU_LOCK_INIT(sc);
+ /* Allocate our own core clkctl state directly; we use this to wait on
+ * PMU state transitions, avoiding a cyclic dependency between bhnd(4)'s
+ * clkctl handling and registration of this device as a PMU */
+ sc->clkctl = bhnd_alloc_core_clkctl(core, dev, sc->res, BHND_CLK_CTL_ST,
+ BHND_PMU_MAX_TRANSITION_DLY);
+ if (sc->clkctl == NULL) {
+ device_printf(sc->dev, "failed to allocate clkctl for %s\n",
+ device_get_nameunit(core));
+ error = ENOMEM;
+ goto failed;
+ }
+
+ /* Locate ChipCommon device */
+ sc->chipc_dev = bhnd_retain_provider(dev, BHND_SERVICE_CHIPC);
+ if (sc->chipc_dev == NULL) {
+ device_printf(sc->dev, "chipcommon device not found\n");
+ error = ENXIO;
+ goto failed;
+ }
+
/* Initialize PMU */
if ((error = bhnd_pmu_init(sc))) {
device_printf(sc->dev, "PMU init failed: %d\n", error);
@@ -204,8 +205,14 @@ bhnd_pmu_attach(device_t dev, struct bhnd_resource *re
failed:
BPMU_LOCK_DESTROY(sc);
bhnd_pmu_query_fini(&sc->query);
- bhnd_free_core_clkctl(sc->clkctl);
- bhnd_release_provider(sc->dev, sc->chipc_dev, BHND_SERVICE_CHIPC);
+
+ if (sc->clkctl != NULL)
+ bhnd_free_core_clkctl(sc->clkctl);
+
+ if (sc->chipc_dev != NULL) {
+ bhnd_release_provider(sc->dev, sc->chipc_dev,
+ BHND_SERVICE_CHIPC);
+ }
return (error);
}
More information about the svn-src-all
mailing list