FreeBSD/sys/dev/pci/pci.c
/* Release the MSI messages associated with this device. */
Release the MSI messages associated with this device.
Release the MSI messages associated with this device .
int
pci_release_msi_method(device_t dev, device_t child)
{
	struct pci_devinfo *dinfo = device_get_ivars(child);
	struct pcicfg_msi *msi = &dinfo->cfg.msi;
	struct resource_list_entry *rle;
	int error, i, irqs[32];
	error = pci_release_msix(dev, child);
	if (error != ENODEV)
		return (error);
	if (msi->msi_alloc == 0)
		return (ENODEV);
	KASSERT(msi->msi_alloc <= 32, ("more than 32 alloc'd messages"));
	if (msi->msi_handlers > 0)
		return (EBUSY);
	for (i = 0; i < msi->msi_alloc; i++) {
		rle = resource_list_find(&dinfo->resources, SYS_RES_IRQ, i + 1);
		KASSERT(rle != NULL, ("missing MSI resource"));
		if (rle->res != NULL)
			return (EBUSY);
		irqs[i] = rle->start;
	}
	KASSERT(!(msi->msi_ctrl & PCIM_MSICTRL_MSI_ENABLE),
	    ("%s: MSI still enabled", __func__));
	msi->msi_ctrl &= ~PCIM_MSICTRL_MME_MASK;
	pci_write_config(child, msi->msi_location + PCIR_MSI_CTRL,
	    msi->msi_ctrl, 2);
	PCIB_RELEASE_MSI(device_get_parent(dev), child, msi->msi_alloc, irqs);
	for (i = 0; i < msi->msi_alloc; i++)
		resource_list_delete(&dinfo->resources, SYS_RES_IRQ, i + 1);
	msi->msi_alloc = 0;
	msi->msi_addr = 0;
	msi->msi_data = 0;
	return (0);
}
int pci_release_msi_method ( device_t dev , device_t child ) { struct pci_devinfo * dinfo = device_get_ivars ( child ) ; struct pcicfg_msi * msi = & dinfo -> cfg . msi ; struct resource_list_entry * rle ; int error , i , irqs [ 32 ] ; error = pci_release_msix ( dev , child ) ; if ( error != ENODEV ) return ( error ) ; if ( msi -> msi_alloc == 0 ) return ( ENODEV ) ; KASSERT ( msi -> msi_alloc <= 32 , ( " " ) ) ; if ( msi -> msi_handlers > 0 ) return ( EBUSY ) ; for ( i = 0 ; i < msi -> msi_alloc ; i ++ ) { rle = resource_list_find ( & dinfo -> resources , SYS_RES_IRQ , i + 1 ) ; KASSERT ( rle != NULL , ( " " ) ) ; if ( rle -> res != NULL ) return ( EBUSY ) ; irqs [ i ] = rle -> start ; } KASSERT ( ! ( msi -> msi_ctrl & PCIM_MSICTRL_MSI_ENABLE ) , ( " " , __func__ ) ) ; msi -> msi_ctrl &= ~ PCIM_MSICTRL_MME_MASK ; pci_write_config ( child , msi -> msi_location + PCIR_MSI_CTRL , msi -> msi_ctrl , 2 ) ; PCIB_RELEASE_MSI ( device_get_parent ( dev ) , child , msi -> msi_alloc , irqs ) ; for ( i = 0 ; i < msi -> msi_alloc ; i ++ ) resource_list_delete ( & dinfo -> resources , SYS_RES_IRQ , i + 1 ) ; msi -> msi_alloc = 0 ; msi -> msi_addr = 0 ; msi -> msi_data = 0 ; return ( 0 ) ; }
Release the MSI messages associated with this device.
Release the MSI messages associated with this device .
/* Try MSI-X first. */ /* Do we have any messages to release? */ /* Make sure none of the resources are allocated. */ /* Update control register with 0 count. */ /* Release the messages. */ /* Update alloc count. */