diff options
-rw-r--r-- | drivers/pci/msi.c | 24 | ||||
-rw-r--r-- | include/linux/pci.h | 5 |
2 files changed, 24 insertions, 5 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index baba2eb5367d..08aedd5875b0 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -675,6 +675,23 @@ static int msi_free_irqs(struct pci_dev* dev) | |||
675 | } | 675 | } |
676 | 676 | ||
677 | /** | 677 | /** |
678 | * pci_msix_table_size - return the number of device's MSI-X table entries | ||
679 | * @dev: pointer to the pci_dev data structure of MSI-X device function | ||
680 | */ | ||
681 | int pci_msix_table_size(struct pci_dev *dev) | ||
682 | { | ||
683 | int pos; | ||
684 | u16 control; | ||
685 | |||
686 | pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); | ||
687 | if (!pos) | ||
688 | return 0; | ||
689 | |||
690 | pci_read_config_word(dev, msi_control_reg(pos), &control); | ||
691 | return multi_msix_capable(control); | ||
692 | } | ||
693 | |||
694 | /** | ||
678 | * pci_enable_msix - configure device's MSI-X capability structure | 695 | * pci_enable_msix - configure device's MSI-X capability structure |
679 | * @dev: pointer to the pci_dev data structure of MSI-X device function | 696 | * @dev: pointer to the pci_dev data structure of MSI-X device function |
680 | * @entries: pointer to an array of MSI-X entries | 697 | * @entries: pointer to an array of MSI-X entries |
@@ -691,9 +708,8 @@ static int msi_free_irqs(struct pci_dev* dev) | |||
691 | **/ | 708 | **/ |
692 | int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) | 709 | int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) |
693 | { | 710 | { |
694 | int status, pos, nr_entries; | 711 | int status, nr_entries; |
695 | int i, j; | 712 | int i, j; |
696 | u16 control; | ||
697 | 713 | ||
698 | if (!entries) | 714 | if (!entries) |
699 | return -EINVAL; | 715 | return -EINVAL; |
@@ -702,9 +718,7 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) | |||
702 | if (status) | 718 | if (status) |
703 | return status; | 719 | return status; |
704 | 720 | ||
705 | pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); | 721 | nr_entries = pci_msix_table_size(dev); |
706 | pci_read_config_word(dev, msi_control_reg(pos), &control); | ||
707 | nr_entries = multi_msix_capable(control); | ||
708 | if (nvec > nr_entries) | 722 | if (nvec > nr_entries) |
709 | return -EINVAL; | 723 | return -EINVAL; |
710 | 724 | ||
diff --git a/include/linux/pci.h b/include/linux/pci.h index 7bd624bfdcfd..b5d6d0e0f1cb 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -799,6 +799,10 @@ static inline void pci_msi_shutdown(struct pci_dev *dev) | |||
799 | static inline void pci_disable_msi(struct pci_dev *dev) | 799 | static inline void pci_disable_msi(struct pci_dev *dev) |
800 | { } | 800 | { } |
801 | 801 | ||
802 | static inline int pci_msix_table_size(struct pci_dev *dev) | ||
803 | { | ||
804 | return 0; | ||
805 | } | ||
802 | static inline int pci_enable_msix(struct pci_dev *dev, | 806 | static inline int pci_enable_msix(struct pci_dev *dev, |
803 | struct msix_entry *entries, int nvec) | 807 | struct msix_entry *entries, int nvec) |
804 | { | 808 | { |
@@ -823,6 +827,7 @@ static inline int pci_msi_enabled(void) | |||
823 | extern int pci_enable_msi(struct pci_dev *dev); | 827 | extern int pci_enable_msi(struct pci_dev *dev); |
824 | extern void pci_msi_shutdown(struct pci_dev *dev); | 828 | extern void pci_msi_shutdown(struct pci_dev *dev); |
825 | extern void pci_disable_msi(struct pci_dev *dev); | 829 | extern void pci_disable_msi(struct pci_dev *dev); |
830 | extern int pci_msix_table_size(struct pci_dev *dev); | ||
826 | extern int pci_enable_msix(struct pci_dev *dev, | 831 | extern int pci_enable_msix(struct pci_dev *dev, |
827 | struct msix_entry *entries, int nvec); | 832 | struct msix_entry *entries, int nvec); |
828 | extern void pci_msix_shutdown(struct pci_dev *dev); | 833 | extern void pci_msix_shutdown(struct pci_dev *dev); |