aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/msi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/msi.c')
-rw-r--r--drivers/pci/msi.c96
1 files changed, 39 insertions, 57 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 955ab7990c5b..27a7e67ddfe4 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -10,7 +10,6 @@
10#include <linux/mm.h> 10#include <linux/mm.h>
11#include <linux/irq.h> 11#include <linux/irq.h>
12#include <linux/interrupt.h> 12#include <linux/interrupt.h>
13#include <linux/init.h>
14#include <linux/export.h> 13#include <linux/export.h>
15#include <linux/ioport.h> 14#include <linux/ioport.h>
16#include <linux/pci.h> 15#include <linux/pci.h>
@@ -544,22 +543,18 @@ static int populate_msi_sysfs(struct pci_dev *pdev)
544 if (!msi_attrs) 543 if (!msi_attrs)
545 return -ENOMEM; 544 return -ENOMEM;
546 list_for_each_entry(entry, &pdev->msi_list, list) { 545 list_for_each_entry(entry, &pdev->msi_list, list) {
547 char *name = kmalloc(20, GFP_KERNEL);
548 if (!name)
549 goto error_attrs;
550
551 msi_dev_attr = kzalloc(sizeof(*msi_dev_attr), GFP_KERNEL); 546 msi_dev_attr = kzalloc(sizeof(*msi_dev_attr), GFP_KERNEL);
552 if (!msi_dev_attr) { 547 if (!msi_dev_attr)
553 kfree(name);
554 goto error_attrs; 548 goto error_attrs;
555 } 549 msi_attrs[count] = &msi_dev_attr->attr;
556 550
557 sprintf(name, "%d", entry->irq);
558 sysfs_attr_init(&msi_dev_attr->attr); 551 sysfs_attr_init(&msi_dev_attr->attr);
559 msi_dev_attr->attr.name = name; 552 msi_dev_attr->attr.name = kasprintf(GFP_KERNEL, "%d",
553 entry->irq);
554 if (!msi_dev_attr->attr.name)
555 goto error_attrs;
560 msi_dev_attr->attr.mode = S_IRUGO; 556 msi_dev_attr->attr.mode = S_IRUGO;
561 msi_dev_attr->show = msi_mode_show; 557 msi_dev_attr->show = msi_mode_show;
562 msi_attrs[count] = &msi_dev_attr->attr;
563 ++count; 558 ++count;
564 } 559 }
565 560
@@ -883,50 +878,6 @@ int pci_msi_vec_count(struct pci_dev *dev)
883} 878}
884EXPORT_SYMBOL(pci_msi_vec_count); 879EXPORT_SYMBOL(pci_msi_vec_count);
885 880
886/**
887 * pci_enable_msi_block - configure device's MSI capability structure
888 * @dev: device to configure
889 * @nvec: number of interrupts to configure
890 *
891 * Allocate IRQs for a device with the MSI capability.
892 * This function returns a negative errno if an error occurs. If it
893 * is unable to allocate the number of interrupts requested, it returns
894 * the number of interrupts it might be able to allocate. If it successfully
895 * allocates at least the number of interrupts requested, it returns 0 and
896 * updates the @dev's irq member to the lowest new interrupt number; the
897 * other interrupt numbers allocated to this device are consecutive.
898 */
899int pci_enable_msi_block(struct pci_dev *dev, int nvec)
900{
901 int status, maxvec;
902
903 if (dev->current_state != PCI_D0)
904 return -EINVAL;
905
906 maxvec = pci_msi_vec_count(dev);
907 if (maxvec < 0)
908 return maxvec;
909 if (nvec > maxvec)
910 return maxvec;
911
912 status = pci_msi_check_device(dev, nvec, PCI_CAP_ID_MSI);
913 if (status)
914 return status;
915
916 WARN_ON(!!dev->msi_enabled);
917
918 /* Check whether driver already requested MSI-X irqs */
919 if (dev->msix_enabled) {
920 dev_info(&dev->dev, "can't enable MSI "
921 "(MSI-X already enabled)\n");
922 return -EINVAL;
923 }
924
925 status = msi_capability_init(dev, nvec);
926 return status;
927}
928EXPORT_SYMBOL(pci_enable_msi_block);
929
930void pci_msi_shutdown(struct pci_dev *dev) 881void pci_msi_shutdown(struct pci_dev *dev)
931{ 882{
932 struct msi_desc *desc; 883 struct msi_desc *desc;
@@ -1132,14 +1083,45 @@ void pci_msi_init_pci_dev(struct pci_dev *dev)
1132 **/ 1083 **/
1133int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec) 1084int pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec)
1134{ 1085{
1135 int nvec = maxvec; 1086 int nvec;
1136 int rc; 1087 int rc;
1137 1088
1089 if (dev->current_state != PCI_D0)
1090 return -EINVAL;
1091
1092 WARN_ON(!!dev->msi_enabled);
1093
1094 /* Check whether driver already requested MSI-X irqs */
1095 if (dev->msix_enabled) {
1096 dev_info(&dev->dev,
1097 "can't enable MSI (MSI-X already enabled)\n");
1098 return -EINVAL;
1099 }
1100
1138 if (maxvec < minvec) 1101 if (maxvec < minvec)
1139 return -ERANGE; 1102 return -ERANGE;
1140 1103
1104 nvec = pci_msi_vec_count(dev);
1105 if (nvec < 0)
1106 return nvec;
1107 else if (nvec < minvec)
1108 return -EINVAL;
1109 else if (nvec > maxvec)
1110 nvec = maxvec;
1111
1112 do {
1113 rc = pci_msi_check_device(dev, nvec, PCI_CAP_ID_MSI);
1114 if (rc < 0) {
1115 return rc;
1116 } else if (rc > 0) {
1117 if (rc < minvec)
1118 return -ENOSPC;
1119 nvec = rc;
1120 }
1121 } while (rc);
1122
1141 do { 1123 do {
1142 rc = pci_enable_msi_block(dev, nvec); 1124 rc = msi_capability_init(dev, nvec);
1143 if (rc < 0) { 1125 if (rc < 0) {
1144 return rc; 1126 return rc;
1145 } else if (rc > 0) { 1127 } else if (rc > 0) {