示例#1
0
文件: ata-pci.c 项目: coyizumi/cs111
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;
}
示例#2
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);
}
示例#3
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;
}
示例#4
0
文件: ppt.c 项目: ele7enxxh/dtrace-pf
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;
}
示例#5
0
文件: ppt.c 项目: ele7enxxh/dtrace-pf
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;
}
示例#6
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;
}
示例#7
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);
}
示例#8
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);
}
示例#9
0
文件: ata-pci.c 项目: coyizumi/cs111
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;
}
示例#10
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);
}
示例#11
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;
	}
}
示例#12
0
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]);
	}
}
示例#13
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);
}
示例#14
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);
}
示例#15
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;
}
示例#16
0
/*
 * 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);
}
示例#17
0
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);
}
示例#18
0
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));
}
示例#19
0
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;
}
示例#20
0
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);
}
示例#21
0
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);
}
示例#22
0
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);
}
示例#23
0
文件: ismt.c 项目: 2asoft/freebsd
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;
}
示例#24
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);
}
示例#25
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);
}
示例#26
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);
}
示例#27
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);
}
示例#28
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);
}
示例#29
0
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;
}
示例#30
0
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;
}