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.c71
1 files changed, 37 insertions, 34 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 7f8429284fab..27a057409eca 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -10,7 +10,6 @@
10#include <linux/irq.h> 10#include <linux/irq.h>
11#include <linux/interrupt.h> 11#include <linux/interrupt.h>
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/config.h>
14#include <linux/ioport.h> 13#include <linux/ioport.h>
15#include <linux/smp_lock.h> 14#include <linux/smp_lock.h>
16#include <linux/pci.h> 15#include <linux/pci.h>
@@ -46,16 +45,10 @@ msi_register(struct msi_ops *ops)
46 return 0; 45 return 0;
47} 46}
48 47
49static void msi_cache_ctor(void *p, kmem_cache_t *cache, unsigned long flags)
50{
51 memset(p, 0, NR_IRQS * sizeof(struct msi_desc));
52}
53
54static int msi_cache_init(void) 48static int msi_cache_init(void)
55{ 49{
56 msi_cachep = kmem_cache_create("msi_cache", 50 msi_cachep = kmem_cache_create("msi_cache", sizeof(struct msi_desc),
57 NR_IRQS * sizeof(struct msi_desc), 51 0, SLAB_HWCACHE_ALIGN, NULL, NULL);
58 0, SLAB_HWCACHE_ALIGN, msi_cache_ctor, NULL);
59 if (!msi_cachep) 52 if (!msi_cachep)
60 return -ENOMEM; 53 return -ENOMEM;
61 54
@@ -403,11 +396,10 @@ static struct msi_desc* alloc_msi_entry(void)
403{ 396{
404 struct msi_desc *entry; 397 struct msi_desc *entry;
405 398
406 entry = kmem_cache_alloc(msi_cachep, SLAB_KERNEL); 399 entry = kmem_cache_zalloc(msi_cachep, GFP_KERNEL);
407 if (!entry) 400 if (!entry)
408 return NULL; 401 return NULL;
409 402
410 memset(entry, 0, sizeof(struct msi_desc));
411 entry->link.tail = entry->link.head = 0; /* single message */ 403 entry->link.tail = entry->link.head = 0; /* single message */
412 entry->dev = NULL; 404 entry->dev = NULL;
413 405
@@ -429,12 +421,12 @@ static void irq_handler_init(int cap_id, int pos, int mask)
429 421
430 spin_lock_irqsave(&irq_desc[pos].lock, flags); 422 spin_lock_irqsave(&irq_desc[pos].lock, flags);
431 if (cap_id == PCI_CAP_ID_MSIX) 423 if (cap_id == PCI_CAP_ID_MSIX)
432 irq_desc[pos].handler = &msix_irq_type; 424 irq_desc[pos].chip = &msix_irq_type;
433 else { 425 else {
434 if (!mask) 426 if (!mask)
435 irq_desc[pos].handler = &msi_irq_wo_maskbit_type; 427 irq_desc[pos].chip = &msi_irq_wo_maskbit_type;
436 else 428 else
437 irq_desc[pos].handler = &msi_irq_w_maskbit_type; 429 irq_desc[pos].chip = &msi_irq_w_maskbit_type;
438 } 430 }
439 spin_unlock_irqrestore(&irq_desc[pos].lock, flags); 431 spin_unlock_irqrestore(&irq_desc[pos].lock, flags);
440} 432}
@@ -902,6 +894,33 @@ static int msix_capability_init(struct pci_dev *dev,
902} 894}
903 895
904/** 896/**
897 * pci_msi_supported - check whether MSI may be enabled on device
898 * @dev: pointer to the pci_dev data structure of MSI device function
899 *
900 * MSI must be globally enabled and supported by the device and its root
901 * bus. But, the root bus is not easy to find since some architectures
902 * have virtual busses on top of the PCI hierarchy (for instance the
903 * hypertransport bus), while the actual bus where MSI must be supported
904 * is below. So we test the MSI flag on all parent busses and assume
905 * that no quirk will ever set the NO_MSI flag on a non-root bus.
906 **/
907static
908int pci_msi_supported(struct pci_dev * dev)
909{
910 struct pci_bus *bus;
911
912 if (!pci_msi_enable || !dev || dev->no_msi)
913 return -EINVAL;
914
915 /* check MSI flags of all parent busses */
916 for (bus = dev->bus; bus; bus = bus->parent)
917 if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI)
918 return -EINVAL;
919
920 return 0;
921}
922
923/**
905 * pci_enable_msi - configure device's MSI capability structure 924 * pci_enable_msi - configure device's MSI capability structure
906 * @dev: pointer to the pci_dev data structure of MSI device function 925 * @dev: pointer to the pci_dev data structure of MSI device function
907 * 926 *
@@ -913,19 +932,11 @@ static int msix_capability_init(struct pci_dev *dev,
913 **/ 932 **/
914int pci_enable_msi(struct pci_dev* dev) 933int pci_enable_msi(struct pci_dev* dev)
915{ 934{
916 struct pci_bus *bus; 935 int pos, temp, status;
917 int pos, temp, status = -EINVAL;
918 u16 control; 936 u16 control;
919 937
920 if (!pci_msi_enable || !dev) 938 if (pci_msi_supported(dev) < 0)
921 return status; 939 return -EINVAL;
922
923 if (dev->no_msi)
924 return status;
925
926 for (bus = dev->bus; bus; bus = bus->parent)
927 if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI)
928 return -EINVAL;
929 940
930 temp = dev->irq; 941 temp = dev->irq;
931 942
@@ -1135,22 +1146,14 @@ static int reroute_msix_table(int head, struct msix_entry *entries, int *nvec)
1135 **/ 1146 **/
1136int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) 1147int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
1137{ 1148{
1138 struct pci_bus *bus;
1139 int status, pos, nr_entries, free_vectors; 1149 int status, pos, nr_entries, free_vectors;
1140 int i, j, temp; 1150 int i, j, temp;
1141 u16 control; 1151 u16 control;
1142 unsigned long flags; 1152 unsigned long flags;
1143 1153
1144 if (!pci_msi_enable || !dev || !entries) 1154 if (!entries || pci_msi_supported(dev) < 0)
1145 return -EINVAL; 1155 return -EINVAL;
1146 1156
1147 if (dev->no_msi)
1148 return -EINVAL;
1149
1150 for (bus = dev->bus; bus; bus = bus->parent)
1151 if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI)
1152 return -EINVAL;
1153
1154 status = msi_init(); 1157 status = msi_init();
1155 if (status < 0) 1158 if (status < 0)
1156 return status; 1159 return status;