diff options
Diffstat (limited to 'drivers/pci/msi.c')
| -rw-r--r-- | drivers/pci/msi.c | 26 | 
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 5099636a6e5..00cc78c7aa0 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -845,6 +845,32 @@ int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec)  }  EXPORT_SYMBOL(pci_enable_msi_block); +int pci_enable_msi_block_auto(struct pci_dev *dev, unsigned int *maxvec) +{ +	int ret, pos, nvec; +	u16 msgctl; + +	pos = pci_find_capability(dev, PCI_CAP_ID_MSI); +	if (!pos) +		return -EINVAL; + +	pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &msgctl); +	ret = 1 << ((msgctl & PCI_MSI_FLAGS_QMASK) >> 1); + +	if (maxvec) +		*maxvec = ret; + +	do { +		nvec = ret; +		ret = pci_enable_msi_block(dev, nvec); +	} while (ret > 0); + +	if (ret < 0) +		return ret; +	return nvec; +} +EXPORT_SYMBOL(pci_enable_msi_block_auto); +  void pci_msi_shutdown(struct pci_dev *dev)  {  	struct msi_desc *desc;  |