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
 | 
					be accessed directly by the device driver.  If the driver wishes to
 | 
				
			||||||
mask or unmask an interrupt, it should call disable_irq() / enable_irq().
 | 
					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
 | 
					4.4 Handling devices implementing both MSI and MSI-X capabilities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
If a device implements both MSI and MSI-X capabilities, it can
 | 
					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);
 | 
					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
 | 
					 * @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;
 | 
						u16 control;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!dev->msix_cap)
 | 
						if (!dev->msix_cap)
 | 
				
			||||||
		return 0;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control);
 | 
						pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control);
 | 
				
			||||||
	return msix_table_size(control);
 | 
						return msix_table_size(control);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(pci_msix_vec_count);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * pci_enable_msix - configure device's MSI-X capability structure
 | 
					 * 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)
 | 
						if (status)
 | 
				
			||||||
		return 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)
 | 
						if (nvec > nr_entries)
 | 
				
			||||||
		return 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;
 | 
						u16 reg16;
 | 
				
			||||||
	u32 reg32;
 | 
						u32 reg32;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	nr_entries = pci_msix_table_size(dev);
 | 
						nr_entries = pci_msix_vec_count(dev);
 | 
				
			||||||
	if (!nr_entries)
 | 
						if (nr_entries < 0)
 | 
				
			||||||
		return -EINVAL;
 | 
							return nr_entries;
 | 
				
			||||||
 | 
						BUG_ON(!nr_entries);
 | 
				
			||||||
	if (nr_entries > PCIE_PORT_MAX_MSIX_ENTRIES)
 | 
						if (nr_entries > PCIE_PORT_MAX_MSIX_ENTRIES)
 | 
				
			||||||
		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 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,
 | 
					static inline int pci_enable_msix(struct pci_dev *dev,
 | 
				
			||||||
				  struct msix_entry *entries, int nvec)
 | 
									  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);
 | 
					int pci_enable_msi_block(struct pci_dev *dev, int nvec);
 | 
				
			||||||
void pci_msi_shutdown(struct pci_dev *dev);
 | 
					void pci_msi_shutdown(struct pci_dev *dev);
 | 
				
			||||||
void pci_disable_msi(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);
 | 
					int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec);
 | 
				
			||||||
void pci_msix_shutdown(struct pci_dev *dev);
 | 
					void pci_msix_shutdown(struct pci_dev *dev);
 | 
				
			||||||
void pci_disable_msix(struct pci_dev *dev);
 | 
					void pci_disable_msix(struct pci_dev *dev);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue