git: 2069f112f007 - stable/13 - Clean up in the pci host generic driver

From: Andrew Turner <andrew_at_FreeBSD.org>
Date: Tue, 19 Jul 2022 07:37:18 UTC
The branch stable/13 has been updated by andrew:

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

commit 2069f112f0073e21fb47aa921a880d0404d69484
Author:     Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2022-05-23 09:41:36 +0000
Commit:     Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2022-07-19 07:03:30 +0000

    Clean up in the pci host generic driver
    
    Add clean up on failure and a detach function to the pci host generic
    driver.
    
    Reviewed by:    jhb (earlier version)
    Sponsored by:   The FreeBSD Foundation
    Differential Revision: https://reviews.freebsd.org/D35291
    
    (cherry picked from commit d843dd0e1addd2aa69a78be99e251147aafcfd80)
---
 sys/dev/pci/pci_host_generic.c | 51 ++++++++++++++++++++++++++++++++++--------
 sys/dev/pci/pci_host_generic.h |  1 +
 2 files changed, 43 insertions(+), 9 deletions(-)

diff --git a/sys/dev/pci/pci_host_generic.c b/sys/dev/pci/pci_host_generic.c
index 22b3ccdc17b1..f23173ce0a43 100644
--- a/sys/dev/pci/pci_host_generic.c
+++ b/sys/dev/pci/pci_host_generic.c
@@ -97,8 +97,9 @@ pci_host_generic_core_attach(device_t dev)
 	rid = 0;
 	sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
 	if (sc->res == NULL) {
-		device_printf(dev, "could not map memory.\n");
-		return (ENXIO);
+		device_printf(dev, "could not allocate memory.\n");
+		error = ENXIO;
+		goto err_resource;
 	}
 
 	sc->bst = rman_get_bustag(sc->res);
@@ -118,19 +119,19 @@ pci_host_generic_core_attach(device_t dev)
 	error = rman_init(&sc->pmem_rman);
 	if (error) {
 		device_printf(dev, "rman_init() failed. error = %d\n", error);
-		return (error);
+		goto err_pmem_rman;
 	}
 
 	error = rman_init(&sc->mem_rman);
 	if (error) {
 		device_printf(dev, "rman_init() failed. error = %d\n", error);
-		return (error);
+		goto err_mem_rman;
 	}
 
 	error = rman_init(&sc->io_rman);
 	if (error) {
 		device_printf(dev, "rman_init() failed. error = %d\n", error);
-		return (error);
+		goto err_io_rman;
 	}
 
 	for (tuple = 0; tuple < MAX_RANGES_TUPLES; tuple++) {
@@ -159,13 +160,43 @@ pci_host_generic_core_attach(device_t dev)
 		if (error) {
 			device_printf(dev, "rman_manage_region() failed."
 						"error = %d\n", error);
-			rman_fini(&sc->pmem_rman);
-			rman_fini(&sc->mem_rman);
-			rman_fini(&sc->io_rman);
-			return (error);
+			goto err_rman_manage;
 		}
 	}
 
+	return (0);
+
+err_rman_manage:
+	rman_fini(&sc->io_rman);
+err_io_rman:
+	rman_fini(&sc->mem_rman);
+err_mem_rman:
+	rman_fini(&sc->pmem_rman);
+err_pmem_rman:
+	bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->res);
+err_resource:
+	bus_dma_tag_destroy(sc->dmat);
+	return (error);
+}
+
+int
+pci_host_generic_core_detach(device_t dev)
+{
+	struct generic_pcie_core_softc *sc;
+	int error;
+
+	sc = device_get_softc(dev);
+
+	error = bus_generic_detach(dev);
+	if (error != 0)
+		return (error);
+
+	rman_fini(&sc->io_rman);
+	rman_fini(&sc->mem_rman);
+	rman_fini(&sc->pmem_rman);
+	bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->res);
+	bus_dma_tag_destroy(sc->dmat);
+
 	return (0);
 }
 
@@ -522,6 +553,8 @@ generic_pcie_get_dma_tag(device_t dev, device_t child)
 
 static device_method_t generic_pcie_methods[] = {
 	DEVMETHOD(device_attach,		pci_host_generic_core_attach),
+	DEVMETHOD(device_detach,		pci_host_generic_core_detach),
+
 	DEVMETHOD(bus_read_ivar,		generic_pcie_read_ivar),
 	DEVMETHOD(bus_write_ivar,		generic_pcie_write_ivar),
 	DEVMETHOD(bus_alloc_resource,		pci_host_generic_core_alloc_resource),
diff --git a/sys/dev/pci/pci_host_generic.h b/sys/dev/pci/pci_host_generic.h
index 20117cbe32e3..80da4f523165 100644
--- a/sys/dev/pci/pci_host_generic.h
+++ b/sys/dev/pci/pci_host_generic.h
@@ -94,6 +94,7 @@ struct generic_pcie_core_softc {
 DECLARE_CLASS(generic_pcie_core_driver);
 
 int pci_host_generic_core_attach(device_t);
+int pci_host_generic_core_detach(device_t);
 struct resource *pci_host_generic_core_alloc_resource(device_t, device_t, int,
     int *, rman_res_t, rman_res_t, rman_res_t, u_int);
 int pci_host_generic_core_release_resource(device_t, device_t, int, int,