diff options
| -rw-r--r-- | Documentation/PCI/MSI-HOWTO.txt | 13 | ||||
| -rw-r--r-- | drivers/pci/msi.c | 18 | ||||
| -rw-r--r-- | drivers/pci/pcie/portdrv_core.c | 7 | ||||
| -rw-r--r-- | include/linux/pci.h | 6 |
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 | |||
| 243 | be accessed directly by the device driver. If the driver wishes to | 243 | be accessed directly by the device driver. If the driver wishes to |
| 244 | mask or unmask an interrupt, it should call disable_irq() / enable_irq(). | 244 | mask or unmask an interrupt, it should call disable_irq() / enable_irq(). |
| 245 | 245 | ||
| 246 | 4.3.4 pci_msix_vec_count | ||
| 247 | |||
| 248 | int pci_msix_vec_count(struct pci_dev *dev) | ||
| 249 | |||
| 250 | This function could be used to retrieve number of entries in the device | ||
| 251 | MSI-X table. | ||
| 252 | |||
| 253 | If this function returns a negative number, it indicates the device is | ||
| 254 | not capable of sending MSI-Xs. | ||
| 255 | |||
| 256 | If this function returns a positive number, it indicates the maximum | ||
| 257 | number of MSI-X interrupt vectors that could be allocated. | ||
| 258 | |||
| 246 | 4.4 Handling devices implementing both MSI and MSI-X capabilities | 259 | 4.4 Handling devices implementing both MSI and MSI-X capabilities |
| 247 | 260 | ||
| 248 | If a device implements both MSI and MSI-X capabilities, it can | 261 | If 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) | |||
| 948 | EXPORT_SYMBOL(pci_disable_msi); | 948 | EXPORT_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 | |
| 954 | int 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 | **/ | ||
| 959 | int 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 | } |
| 969 | EXPORT_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) | |||
| 1169 | static inline void pci_disable_msi(struct pci_dev *dev) | 1169 | static inline void pci_disable_msi(struct pci_dev *dev) |
| 1170 | { } | 1170 | { } |
| 1171 | 1171 | ||
| 1172 | static inline int pci_msix_table_size(struct pci_dev *dev) | 1172 | static inline int pci_msix_vec_count(struct pci_dev *dev) |
| 1173 | { | 1173 | { |
| 1174 | return 0; | 1174 | return -ENOSYS; |
| 1175 | } | 1175 | } |
| 1176 | static inline int pci_enable_msix(struct pci_dev *dev, | 1176 | static 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); | |||
| 1198 | int pci_enable_msi_block(struct pci_dev *dev, int nvec); | 1198 | int pci_enable_msi_block(struct pci_dev *dev, int nvec); |
| 1199 | void pci_msi_shutdown(struct pci_dev *dev); | 1199 | void pci_msi_shutdown(struct pci_dev *dev); |
| 1200 | void pci_disable_msi(struct pci_dev *dev); | 1200 | void pci_disable_msi(struct pci_dev *dev); |
| 1201 | int pci_msix_table_size(struct pci_dev *dev); | 1201 | int pci_msix_vec_count(struct pci_dev *dev); |
| 1202 | int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec); | 1202 | int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec); |
| 1203 | void pci_msix_shutdown(struct pci_dev *dev); | 1203 | void pci_msix_shutdown(struct pci_dev *dev); |
| 1204 | void pci_disable_msix(struct pci_dev *dev); | 1204 | void pci_disable_msix(struct pci_dev *dev); |
