msi: Kill the msi_desc array.
authorEric W. Biederman <ebiederm@xmission.com>
Sun, 28 Jan 2007 19:52:03 +0000 (12:52 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 7 Feb 2007 23:50:08 +0000 (15:50 -0800)
We need to be able to get from an irq number to a struct msi_desc.
The msi_desc array in msi.c had several short comings the big one was
that it could not be used outside of msi.c.  Using irq_data in struct
irq_desc almost worked except on some architectures irq_data needs to
be used for something else.

So this patch adds a msi_desc pointer to irq_desc, adds the appropriate
wrappers and changes all of the msi code to use them.

The dynamic_irq_init/cleanup code was tweaked to ensure the new
field is left in a well defined state.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Acked-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
arch/ia64/sn/kernel/msi_sn.c
drivers/pci/msi.c
include/linux/irq.h
kernel/irq/chip.c

index b3a435fd70fbc717d8c819e3f253aa50612d09f1..31fbb859b67ea9acce5542f5f105f5a81b3169fc 100644 (file)
@@ -74,7 +74,7 @@ int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev)
        struct pcibus_bussoft *bussoft = SN_PCIDEV_BUSSOFT(pdev);
        struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
 
-       entry = get_irq_data(irq);
+       entry = get_irq_msi(irq);
        if (!entry->msi_attrib.is_64)
                return -EINVAL;
 
index 55fe83dfd77bd300fa28e43bab4f273c0e2be422..52c253c5ad3dbe84687205c761d522ae79c4abf2 100644 (file)
@@ -24,7 +24,6 @@
 #include "pci.h"
 #include "msi.h"
 
-static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL };
 static struct kmem_cache* msi_cachep;
 
 static int pci_msi_enable = 1;
