This update is needed to facilitate a forthcoming re-design MSI/MSI-X interrupts enabling pattern.
Device drivers will use this interface to obtain maximum number of MSI interrupts the device supports and use that value in the following call to pci_enable_msi_block() interface. Signed-off-by: Alexander Gordeev <[email protected]> --- Documentation/PCI/MSI-HOWTO.txt | 15 +++++++++++++++ drivers/pci/msi.c | 33 +++++++++++++++++++++------------ include/linux/pci.h | 6 ++++++ 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/Documentation/PCI/MSI-HOWTO.txt b/Documentation/PCI/MSI-HOWTO.txt index 35b2d64..1f37ce2 100644 --- a/Documentation/PCI/MSI-HOWTO.txt +++ b/Documentation/PCI/MSI-HOWTO.txt @@ -169,6 +169,21 @@ on any interrupt for which it previously called request_irq(). Failure to do so results in a BUG_ON(), leaving the device with MSI enabled and thus leaking its vector. +4.2.5 pci_get_msi_cap + +int pci_get_msi_cap(struct pci_dev *dev) + +This function could be used to retrieve the number of MSI vectors the +device requested (via the Multiple Message Capable register). The MSI +specification only allows the returned value to be a power of two, +up to a maximum of 2^5 (32). + +If this function returns a negative number, it indicates the device is +not capable of sending MSIs. + +If this function returns a positive number, it indicates the maximum +number of MSI interrupt vectors that could be allocated. + 4.3 Using MSI-X The MSI-X capability is much more flexible than the MSI capability. diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 875c353..ca59bfc 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -812,6 +812,21 @@ static int pci_msi_check_device(struct pci_dev *dev, int nvec, int type) return 0; } +int pci_get_msi_cap(struct pci_dev *dev) +{ + int ret; + u16 msgctl; + + if (!dev->msi_cap) + return -EINVAL; + + pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &msgctl); + ret = 1 << ((msgctl & PCI_MSI_FLAGS_QMASK) >> 1); + + return ret; +} +EXPORT_SYMBOL(pci_get_msi_cap); + /** * pci_enable_msi_block - configure device's MSI capability structure * @dev: device to configure @@ -828,13 +843,10 @@ static int pci_msi_check_device(struct pci_dev *dev, int nvec, int type) int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec) { int status, maxvec; - u16 msgctl; - if (!dev->msi_cap) - return -EINVAL; - - pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &msgctl); - maxvec = 1 << ((msgctl & PCI_MSI_FLAGS_QMASK) >> 1); + maxvec = pci_get_msi_cap(dev); + if (maxvec < 0) + return maxvec; if (nvec > maxvec) return maxvec; @@ -859,13 +871,10 @@ EXPORT_SYMBOL(pci_enable_msi_block); int pci_enable_msi_block_auto(struct pci_dev *dev, unsigned int *maxvec) { int ret, nvec; - u16 msgctl; - if (!dev->msi_cap) - return -EINVAL; - - pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &msgctl); - ret = 1 << ((msgctl & PCI_MSI_FLAGS_QMASK) >> 1); + ret = pci_get_msi_cap(dev); + if (ret < 0) + return ret; if (maxvec) *maxvec = ret; diff --git a/include/linux/pci.h b/include/linux/pci.h index da172f9..2fa92ef 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1144,6 +1144,11 @@ struct msix_entry { #ifndef CONFIG_PCI_MSI +static inline int pci_get_msi_cap(struct pci_dev *dev) +{ + return -1; +} + static inline int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec) { return -1; @@ -1185,6 +1190,7 @@ static inline int pci_msi_enabled(void) return 0; } #else +int pci_get_msi_cap(struct pci_dev *dev); int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec); int pci_enable_msi_block_auto(struct pci_dev *dev, unsigned int *maxvec); void pci_msi_shutdown(struct pci_dev *dev); -- 1.7.7.6 ------------------------------------------------------------------------------ October Webinars: Code for Performance Free Intel webinars can help you accelerate application performance. Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from the latest Intel processors and coprocessors. See abstracts and register > http://pubads.g.doubleclick.net/gampad/clk?id=60134791&iu=/4140/ostg.clktrk _______________________________________________ E1000-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/e1000-devel To learn more about Intel® Ethernet, visit http://communities.intel.com/community/wired
