pci: pci_host_generic: provide cleanup methods outside of detach
If device_attach() fails, we're expected to actually cleanup after ourselves because device_detach() will not be called. Factor out the cleanup bits that don't rely on attach having actually succeeded so that we can cleanup properly in bcm2838_pci. Reviewed by: andrew, imp Differential Revision: https://reviews.freebsd.org/D56896
This commit is contained in:
@@ -250,15 +250,22 @@ pci_host_generic_core_attach(device_t dev)
|
|||||||
int
|
int
|
||||||
pci_host_generic_core_detach(device_t dev)
|
pci_host_generic_core_detach(device_t dev)
|
||||||
{
|
{
|
||||||
struct generic_pcie_core_softc *sc;
|
int error;
|
||||||
int error, rid, tuple;
|
|
||||||
|
|
||||||
sc = device_get_softc(dev);
|
|
||||||
|
|
||||||
error = bus_generic_detach(dev);
|
error = bus_generic_detach(dev);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
return (error);
|
return (error);
|
||||||
|
|
||||||
|
return (pci_host_generic_core_free(dev));
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
pci_host_generic_core_free(device_t dev)
|
||||||
|
{
|
||||||
|
struct generic_pcie_core_softc *sc;
|
||||||
|
int rid, tuple;
|
||||||
|
|
||||||
|
sc = device_get_softc(dev);
|
||||||
for (tuple = 0; tuple < MAX_RANGES_TUPLES; tuple++) {
|
for (tuple = 0; tuple < MAX_RANGES_TUPLES; tuple++) {
|
||||||
rid = sc->ranges[tuple].rid;
|
rid = sc->ranges[tuple].rid;
|
||||||
if (sc->ranges[tuple].size == 0) {
|
if (sc->ranges[tuple].size == 0) {
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ DECLARE_CLASS(generic_pcie_core_driver);
|
|||||||
|
|
||||||
int pci_host_generic_core_attach(device_t);
|
int pci_host_generic_core_attach(device_t);
|
||||||
int pci_host_generic_core_detach(device_t);
|
int pci_host_generic_core_detach(device_t);
|
||||||
|
int pci_host_generic_core_free(device_t);
|
||||||
struct resource *pci_host_generic_core_alloc_resource(device_t, device_t, int,
|
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, rman_res_t, rman_res_t, rman_res_t, u_int);
|
||||||
int pci_host_generic_core_release_resource(device_t, device_t,
|
int pci_host_generic_core_release_resource(device_t, device_t,
|
||||||
|
|||||||
@@ -104,6 +104,25 @@ generic_pcie_fdt_probe(device_t dev)
|
|||||||
return (ENXIO);
|
return (ENXIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pci_host_generic_destroy_fdt(device_t dev)
|
||||||
|
{
|
||||||
|
struct generic_pcie_fdt_softc *sc;
|
||||||
|
struct pci_ofw_devinfo *di;
|
||||||
|
|
||||||
|
sc = device_get_softc(dev);
|
||||||
|
while (!STAILQ_EMPTY(&sc->pci_ofw_devlist)) {
|
||||||
|
di = STAILQ_FIRST(&sc->pci_ofw_devlist);
|
||||||
|
STAILQ_REMOVE_HEAD(&sc->pci_ofw_devlist, pci_ofw_link);
|
||||||
|
|
||||||
|
ofw_bus_gen_destroy_devinfo(&di->di_dinfo);
|
||||||
|
free(di, M_DEVBUF);
|
||||||
|
}
|
||||||
|
|
||||||
|
ofw_bus_destroy_iinfo(&sc->pci_iinfo);
|
||||||
|
(void)pci_host_generic_core_free(dev);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pci_host_generic_setup_fdt(device_t dev)
|
pci_host_generic_setup_fdt(device_t dev)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ DECLARE_CLASS(generic_pcie_fdt_driver);
|
|||||||
struct resource *pci_host_generic_alloc_resource(device_t,
|
struct resource *pci_host_generic_alloc_resource(device_t,
|
||||||
device_t, int, int *, rman_res_t, rman_res_t, rman_res_t, u_int);
|
device_t, int, int *, rman_res_t, rman_res_t, rman_res_t, u_int);
|
||||||
int pci_host_generic_setup_fdt(device_t);
|
int pci_host_generic_setup_fdt(device_t);
|
||||||
|
void pci_host_generic_destroy_fdt(device_t);
|
||||||
int pci_host_generic_fdt_attach(device_t);
|
int pci_host_generic_fdt_attach(device_t);
|
||||||
int generic_pcie_get_id(device_t, device_t, enum pci_id_type, uintptr_t *);
|
int generic_pcie_get_id(device_t, device_t, enum pci_id_type, uintptr_t *);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user