diff options
Diffstat (limited to 'sys/dev/ahci/ahci.c')
-rw-r--r-- | sys/dev/ahci/ahci.c | 29 |
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 |