forked from mirrors/linux
		
	PCI/MSI: Add pci_msix_vec_count()
This creates an MSI-X counterpart for pci_msi_vec_count(). Device drivers can use this function to obtain maximum number of MSI-X interrupts the device supports and use that number in a subsequent call to pci_enable_msix(). pci_msix_vec_count() supersedes pci_msix_table_size() and returns a negative errno if device does not support MSI-X interrupts. After this update, callers must always check the returned value. The only user of pci_msix_table_size() was the PCI-Express port driver, which is also updated by this change. Signed-off-by: Alexander Gordeev <agordeev@redhat.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Tejun Heo <tj@kernel.org>
This commit is contained in:
		
							parent
							
								
									7b92b4f61e
								
							
						
					
					
						commit
						ff1aa430a2
					
				
					 4 changed files with 33 additions and 11 deletions
				
			
		| 
						 | 
				
			
			@ -243,6 +243,19 @@ MSI-X Table.  This address is mapped by the PCI subsystem, and should not
 | 
			
		|||
be accessed directly by the device driver.  If the driver wishes to
 | 
			
		||||
mask or unmask an interrupt, it should call disable_irq() / enable_irq().
 | 
			
		||||
 | 
			
		||||
4.3.4 pci_msix_vec_count
 | 
			
		||||
 | 
			
		||||
int pci_msix_vec_count(struct pci_dev *dev)
 | 
			
		||||
 | 
			
		||||
This function could be used to retrieve number of entries in the device
 | 
			
		||||
MSI-X table.
 | 
			
		||||
 | 
			
		||||
If this function returns a negative number, it indicates the device is
 | 
			
		||||
not capable of sending MSI-Xs.
 | 
			
		||||
 | 
			
		||||
If this function returns a positive number, it indicates the maximum
 | 
			
		||||
number of MSI-X interrupt vectors that could be allocated.
 | 
			
		||||
 | 
			
		||||
4.4 Handling devices implementing both MSI and MSI-X capabilities
 | 
			
		||||
 | 
			
		||||
If a device implements both MSI and MSI-X capabilities, it can
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -948,19 +948,25 @@ void pci_disable_msi(struct pci_dev *dev)
 | 
			
		|||
EXPORT_SYMBOL(pci_disable_msi);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * pci_msix_table_size - return the number of device's MSI-X table entries
 | 
			
		||||
 * pci_msix_vec_count - return the number of device's MSI-X table entries
 | 
			
		||||
 * @dev: pointer to the pci_dev data structure of MSI-X device function
 | 
			
		||||
 */
 | 
			
		||||
int pci_msix_table_size(struct pci_dev *dev)
 | 
			
		||||
 | 
			
		||||
 * This function returns the number of device's MSI-X table entries and
 | 
			
		||||
 * therefore the number of MSI-X vectors device is capable of sending.
 | 
			
		||||
 * It returns a negative errno if the device is not capable of sending MSI-X
 | 
			
		||||
 * interrupts.
 | 
			
		||||
 **/
 | 
			
		||||
int pci_msix_vec_count(struct pci_dev *dev)
 | 
			
		||||
{
 | 
			
		||||
	u16 control;
 | 
			
		||||
 | 
			
		||||
	if (!dev->msix_cap)
 | 
			
		||||
		return 0;
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
	pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control);
 | 
			
		||||
	return msix_table_size(control);
 | 
			
		||||
}
 | 
			
		||||
EXPORT_SYMBOL(pci_msix_vec_count);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * pci_enable_msix - configure device's MSI-X capability structure
 | 
			
		||||
| 
						 | 
				
			
			@ -989,7 +995,9 @@ int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec)
 | 
			
		|||
	if (status)
 | 
			
		||||
		return status;
 | 
			
		||||
 | 
			
		||||
	nr_entries = pci_msix_table_size(dev);
 | 
			
		||||
	nr_entries = pci_msix_vec_count(dev);
 | 
			
		||||
	if (nr_entries < 0)
 | 
			
		||||
		return nr_entries;
 | 
			
		||||
	if (nvec > nr_entries)
 | 
			
		||||
		return nr_entries;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -79,9 +79,10 @@ static int pcie_port_enable_msix(struct pci_dev *dev, int *vectors, int mask)
 | 
			
		|||
	u16 reg16;
 | 
			
		||||
	u32 reg32;
 | 
			
		||||
 | 
			
		||||
	nr_entries = pci_msix_table_size(dev);
 | 
			
		||||
	if (!nr_entries)
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	nr_entries = pci_msix_vec_count(dev);
 | 
			
		||||
	if (nr_entries < 0)
 | 
			
		||||
		return nr_entries;
 | 
			
		||||
	BUG_ON(!nr_entries);
 | 
			
		||||
	if (nr_entries > PCIE_PORT_MAX_MSIX_ENTRIES)
 | 
			
		||||
		nr_entries = PCIE_PORT_MAX_MSIX_ENTRIES;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1169,9 +1169,9 @@ static inline void pci_msi_shutdown(struct pci_dev *dev)
 | 
			
		|||
static inline void pci_disable_msi(struct pci_dev *dev)
 | 
			
		||||
{ }
 | 
			
		||||
 | 
			
		||||
static inline int pci_msix_table_size(struct pci_dev *dev)
 | 
			
		||||
static inline int pci_msix_vec_count(struct pci_dev *dev)
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
	return -ENOSYS;
 | 
			
		||||
}
 | 
			
		||||
static inline int pci_enable_msix(struct pci_dev *dev,
 | 
			
		||||
				  struct msix_entry *entries, int nvec)
 | 
			
		||||
| 
						 | 
				
			
			@ -1198,7 +1198,7 @@ int pci_msi_vec_count(struct pci_dev *dev);
 | 
			
		|||
int pci_enable_msi_block(struct pci_dev *dev, int nvec);
 | 
			
		||||
void pci_msi_shutdown(struct pci_dev *dev);
 | 
			
		||||
void pci_disable_msi(struct pci_dev *dev);
 | 
			
		||||
int pci_msix_table_size(struct pci_dev *dev);
 | 
			
		||||
int pci_msix_vec_count(struct pci_dev *dev);
 | 
			
		||||
int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec);
 | 
			
		||||
void pci_msix_shutdown(struct pci_dev *dev);
 | 
			
		||||
void pci_disable_msix(struct pci_dev *dev);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue