git: b1e931327426 - main - Fix ofw pcib when it rman_init fails

From: Andrew Turner <andrew_at_FreeBSD.org>
Date: Mon, 04 Jul 2022 14:27:19 UTC
The branch main has been updated by andrew:

URL: https://cgit.FreeBSD.org/src/commit/?id=b1e9313274265645e163508ff1704ace2e0b1294

commit b1e9313274265645e163508ff1704ace2e0b1294
Author:     Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2022-06-30 18:12:46 +0000
Commit:     Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2022-07-04 14:27:00 +0000

    Fix ofw pcib when it rman_init fails
    
    rman_fini assumes rman_init has been called successfully. Clean up
    init faulure by only calling rman_fini when rman_init has succeeded.
    
    While here add ofw_pcib_fini that can be used by a sub-class to clean
    up.
    
    Reviewed by:    bz, imp
    Sponsored by:   The FreeBSD Foundation
    Differential Revision: https://reviews.freebsd.org/D35681
---
 sys/dev/ofw/ofw_pcib.c | 28 ++++++++++++++++++++++------
 sys/dev/ofw/ofwpci.h   |  1 +
 2 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/sys/dev/ofw/ofw_pcib.c b/sys/dev/ofw/ofw_pcib.c
index b10feffedf6c..e2aa0c9203b7 100644
--- a/sys/dev/ofw/ofw_pcib.c
+++ b/sys/dev/ofw/ofw_pcib.c
@@ -211,7 +211,7 @@ ofw_pcib_init(device_t dev)
 	error = rman_init(&sc->sc_mem_rman);
 	if (error != 0) {
 		device_printf(dev, "rman_init() failed. error = %d\n", error);
-		goto out;
+		goto out_mem_rman;
 	}
 
 	sc->sc_pmem_rman.rm_type = RMAN_ARRAY;
@@ -219,7 +219,7 @@ ofw_pcib_init(device_t dev)
 	error = rman_init(&sc->sc_pmem_rman);
 	if (error != 0) {
 		device_printf(dev, "rman_init() failed. error = %d\n", error);
-		goto out;
+		goto out_pmem_rman;
 	}
 
 	for (i = 0; i < sc->sc_nrange; i++) {
@@ -254,21 +254,37 @@ ofw_pcib_init(device_t dev)
 			    "error = %d\n", rp->pci_hi &
 			    OFW_PCI_PHYS_HI_SPACEMASK, rp->pci,
 			    rp->pci + rp->size - 1, error);
-			goto out;
+			goto out_full;
 		}
 	}
 
 	ofw_bus_setup_iinfo(node, &sc->sc_pci_iinfo, sizeof(cell_t));
 	return (0);
 
+out_full:
+	rman_fini(&sc->sc_pmem_rman);
+out_pmem_rman:
+	rman_fini(&sc->sc_mem_rman);
+out_mem_rman:
+	rman_fini(&sc->sc_io_rman);
 out:
-	free(cell_info, M_DEVBUF);
+	free(sc->sc_cell_info, M_DEVBUF);
+	free(sc->sc_range, M_DEVBUF);
+
+	return (error);
+}
+
+void
+ofw_pcib_fini(device_t dev)
+{
+	struct ofw_pci_softc *sc;
+
+	sc = device_get_softc(dev);
+	free(sc->sc_cell_info, M_DEVBUF);
 	free(sc->sc_range, M_DEVBUF);
 	rman_fini(&sc->sc_io_rman);
 	rman_fini(&sc->sc_mem_rman);
 	rman_fini(&sc->sc_pmem_rman);
-
-	return (error);
 }
 
 int
diff --git a/sys/dev/ofw/ofwpci.h b/sys/dev/ofw/ofwpci.h
index d58efa2daaef..7c2ec90a5d18 100644
--- a/sys/dev/ofw/ofwpci.h
+++ b/sys/dev/ofw/ofwpci.h
@@ -78,6 +78,7 @@ struct ofw_pci_softc {
 };
 
 int ofw_pcib_init(device_t);
+void ofw_pcib_fini(device_t);
 int ofw_pcib_attach(device_t);
 int ofw_pcib_read_ivar(device_t, device_t, int, uintptr_t *);
 int ofw_pcib_write_ivar(device_t, device_t, int, uintptr_t);