@@ -43,7 +42,7 @@ static void msi_set_mask_bit(unsigned int irq, int flag)
 {
        struct msi_desc *entry;
 
-       entry = msi_desc[irq];
+       entry = get_irq_msi(irq);
        BUG_ON(!entry || !entry->dev);
        switch (entry->msi_attrib.type) {
        case PCI_CAP_ID_MSI:
@@ -73,7 +72,7 @@ static void msi_set_mask_bit(unsigned int irq, int flag)
 
 void read_msi_msg(unsigned int irq, struct msi_msg *msg)
 {
-       struct msi_desc *entry = get_irq_data(irq);
+       struct msi_desc *entry = get_irq_msi(irq);
        switch(entry->msi_attrib.type) {
        case PCI_CAP_ID_MSI:
        {
@@ -112,7 +111,7 @@ void read_msi_msg(unsigned int irq, struct msi_msg *msg)
 
 void write_msi_msg(unsigned int irq, struct msi_msg *msg)
 {
-       struct msi_desc *entry = get_irq_data(irq);
+       struct msi_desc *entry = get_irq_msi(irq);
        switch (entry->msi_attrib.type) {
        case PCI_CAP_ID_MSI:
        {
@@ -208,7 +207,7 @@ static int create_msi_irq(void)
                return -EBUSY;
        }
 
-       set_irq_data(irq, entry);
+       set_irq_msi(irq, entry);
 
        return irq;
 }
@@ -217,9 +216,9 @@ static void destroy_msi_irq(unsigned int irq)
 {
        struct msi_desc *entry;
 
-       entry = get_irq_data(irq);
+       entry = get_irq_msi(irq);
        set_irq_chip(irq, NULL);
-       set_irq_data(irq, NULL);
+       set_irq_msi(irq, NULL);
        destroy_irq(irq);
        kmem_cache_free(msi_cachep, entry);
 }
@@ -360,10 +359,10 @@ static int __pci_save_msix_state(struct pci_dev *dev)
        while (head != tail) {
                struct msi_desc *entry;
 
-               entry = msi_desc[irq];
+               entry = get_irq_msi(irq);
                read_msi_msg(irq, &entry->msg_save);
 
-               tail = msi_desc[irq]->link.tail;
+               tail = entry->link.tail;
                irq = tail;
        }
 
@@ -410,10 +409,10 @@ static void __pci_restore_msix_state(struct pci_dev *dev)
        /* route the table */
        irq = head = dev->first_msi_irq;
        while (head != tail) {
-               entry = msi_desc[irq];
+               entry = get_irq_msi(irq);
                write_msi_msg(irq, &entry->msg_save);
 
-               tail = msi_desc[irq]->link.tail;
+               tail = entry->link.tail;
                irq = tail;
        }
 
@@ -451,7 +450,7 @@ static int msi_capability_init(struct pci_dev *dev)
        if (irq < 0)
                return irq;
 
-       entry = get_irq_data(irq);
+       entry = get_irq_msi(irq);
        entry->link.head = irq;
        entry->link.tail = irq;
        entry->msi_attrib.type = PCI_CAP_ID_MSI;
@@ -486,7 +485,7 @@ static int msi_capability_init(struct pci_dev *dev)
        }
 
        dev->first_msi_irq = irq;
-       msi_desc[irq] = entry;
+       set_irq_msi(irq, entry);
        /* Set MSI enabled bits  */
        enable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
 
@@ -535,7 +534,7 @@ static int msix_capability_init(struct pci_dev *dev,
                if (irq < 0)
                        break;
 
-               entry = get_irq_data(irq);
+               entry = get_irq_msi(irq);
                j = entries[i].entry;
                entries[i].vector = irq;
                entry->msi_attrib.type = PCI_CAP_ID_MSIX;
@@ -565,7 +564,7 @@ static int msix_capability_init(struct pci_dev *dev,
                        break;
                }
 
-               msi_desc[irq] = entry;
+               set_irq_msi(irq, entry);
        }
        if (i != nvec) {
                int avail = i - 1;
@@ -682,7 +681,7 @@ void pci_disable_msi(struct pci_dev* dev)
 
        disable_msi_mode(dev, pos, PCI_CAP_ID_MSI);
 
-       entry = msi_desc[dev->first_msi_irq];
+       entry = get_irq_msi(dev->first_msi_irq);
        if (!entry || !entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) {
                return;
        }
@@ -709,7 +708,7 @@ static int msi_free_irq(struct pci_dev* dev, int irq)
 
        arch_teardown_msi_irq(irq);
 
-       entry = msi_desc[irq];
+       entry = get_irq_msi(irq);
        if (!entry || entry->dev != dev) {
                return -EINVAL;
        }
@@ -717,10 +716,9 @@ static int msi_free_irq(struct pci_dev* dev, int irq)
        entry_nr = entry->msi_attrib.entry_nr;
        head = entry->link.head;
        base = entry->mask_base;
-       msi_desc[entry->link.head]->link.tail = entry->link.tail;
-       msi_desc[entry->link.tail]->link.head = entry->link.head;
+       get_irq_msi(entry->link.head)->link.tail = entry->link.tail;
+       get_irq_msi(entry->link.tail)->link.head = entry->link.head;
        entry->dev = NULL;
-       msi_desc[irq] = NULL;
 
        destroy_msi_irq(irq);
 
@@ -821,7 +819,7 @@ void pci_disable_msix(struct pci_dev* dev)
 
        irq = head = dev->first_msi_irq;
        while (head != tail) {
-               tail = msi_desc[irq]->link.tail;
+               tail = get_irq_msi(irq)->link.tail;
                if (irq_has_action(irq))
                        warning = 1;
                else if (irq != head)   /* Release MSI-X irq */
@@ -867,8 +865,8 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev)
 
                irq = head = dev->first_msi_irq;
                while (head != tail) {
-                       tail = msi_desc[irq]->link.tail;
-                       base = msi_desc[irq]->mask_base;
+                       tail = get_irq_msi(irq)->link.tail;
+                       base = get_irq_msi(irq)->mask_base;
                        if (irq_has_action(irq))
                                warning = 1;
                        else if (irq != head) /* Release MSI-X irq */
index 52fc4052a0ae62d113fe1a7eef6692d8d93bf645..5504b671357f2cf3adf476244cc81b06f84af137 100644 (file)
@@ -68,6 +68,7 @@ typedef       void fastcall (*irq_flow_handler_t)(unsigned int irq,
 #define IRQ_MOVE_PENDING       0x40000000      /* need to re-target IRQ destination */
 
 struct proc_dir_entry;
+struct msi_desc;
 
 /**
  * struct irq_chip - hardware interrupt chip descriptor
@@ -148,6 +149,7 @@ struct irq_chip {
 struct irq_desc {
        irq_flow_handler_t      handle_irq;
        struct irq_chip         *chip;
+       struct msi_desc         *msi_desc;
        void                    *handler_data;
        void                    *chip_data;
        struct irqaction        *action;        /* IRQ action list */
@@ -373,10 +375,12 @@ extern int set_irq_chip(unsigned int irq, struct irq_chip *chip);
 extern int set_irq_data(unsigned int irq, void *data);
 extern int set_irq_chip_data(unsigned int irq, void *data);
 extern int set_irq_type(unsigned int irq, unsigned int type);
+extern int set_irq_msi(unsigned int irq, struct msi_desc *entry);
 
 #define get_irq_chip(irq)      (irq_desc[irq].chip)
 #define get_irq_chip_data(irq) (irq_desc[irq].chip_data)
 #define get_irq_data(irq)      (irq_desc[irq].handler_data)
+#define get_irq_msi(irq)       (irq_desc[irq].msi_desc)
 
 #endif /* CONFIG_GENERIC_HARDIRQS */
 
index d27b2585574318ff2a3dd9e21b798c21164fa302..475e8a71bcdc19772b312461b95ba0b171f1790e 100644 (file)
@@ -39,6 +39,7 @@ void dynamic_irq_init(unsigned int irq)
        desc->chip = &no_irq_chip;
        desc->handle_irq = handle_bad_irq;
        desc->depth = 1;
+       desc->msi_desc = NULL;
        desc->handler_data = NULL;
        desc->chip_data = NULL;
        desc->action = NULL;
@@ -74,6 +75,9 @@ void dynamic_irq_cleanup(unsigned int irq)
                WARN_ON(1);
                return;
        }
+       desc->msi_desc = NULL;
+       desc->handler_data = NULL;
+       desc->chip_data = NULL;
        desc->handle_irq = handle_bad_irq;
        desc->chip = &no_irq_chip;
        spin_unlock_irqrestore(&desc->lock, flags);
@@ -161,6 +165,30 @@ int set_irq_data(unsigned int irq, void *data)
 }
 EXPORT_SYMBOL(set_irq_data);
 
+/**
+ *     set_irq_data - set irq type data for an irq
+ *     @irq:   Interrupt number
+ *     @data:  Pointer to interrupt specific data
+ *
+ *     Set the hardware irq controller data for an irq
+ */
+int set_irq_msi(unsigned int irq, struct msi_desc *entry)
+{
+       struct irq_desc *desc;
+       unsigned long flags;
+
+       if (irq >= NR_IRQS) {
+               printk(KERN_ERR
+                      "Trying to install msi data for IRQ%d\n", irq);
+               return -EINVAL;
+       }
+       desc = irq_desc + irq;
+       spin_lock_irqsave(&desc->lock, flags);
+       desc->msi_desc = entry;
+       spin_unlock_irqrestore(&desc->lock, flags);
+       return 0;
+}
+
 /**
  *     set_irq_chip_data - set irq chip data for an irq
  *     @irq:   Interrupt number