aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/PCI/MSI-HOWTO.txt13
-rw-r--r--drivers/pci/msi.c18
-rw-r--r--drivers/pci/pcie/portdrv_core.c7
-rw-r--r--include/linux/pci.h6
4 files changed, 33 insertions, 11 deletions
diff --git a/Documentation/PCI/MSI-HOWTO.txt b/Documentation/PCI/MSI-HOWTO.txt
index aa4ad987510d..b58f4a4d14bb 100644
--- a/Documentation/PCI/MSI-HOWTO.txt
+++ b/Documentation/PCI/MSI-HOWTO.txt
@@ -243,6 +243,19 @@ MSI-X Table. This address is mapped by the PCI subsystem, and should not
243be accessed directly by the device driver. If the driver wishes to 243be accessed directly by the device driver. If the driver wishes to
244mask or unmask an interrupt, it should call disable_irq() / enable_irq(). 244mask or unmask an interrupt, it should call disable_irq() / enable_irq().
245 245
2464.3.4 pci_msix_vec_count
247
248int pci_msix_vec_count(struct pci_dev *dev)
249
250This function could be used to retrieve number of entries in the device
251MSI-X table.
252
253If this function returns a negative number, it indicates the device is
254not capable of sending MSI-Xs.
255
256If this function returns a positive number, it indicates the maximum
257number of MSI-X interrupt vectors that could be allocated.
258
2464.4 Handling devices implementing both MSI and MSI-X capabilities 2594.4 Handling devices implementing both MSI and MSI-X capabilities
247 260
248If a device implements both MSI and MSI-X capabilities, it can 261If a device implements both MSI and MSI-X capabilities, it can
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 76507ab13beb..bd18ecf74c55 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -948,19 +948,25 @@ void pci_disable_msi(struct pci_dev *dev)
948EXPORT_SYMBOL(pci_disable_msi); 948EXPORT_SYMBOL(pci_disable_msi);
949 949
950/** 950/**
951 * pci_msix_table_size - return the number of device's MSI-X table entries 951 * pci_msix_vec_count - return the number of device's MSI-X table entries
952 * @dev: pointer to the pci_dev data structure of MSI-X device function 952 * @dev: pointer to the pci_dev data structure of MSI-X device function
953 */ 953
954int pci_msix_table_size(struct pci_dev *dev) 954 * This function returns the number of device's MSI-X table entries and
955 * therefore the number of MSI-X vectors device is capable of sending.
956 * It returns a negative errno if the device is not capable of sending MSI-X
957 * interrupts.
958 **/
959int pci_msix_vec_count(struct pci_dev *dev)
955{ 960{
956 u16 control; 961 u16 control;
957 962
958 if (!dev->msix_cap) 963 if (!dev->msix_cap)
959 return 0; 964 return -EINVAL;
960 965
961 pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control); 966 pci_read_config_word(dev, dev->msix_cap + PCI_MSIX_FLAGS, &control);
962 return msix_table_size(control); 967 return msix_table_size(control);
963} 968}
969EXPORT_SYMBOL(pci_msix_vec_count);
964 970
965/** 971/**
966 * pci_enable_msix - configure device's MSI-X capability structure 972 * 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)
989 if (status) 995 if (status)
990 return status; 996 return status;
991 997
992 nr_entries = pci_msix_table_size(dev); 998 nr_entries = pci_msix_vec_count(dev);
999 if (nr_entries < 0)
1000 return nr_entries;
993 if (nvec > nr_entries) 1001 if (nvec > nr_entries)
994 return nr_entries; 1002 return nr_entries;
995 1003
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index 0b6e76604068..4ab719826dd7 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -79,9 +79,10 @@ static int pcie_port_enable_msix(struct pci_dev *dev, int *vectors, int mask)
79 u16 reg16; 79 u16 reg16;
80 u32 reg32; 80 u32 reg32;
81 81
82 nr_entries = pci_msix_table_size(dev); 82 nr_entries = pci_msix_vec_count(dev);
83 if (!nr_entries) 83 if (nr_entries < 0)
84 return -EINVAL; 84 return nr_entries;
85 BUG_ON(!nr_entries);
85 if (nr_entries > PCIE_PORT_MAX_MSIX_ENTRIES) 86 if (nr_entries > PCIE_PORT_MAX_MSIX_ENTRIES)
86 nr_entries = PCIE_PORT_MAX_MSIX_ENTRIES; 87 nr_entries = PCIE_PORT_MAX_MSIX_ENTRIES;
87 88
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 86dcf006adcc..cf6125ba649d 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1169,9 +1169,9 @@ static inline void pci_msi_shutdown(struct pci_dev *dev)
1169static inline void pci_disable_msi(struct pci_dev *dev) 1169static inline void pci_disable_msi(struct pci_dev *dev)
1170{ } 1170{ }
1171 1171
1172static inline int pci_msix_table_size(struct pci_dev *dev) 1172static inline int pci_msix_vec_count(struct pci_dev *dev)
1173{ 1173{
1174 return 0; 1174 return -ENOSYS;
1175} 1175}
1176static inline int pci_enable_msix(struct pci_dev *dev, 1176static inline int pci_enable_msix(struct pci_dev *dev,
1177 struct msix_entry *entries, int nvec) 1177 struct msix_entry *entries, int nvec)
@@ -1198,7 +1198,7 @@ int pci_msi_vec_count(struct pci_dev *dev);
1198int pci_enable_msi_block(struct pci_dev *dev, int nvec); 1198int pci_enable_msi_block(struct pci_dev *dev, int nvec);
1199void pci_msi_shutdown(struct pci_dev *dev); 1199void pci_msi_shutdown(struct pci_dev *dev);
1200void pci_disable_msi(struct pci_dev *dev); 1200void pci_disable_msi(struct pci_dev *dev);
1201int pci_msix_table_size(struct pci_dev *dev); 1201int pci_msix_vec_count(struct pci_dev *dev);
1202int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec); 1202int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec);
1203void pci_msix_shutdown(struct pci_dev *dev); 1203void pci_msix_shutdown(struct pci_dev *dev);
1204void pci_disable_msix(struct pci_dev *dev); 1204void pci_disable_msix(struct pci_dev *dev);