int ata_setup_interrupt(device_t dev, void *intr_func) { struct ata_pci_controller *ctlr = device_get_softc(dev); int i, msi = 0; if (!ctlr->legacy) { if (resource_int_value(device_get_name(dev), device_get_unit(dev), "msi", &i) == 0 && i != 0) msi = 1; if (msi && pci_msi_count(dev) > 0 && pci_alloc_msi(dev, &msi) == 0) { ctlr->r_irq_rid = 0x1; } else { msi = 0; ctlr->r_irq_rid = ATA_IRQ_RID; } if (!(ctlr->r_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &ctlr->r_irq_rid, RF_SHAREABLE | RF_ACTIVE))) { device_printf(dev, "unable to map interrupt\n"); if (msi) pci_release_msi(dev); return ENXIO; } if ((bus_setup_intr(dev, ctlr->r_irq, ATA_INTR_FLAGS, NULL, intr_func, ctlr, &ctlr->handle))) { device_printf(dev, "unable to setup interrupt\n"); bus_release_resource(dev, SYS_RES_IRQ, ctlr->r_irq_rid, ctlr->r_irq); if (msi) pci_release_msi(dev); return ENXIO; } } return 0; }
static int vtpci_alloc_msix(struct vtpci_softc *sc, int nvectors) { device_t dev; int nmsix, cnt, required; dev = sc->vtpci_dev; nmsix = pci_msix_count(dev); if (nmsix < 1) return (1); /* An additional vector is needed for the config changes. */ required = nvectors + 1; if (nmsix >= required) { cnt = required; if (pci_alloc_msix(dev, &cnt) == 0 && cnt >= required) goto out; pci_release_msi(dev); } /* Attempt shared MSIX configuration. */ required = 2; if (nmsix >= required) { cnt = required; if (pci_alloc_msix(dev, &cnt) == 0 && cnt >= required) { sc->vtpci_flags |= VIRTIO_PCI_FLAG_SHARED_MSIX; goto out; } pci_release_msi(dev); } return (1); out: sc->vtpci_nintr_res = required; sc->vtpci_flags |= VIRTIO_PCI_FLAG_MSIX; if (bootverbose) { if (sc->vtpci_flags & VIRTIO_PCI_FLAG_SHARED_MSIX) device_printf(dev, "using shared virtqueue MSIX\n"); else device_printf(dev, "using per virtqueue MSIX\n"); } return (0); }
static void vtpci_free_interrupts(struct vtpci_softc *sc) { struct vtpci_interrupt *intr; int i, nvq_intrs; vtpci_free_interrupt(sc, &sc->vtpci_device_interrupt); if (sc->vtpci_nmsix_resources != 0) { nvq_intrs = sc->vtpci_nmsix_resources - 1; sc->vtpci_nmsix_resources = 0; intr = sc->vtpci_msix_vq_interrupts; if (intr != NULL) { for (i = 0; i < nvq_intrs; i++, intr++) vtpci_free_interrupt(sc, intr); free(sc->vtpci_msix_vq_interrupts, M_DEVBUF); sc->vtpci_msix_vq_interrupts = NULL; } } if (sc->vtpci_flags & (VTPCI_FLAG_MSI | VTPCI_FLAG_MSIX)) pci_release_msi(sc->vtpci_dev); sc->vtpci_flags &= ~VTPCI_FLAG_ITYPE_MASK; }
static void ppt_teardown_msix(struct pptdev *ppt) { int i; if (ppt->msix.num_msgs == 0) return; for (i = 0; i < ppt->msix.num_msgs; i++) ppt_teardown_msix_intr(ppt, i); if (ppt->msix.msix_table_res) { bus_release_resource(ppt->dev, SYS_RES_MEMORY, ppt->msix.msix_table_rid, ppt->msix.msix_table_res); ppt->msix.msix_table_res = NULL; ppt->msix.msix_table_rid = 0; } free(ppt->msix.res, M_PPTMSIX); free(ppt->msix.cookie, M_PPTMSIX); free(ppt->msix.arg, M_PPTMSIX); pci_release_msi(ppt->dev); ppt->msix.num_msgs = 0; }
static void ppt_teardown_msi(struct pptdev *ppt) { int i, rid; void *cookie; struct resource *res; if (ppt->msi.num_msgs == 0) return; for (i = 0; i < ppt->msi.num_msgs; i++) { rid = ppt->msi.startrid + i; res = ppt->msi.res[i]; cookie = ppt->msi.cookie[i]; if (cookie != NULL) bus_teardown_intr(ppt->dev, res, cookie); if (res != NULL) bus_release_resource(ppt->dev, SYS_RES_IRQ, rid, res); ppt->msi.res[i] = NULL; ppt->msi.cookie[i] = NULL; } if (ppt->msi.startrid == 1) pci_release_msi(ppt->dev); ppt->msi.num_msgs = 0; }
static int ig4iic_pci_detach(device_t dev) { ig4iic_softc_t *sc = device_get_softc(dev); int error; if (sc->pci_attached) { error = ig4iic_detach(sc); if (error) return error; sc->pci_attached = 0; } if (sc->intr_res) { bus_release_resource(dev, SYS_RES_IRQ, sc->intr_rid, sc->intr_res); sc->intr_res = NULL; } if (sc->intr_type == PCI_INTR_TYPE_MSI) pci_release_msi(dev); if (sc->regs_res) { bus_release_resource(dev, SYS_RES_MEMORY, sc->regs_rid, sc->regs_res); sc->regs_res = NULL; } sc->regs_t = 0; sc->regs_h = 0; lockuninit(&sc->lk); return 0; }
static int rtwn_pci_detach(device_t dev) { struct rtwn_pci_softc *pc = device_get_softc(dev); struct rtwn_softc *sc = &pc->pc_sc; int i; /* Generic detach. */ rtwn_detach(sc); /* Uninstall interrupt handler. */ if (pc->irq != NULL) { bus_teardown_intr(dev, pc->irq, pc->pc_ih); bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(pc->irq), pc->irq); pci_release_msi(dev); } /* Free Tx/Rx buffers. */ for (i = 0; i < RTWN_PCI_NTXQUEUES; i++) rtwn_pci_free_tx_list(sc, i); rtwn_pci_free_rx_list(sc); if (pc->mem != NULL) bus_release_resource(dev, SYS_RES_MEMORY, rman_get_rid(pc->mem), pc->mem); rtwn_detach_private(sc); mtx_destroy(&sc->sc_mtx); return (0); }
static int vtpci_alloc_msix(struct vtpci_softc *sc, int nvectors) { device_t dev; int nmsix, cnt, required; dev = sc->vtpci_dev; /* Allocate an additional vector for the config changes. */ required = nvectors + 1; nmsix = pci_msix_count(dev); if (nmsix < required) return (1); cnt = required; if (pci_alloc_msix(dev, &cnt) == 0 && cnt >= required) { sc->vtpci_nmsix_resources = required; return (0); } pci_release_msi(dev); return (1); }
int ata_pci_detach(device_t dev) { struct ata_pci_controller *ctlr = device_get_softc(dev); /* detach & delete all children */ device_delete_children(dev); if (ctlr->r_irq) { bus_teardown_intr(dev, ctlr->r_irq, ctlr->handle); bus_release_resource(dev, SYS_RES_IRQ, ctlr->r_irq_rid, ctlr->r_irq); if (ctlr->r_irq_rid != ATA_IRQ_RID) pci_release_msi(dev); } if (ctlr->chipdeinit != NULL) ctlr->chipdeinit(dev); if (ctlr->r_res2) { #ifdef __sparc64__ bus_space_unmap(rman_get_bustag(ctlr->r_res2), rman_get_bushandle(ctlr->r_res2), rman_get_size(ctlr->r_res2)); #endif bus_release_resource(dev, ctlr->r_type2, ctlr->r_rid2, ctlr->r_res2); } if (ctlr->r_res1) { #ifdef __sparc64__ bus_space_unmap(rman_get_bustag(ctlr->r_res1), rman_get_bushandle(ctlr->r_res1), rman_get_size(ctlr->r_res1)); #endif bus_release_resource(dev, ctlr->r_type1, ctlr->r_rid1, ctlr->r_res1); } return 0; }
static int malo_pci_detach(device_t dev) { int i; struct malo_pci_softc *psc = device_get_softc(dev); struct malo_softc *sc = &psc->malo_sc; /* check if device was removed */ sc->malo_invalid = !bus_child_present(dev); malo_detach(sc); bus_generic_detach(dev); if (psc->malo_msi == 0) bus_teardown_intr(dev, psc->malo_res_irq[0], psc->malo_intrhand[0]); else { for (i = 0; i < MALO_MSI_MESSAGES; i++) bus_teardown_intr(dev, psc->malo_res_irq[i], psc->malo_intrhand[i]); pci_release_msi(dev); } bus_release_resources(dev, psc->malo_irq_spec, psc->malo_res_irq); bus_dma_tag_destroy(sc->malo_dmat); bus_release_resources(dev, psc->malo_mem_spec, psc->malo_res_mem); return (0); }
static void vtpci_free_interrupts(struct vtpci_softc *sc) { device_t dev; struct vtpci_intr_resource *ires; int i; dev = sc->vtpci_dev; sc->vtpci_nintr_res = 0; if (sc->vtpci_flags & (VIRTIO_PCI_FLAG_MSI | VIRTIO_PCI_FLAG_MSIX)) { pci_release_msi(dev); sc->vtpci_flags &= ~(VIRTIO_PCI_FLAG_MSI | VIRTIO_PCI_FLAG_MSIX | VIRTIO_PCI_FLAG_SHARED_MSIX); } for (i = 0; i < 1 + VIRTIO_MAX_VIRTQUEUES; i++) { ires = &sc->vtpci_intr_res[i]; if (ires->intrhand != NULL) { bus_teardown_intr(dev, ires->irq, ires->intrhand); ires->intrhand = NULL; } if (ires->irq != NULL) { bus_release_resource(dev, SYS_RES_IRQ, ires->rid, ires->irq); ires->irq = NULL; } ires->rid = -1; } }
static void ath10k_pci_free_irq(struct ath10k_pci *ar_pci) { struct ath10k *ar = &ar_pci->sc_sc; device_t dev = ar->sc_dev; int i; if (ar_pci->num_msi_intrs >= 1) { /* MSI/MSIX */ for (i = 0; i < ar_pci->num_msi_intrs; i++) { if (ar_pci->sc_ih[i] != NULL) bus_teardown_intr(dev, ar_pci->sc_irq[i], ar_pci->sc_ih[i]); if (ar_pci->sc_irq[i] != NULL) bus_release_resource(dev, SYS_RES_IRQ, i + 1, ar_pci->sc_irq[i]); } pci_release_msi(dev); } else { /* Legacy */ if (ar_pci->sc_ih[0] != NULL) bus_teardown_intr(dev, ar_pci->sc_irq[0], ar_pci->sc_ih[0]); if (ar_pci->sc_irq[0] != NULL) bus_release_resource(dev, SYS_RES_IRQ, 0, ar_pci->sc_irq[0]); } }
static int bhndb_pci_detach(device_t dev) { struct bhndb_pci_softc *sc; int error; sc = device_get_softc(dev); /* Attempt to detach our children */ if ((error = bus_generic_detach(dev))) return (error); /* Perform generic bridge detach */ if ((error = bhndb_generic_detach(dev))) return (error); /* Disable clocks (if required by this hardware) */ if ((error = bhndb_disable_pci_clocks(sc->dev))) return (error); /* Free our interrupt resources */ bhndb_free_intr_isrc(sc->isrc); /* Release MSI interrupts */ if (sc->msi_count > 0) pci_release_msi(sc->parent); /* Disable PCI bus mastering */ pci_disable_busmaster(sc->parent); BHNDB_PCI_LOCK_DESTROY(sc); return (0); }
/** * Attempt to allocate MSI interrupts, returning the count in @p msi_count * on success. */ static int bhndb_pci_alloc_msi(struct bhndb_pci_softc *sc, int *msi_count) { int error, count; /* Is MSI available? */ if (pci_msi_count(sc->parent) < BHNDB_PCI_MSI_COUNT) return (ENXIO); /* Allocate expected message count */ count = BHNDB_PCI_MSI_COUNT; if ((error = pci_alloc_msi(sc->parent, &count))) { device_printf(sc->dev, "failed to allocate MSI interrupts: " "%d\n", error); return (error); } if (count < BHNDB_PCI_MSI_COUNT) { pci_release_msi(sc->parent); return (ENXIO); } *msi_count = count; return (0); }
static void mpr_pci_free(struct mpr_softc *sc) { int i; if (sc->mpr_parent_dmat != NULL) { bus_dma_tag_destroy(sc->mpr_parent_dmat); } if (sc->mpr_flags & MPR_FLAGS_MSI) { for (i = 0; i < MPR_MSI_COUNT; i++) { if (sc->mpr_irq[i] != NULL) { bus_teardown_intr(sc->mpr_dev, sc->mpr_irq[i], sc->mpr_intrhand[i]); bus_release_resource(sc->mpr_dev, SYS_RES_IRQ, sc->mpr_irq_rid[i], sc->mpr_irq[i]); } } pci_release_msi(sc->mpr_dev); } if (sc->mpr_flags & MPR_FLAGS_INTX) { bus_teardown_intr(sc->mpr_dev, sc->mpr_irq[0], sc->mpr_intrhand[0]); bus_release_resource(sc->mpr_dev, SYS_RES_IRQ, sc->mpr_irq_rid[0], sc->mpr_irq[0]); } if (sc->mpr_regs_resource != NULL) { bus_release_resource(sc->mpr_dev, SYS_RES_MEMORY, sc->mpr_regs_rid, sc->mpr_regs_resource); } return; }
/* * Free bus resources */ static void mpt_free_bus_resources(struct mpt_softc *mpt) { if (mpt->ih) { bus_teardown_intr(mpt->dev, mpt->pci_irq, mpt->ih); mpt->ih = NULL; } if (mpt->pci_irq) { bus_release_resource(mpt->dev, SYS_RES_IRQ, rman_get_rid(mpt->pci_irq), mpt->pci_irq); mpt->pci_irq = NULL; } if (mpt->pci_msi_count) { pci_release_msi(mpt->dev); mpt->pci_msi_count = 0; } if (mpt->pci_pio_reg) { bus_release_resource(mpt->dev, SYS_RES_IOPORT, rman_get_rid(mpt->pci_pio_reg), mpt->pci_pio_reg); mpt->pci_pio_reg = NULL; } if (mpt->pci_reg) { bus_release_resource(mpt->dev, SYS_RES_MEMORY, rman_get_rid(mpt->pci_reg), mpt->pci_reg); mpt->pci_reg = NULL; } MPT_LOCK_DESTROY(mpt); }
static int ntb_setup_interrupts(struct ntb_softc *ntb) { uint32_t desired_vectors, num_vectors; uint64_t mask; int rc; ntb->allocated_interrupts = 0; /* * On SOC, disable all interrupts. On XEON, disable all but Link * Interrupt. The rest will be unmasked as callbacks are registered. */ mask = 0; if (ntb->type == NTB_XEON) mask = (1 << XEON_LINK_DB); db_iowrite(ntb, ntb->reg_ofs.ldb_mask, ~mask); num_vectors = desired_vectors = MIN(pci_msix_count(ntb->device), ntb->limits.max_db_bits); if (desired_vectors >= 1) { rc = pci_alloc_msix(ntb->device, &num_vectors); if (ntb_force_remap_mode != 0 && rc == 0 && num_vectors == desired_vectors) num_vectors--; if (rc == 0 && num_vectors < desired_vectors) { rc = ntb_remap_msix(ntb->device, desired_vectors, num_vectors); if (rc == 0) num_vectors = desired_vectors; else pci_release_msi(ntb->device); } if (rc != 0) num_vectors = 1; } else num_vectors = 1; ntb_create_callbacks(ntb, num_vectors); if (ntb->type == NTB_XEON) rc = ntb_setup_xeon_msix(ntb, num_vectors); else rc = ntb_setup_soc_msix(ntb, num_vectors); if (rc != 0) device_printf(ntb->device, "Error allocating MSI-X interrupts: %d\n", rc); if (ntb->type == NTB_XEON && rc == ENOSPC) rc = ntb_setup_legacy_interrupt(ntb); return (rc); }
static int uart_pci_detach(device_t dev) { struct uart_softc *sc; sc = device_get_softc(dev); if (sc->sc_irid != 0) pci_release_msi(dev); return (uart_bus_detach(dev)); }
static void mfi_pci_free(struct mfi_softc *sc) { if (sc->mfi_regs_resource != NULL) { bus_release_resource(sc->mfi_dev, SYS_RES_MEMORY, sc->mfi_regs_rid, sc->mfi_regs_resource); } if (sc->mfi_irq_rid != 0) pci_release_msi(sc->mfi_dev); return; }
static int vga_pci_release_msi(device_t dev, device_t child) { struct vga_pci_softc *sc; int error; sc = device_get_softc(dev); if (sc->vga_msi_child != child) return (ENXIO); error = pci_release_msi(dev); if (error == 0) sc->vga_msi_child = NULL; return (error); }
static int siba_bwn_release_msi(device_t dev, device_t child) { struct siba_bwn_softc *ssc; int error; ssc = device_get_softc(dev); if (ssc->ssc_msi_child != child) return (ENXIO); error = pci_release_msi(dev); if (error == 0) ssc->ssc_msi_child = NULL; return (error); }
static int ioat_teardown_intr(struct ioat_softc *ioat) { if (ioat->tag != NULL) bus_teardown_intr(ioat->device, ioat->res, ioat->tag); if (ioat->res != NULL) bus_release_resource(ioat->device, SYS_RES_IRQ, rman_get_rid(ioat->res), ioat->res); pci_release_msi(ioat->device); return (0); }
static int ismt_detach(device_t dev) { struct ismt_softc *sc; int error; ISMT_DEBUG(dev, "%s\n", __func__); sc = device_get_softc(dev); error = bus_generic_detach(dev); if (error) return (error); device_delete_child(dev, sc->smbdev); if (sc->intr_handle != NULL) { bus_teardown_intr(dev, sc->intr_res, sc->intr_handle); sc->intr_handle = NULL; } if (sc->intr_res != NULL) { bus_release_resource(dev, SYS_RES_IRQ, sc->intr_rid, sc->intr_res); sc->intr_res = NULL; } if (sc->using_msi == 1) pci_release_msi(dev); if (sc->mmio_res != NULL) { bus_release_resource(dev, SYS_RES_MEMORY, sc->mmio_rid, sc->mmio_res); sc->mmio_res = NULL; } bus_dmamap_unload(sc->desc_dma_tag, sc->desc_dma_map); bus_dmamap_unload(sc->dma_buffer_dma_tag, sc->dma_buffer_dma_map); bus_dmamem_free(sc->desc_dma_tag, sc->desc, sc->desc_dma_map); bus_dmamem_free(sc->dma_buffer_dma_tag, sc->dma_buffer, sc->dma_buffer_dma_map); bus_dma_tag_destroy(sc->desc_dma_tag); bus_dma_tag_destroy(sc->dma_buffer_dma_tag); pci_disable_busmaster(dev); return 0; }
static int sfxge_intr_setup_msix(struct sfxge_softc *sc) { struct sfxge_intr *intr; struct resource *resp; device_t dev; int count; int rid; dev = sc->dev; intr = &sc->intr; /* Check if MSI-X is available. */ count = pci_msix_count(dev); if (count == 0) return (EINVAL); /* Limit the number of interrupts to the number of CPUs. */ if (count > mp_ncpus) count = mp_ncpus; /* Not very likely these days... */ if (count > EFX_MAXRSS) count = EFX_MAXRSS; rid = PCIR_BAR(4); resp = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (resp == NULL) return (ENOMEM); if (pci_alloc_msix(dev, &count) != 0) { bus_release_resource(dev, SYS_RES_MEMORY, rid, resp); return (ENOMEM); } /* Allocate interrupt handlers. */ if (sfxge_intr_alloc(sc, count) != 0) { bus_release_resource(dev, SYS_RES_MEMORY, rid, resp); pci_release_msi(dev); return (ENOMEM); } intr->type = EFX_INTR_MESSAGE; intr->n_alloc = count; intr->msix_res = resp; return (0); }
int drm_release(device_t kdev) { struct drm_device *dev; dev = device_get_softc(kdev); drm_unload(dev); if (dev->irqr) { bus_release_resource(dev->dev, SYS_RES_IRQ, dev->irqrid, dev->irqr); if (dev->irq_type == PCI_INTR_TYPE_MSI) { pci_release_msi(dev->dev); DRM_INFO("MSI released\n"); } } return (0); }
static int sfxge_intr_setup_msix(struct sfxge_softc *sc) { struct sfxge_intr *intr; struct resource *resp; device_t dev; int count; int rid; dev = sc->dev; intr = &sc->intr; /* Check if MSI-X is available. */ count = pci_msix_count(dev); if (count == 0) return (EINVAL); /* Do not try to allocate more than already estimated EVQ maximum */ KASSERT(sc->evq_max > 0, ("evq_max is zero")); count = MIN(count, sc->evq_max); rid = PCIR_BAR(4); resp = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (resp == NULL) return (ENOMEM); if (pci_alloc_msix(dev, &count) != 0) { bus_release_resource(dev, SYS_RES_MEMORY, rid, resp); return (ENOMEM); } /* Allocate interrupt handlers. */ if (sfxge_intr_alloc(sc, count) != 0) { bus_release_resource(dev, SYS_RES_MEMORY, rid, resp); pci_release_msi(dev); return (ENOMEM); } intr->type = EFX_INTR_MESSAGE; intr->n_alloc = count; intr->msix_res = resp; return (0); }
static int xhci_pci_detach(device_t self) { struct xhci_softc *sc = device_get_softc(self); device_t bdev; if (sc->sc_bus.bdev != NULL) { bdev = sc->sc_bus.bdev; device_detach(bdev); device_delete_child(self, bdev); } /* during module unload there are lots of children leftover */ device_delete_children(self); if (sc->sc_io_res) { usb_callout_drain(&sc->sc_callout); xhci_halt_controller(sc); } pci_disable_busmaster(self); if (sc->sc_irq_res && sc->sc_intr_hdl) { bus_teardown_intr(self, sc->sc_irq_res, sc->sc_intr_hdl); sc->sc_intr_hdl = NULL; } if (sc->sc_irq_res) { if (sc->sc_irq_rid == 1) pci_release_msi(self); bus_release_resource(self, SYS_RES_IRQ, sc->sc_irq_rid, sc->sc_irq_res); sc->sc_irq_res = NULL; } if (sc->sc_io_res) { bus_release_resource(self, SYS_RES_MEMORY, PCI_XHCI_CBMEM, sc->sc_io_res); sc->sc_io_res = NULL; } xhci_uninit(sc); return (0); }
static void ntb_teardown_interrupts(struct ntb_softc *ntb) { struct ntb_int_info *current_int; int i; for (i = 0; i < ntb->allocated_interrupts; i++) { current_int = &ntb->int_info[i]; if (current_int->tag != NULL) bus_teardown_intr(ntb->device, current_int->res, current_int->tag); if (current_int->res != NULL) bus_release_resource(ntb->device, SYS_RES_IRQ, rman_get_rid(current_int->res), current_int->res); } ntb_free_callbacks(ntb); pci_release_msi(ntb->device); }
static void mps_pci_free(struct mps_softc *sc) { if (sc->mps_parent_dmat != NULL) { bus_dma_tag_destroy(sc->mps_parent_dmat); } bus_teardown_intr(sc->mps_dev, sc->mps_irq[0], sc->mps_intrhand[0]); bus_release_resource(sc->mps_dev, SYS_RES_IRQ, sc->mps_irq_rid[0], sc->mps_irq[0]); if (sc->mps_irq_type[0] == PCI_INTR_TYPE_MSI) pci_release_msi(sc->mps_dev); if (sc->mps_regs_resource != NULL) { bus_release_resource(sc->mps_dev, SYS_RES_MEMORY, sc->mps_regs_rid, sc->mps_regs_resource); } return; }
void sfxge_intr_fini(struct sfxge_softc *sc) { struct sfxge_intr_hdl *table; struct sfxge_intr *intr; efsys_mem_t *esmp; device_t dev; int i; dev = sc->dev; intr = &sc->intr; esmp = &intr->status; table = intr->table; KASSERT(intr->state == SFXGE_INTR_INITIALIZED, ("intr->state != SFXGE_INTR_INITIALIZED")); /* Free DMA memory. */ sfxge_dma_free(esmp); /* Free interrupt handles. */ for (i = 0; i < intr->n_alloc; i++) bus_release_resource(dev, SYS_RES_IRQ, table[i].eih_rid, table[i].eih_res); if (table[0].eih_rid != 0) pci_release_msi(dev); if (intr->msix_res != NULL) sfxge_intr_teardown_msix(sc); /* Free the handle table */ free(table, M_SFXGE); intr->table = NULL; intr->n_alloc = 0; /* Clear the interrupt type */ intr->type = EFX_INTR_INVALID; intr->state = SFXGE_INTR_UNINITIALIZED; }