summaryrefslogtreecommitdiffstats
path: root/sys/dev/ahci/ahci.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/ahci/ahci.c')
-rw-r--r--sys/dev/ahci/ahci.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c
index 5944326..6a2c766 100644
--- a/sys/dev/ahci/ahci.c
+++ b/sys/dev/ahci/ahci.c
@@ -181,12 +181,12 @@ ahci_attach(device_t dev)
ctlr->sc_iomem.rm_type = RMAN_ARRAY;
ctlr->sc_iomem.rm_descr = "I/O memory addresses";
if ((error = rman_init(&ctlr->sc_iomem)) != 0) {
- bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem);
+ ahci_free_mem(dev);
return (error);
}
if ((error = rman_manage_region(&ctlr->sc_iomem,
rman_get_start(ctlr->r_mem), rman_get_end(ctlr->r_mem))) != 0) {
- bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem);
+ ahci_free_mem(dev);
rman_fini(&ctlr->sc_iomem);
return (error);
}
@@ -250,8 +250,7 @@ ahci_attach(device_t dev)
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
BUS_SPACE_MAXSIZE, BUS_SPACE_UNRESTRICTED, BUS_SPACE_MAXSIZE,
0, NULL, NULL, &ctlr->dma_tag)) {
- bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid,
- ctlr->r_mem);
+ ahci_free_mem(dev);
rman_fini(&ctlr->sc_iomem);
return (ENXIO);
}
@@ -261,8 +260,7 @@ ahci_attach(device_t dev)
/* Setup interrupts. */
if ((error = ahci_setup_interrupt(dev)) != 0) {
bus_dma_tag_destroy(ctlr->dma_tag);
- bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid,
- ctlr->r_mem);
+ ahci_free_mem(dev);
rman_fini(&ctlr->sc_iomem);
return (error);
}
@@ -367,9 +365,26 @@ ahci_detach(device_t dev)
bus_dma_tag_destroy(ctlr->dma_tag);
/* Free memory. */
rman_fini(&ctlr->sc_iomem);
+ ahci_free_mem(dev);
+ return (0);
+}
+
+void
+ahci_free_mem(device_t dev)
+{
+ struct ahci_controller *ctlr = device_get_softc(dev);
+
+ /* Release memory resources */
if (ctlr->r_mem)
bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem);
- return (0);
+ if (ctlr->r_msix_table)
+ bus_release_resource(dev, SYS_RES_MEMORY,
+ ctlr->r_msix_tab_rid, ctlr->r_msix_table);
+ if (ctlr->r_msix_pba)
+ bus_release_resource(dev, SYS_RES_MEMORY,
+ ctlr->r_msix_pba_rid, ctlr->r_msix_pba);
+
+ ctlr->r_msix_pba = ctlr->r_mem = ctlr->r_msix_table = NULL;
}
int
OpenPOWER on IntegriCloud