Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=4aa9bc955d61fdf03b5f9cee67db188fe1ffa8b7
Commit:     4aa9bc955d61fdf03b5f9cee67db188fe1ffa8b7
Parent:     bab41e9be75121c473b00df2ffa33af3c44066a7
Author:     Michael Ellerman <[EMAIL PROTECTED]>
AuthorDate: Thu Apr 5 17:19:10 2007 +1000
Committer:  Greg Kroah-Hartman <[EMAIL PROTECTED]>
CommitDate: Wed May 2 19:02:37 2007 -0700

    MSI: Use a list instead of the custom link structure
    
    The msi descriptors are linked together with what looks a lot like
    a linked list, but isn't a struct list_head list. Make it one.
    
    The only complication is that previously we walked a list of irqs, and
    got the descriptor for each with get_irq_msi(). Now we have a list of
    descriptors and need to get the irq out of it, so it needs to be in the
    actual struct msi_desc. We use 0 to indicate no irq is setup.
    
    Signed-off-by: Michael Ellerman <[EMAIL PROTECTED]>
    Signed-off-by: Greg Kroah-Hartman <[EMAIL PROTECTED]>
---
 drivers/pci/msi.c   |   66 ++++++++++++++++++--------------------------------
 drivers/pci/pci.h   |    2 +
 drivers/pci/probe.c |    2 +
 include/linux/msi.h |    8 +++---
 include/linux/pci.h |    1 +
 5 files changed, 33 insertions(+), 46 deletions(-)

diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 5902c00..434c718 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -218,7 +218,8 @@ static struct msi_desc* alloc_msi_entry(void)
        if (!entry)
                return NULL;
 
-       entry->link.tail = entry->link.head = 0;        /* single message */
+       INIT_LIST_HEAD(&entry->list);
+       entry->irq = 0;
        entry->dev = NULL;
 
        return entry;
@@ -253,7 +254,6 @@ static void __pci_restore_msi_state(struct pci_dev *dev)
 static void __pci_restore_msix_state(struct pci_dev *dev)
 {
        int pos;
-       int irq, head, tail = 0;
        struct msi_desc *entry;
        u16 control;
 
@@ -263,18 +263,14 @@ static void __pci_restore_msix_state(struct pci_dev *dev)
        /* route the table */
        pci_intx(dev, 0);               /* disable intx */
        msix_set_enable(dev, 0);
-       irq = head = dev->first_msi_irq;
-       entry = get_irq_msi(irq);
-       pos = entry->msi_attrib.pos;
-       while (head != tail) {
-               entry = get_irq_msi(irq);
-               write_msi_msg(irq, &entry->msg);
-               msi_set_mask_bit(irq, entry->msi_attrib.masked);
 
-               tail = entry->link.tail;
-               irq = tail;
+       list_for_each_entry(entry, &dev->msi_list, list) {
+               write_msi_msg(entry->irq, &entry->msg);
+               msi_set_mask_bit(entry->irq, entry->msi_attrib.masked);
        }
 
+       entry = get_irq_msi(dev->first_msi_irq);
+       pos = entry->msi_attrib.pos;
        pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control);
        control &= ~PCI_MSIX_FLAGS_MASKALL;
        control |= PCI_MSIX_FLAGS_ENABLE;
@@ -343,8 +339,8 @@ static int msi_capability_init(struct pci_dev *dev)
                kfree(entry);
                return irq;
        }
-       entry->link.head = irq;
-       entry->link.tail = irq;
+       entry->irq = irq;
+       list_add(&entry->list, &dev->msi_list);
        dev->first_msi_irq = irq;
        set_irq_msi(irq, entry);
 
@@ -370,8 +366,8 @@ static int msi_capability_init(struct pci_dev *dev)
 static int msix_capability_init(struct pci_dev *dev,
                                struct msix_entry *entries, int nvec)
 {
-       struct msi_desc *head = NULL, *tail = NULL, *entry = NULL;
-       int irq, pos, i, j, nr_entries, temp = 0;
+       struct msi_desc *entry;
+       int irq, pos, i, j, nr_entries;
        unsigned long phys_addr;
        u32 table_offset;
        u16 control;
@@ -416,19 +412,9 @@ static int msix_capability_init(struct pci_dev *dev,
                        kfree(entry);
                        break;
                }
+               entry->irq = irq;
                entries[i].vector = irq;
-               if (!head) {
-                       entry->link.head = irq;
-                       entry->link.tail = irq;
-                       head = entry;
-               } else {
-                       entry->link.head = temp;
-                       entry->link.tail = tail->link.tail;
-                       tail->link.tail = irq;
-                       head->link.head = irq;
-               }
-               temp = irq;
-               tail = entry;
+               list_add(&entry->list, &dev->msi_list);
 
                set_irq_msi(irq, entry);
        }
@@ -557,7 +543,7 @@ EXPORT_SYMBOL(pci_disable_msi);
 static int msi_free_irq(struct pci_dev* dev, int irq)
 {
        struct msi_desc *entry;
-       int head, entry_nr, type;
+       int entry_nr, type;
        void __iomem *base;
 
        BUG_ON(irq_has_action(irq));
@@ -568,10 +554,8 @@ static int msi_free_irq(struct pci_dev* dev, int irq)
        }
        type = entry->msi_attrib.type;
        entry_nr = entry->msi_attrib.entry_nr;
-       head = entry->link.head;
        base = entry->mask_base;
-       get_irq_msi(entry->link.head)->link.tail = entry->link.tail;
-       get_irq_msi(entry->link.tail)->link.head = entry->link.head;
+       list_del(&entry->list);
 
        arch_teardown_msi_irq(irq);
        kfree(entry);
@@ -580,7 +564,7 @@ static int msi_free_irq(struct pci_dev* dev, int irq)
                writel(1, base + entry_nr * PCI_MSIX_ENTRY_SIZE +
                        PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
 
-               if (head == irq)
+               if (list_empty(&dev->msi_list))
                        iounmap(base);
        }
 
@@ -646,17 +630,10 @@ EXPORT_SYMBOL(pci_enable_msix);
 
 static void msix_free_all_irqs(struct pci_dev *dev)
 {
-       int irq, head, tail = 0;
-
-       irq = head = dev->first_msi_irq;
-       while (head != tail) {
-               tail = get_irq_msi(irq)->link.tail;
+       struct msi_desc *entry;
 
-               if (irq != head)
-                       msi_free_irq(dev, irq);
-               irq = tail;
-       }
-       msi_free_irq(dev, irq);
+       list_for_each_entry(entry, &dev->msi_list, list)
+               msi_free_irq(dev, entry->irq);
        dev->first_msi_irq = 0;
 }
 
@@ -699,6 +676,11 @@ void pci_no_msi(void)
        pci_msi_enable = 0;
 }
 
+void pci_msi_init_pci_dev(struct pci_dev *dev)
+{
+       INIT_LIST_HEAD(&dev->msi_list);
+}
+
 
 /* Arch hooks */
 
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 62ea04c..3fec13d 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -47,8 +47,10 @@ extern unsigned int pci_pm_d3_delay;
 
 #ifdef CONFIG_PCI_MSI
 void pci_no_msi(void);
+extern void pci_msi_init_pci_dev(struct pci_dev *dev);
 #else
 static inline void pci_no_msi(void) { }
+static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { }
 #endif
 
 #if defined(CONFIG_PCI_MSI) && defined(CONFIG_PM)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index c659f8a..e48fcf0 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -857,6 +857,8 @@ struct pci_dev *alloc_pci_dev(void)
        INIT_LIST_HEAD(&dev->global_list);
        INIT_LIST_HEAD(&dev->bus_list);
 
+       pci_msi_init_pci_dev(dev);
+
        return dev;
 }
 EXPORT_SYMBOL(alloc_pci_dev);
diff --git a/include/linux/msi.h b/include/linux/msi.h
index d2a2000..931e013 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -1,6 +1,8 @@
 #ifndef LINUX_MSI_H
 #define LINUX_MSI_H
 
+#include <linux/list.h>
+
 struct msi_msg {
        u32     address_lo;     /* low 32 bits of msi message address */
        u32     address_hi;     /* high 32 bits of msi message address */
@@ -24,10 +26,8 @@ struct msi_desc {
                unsigned default_irq;   /* default pre-assigned irq       */
        }msi_attrib;
 
-       struct {
-               __u16   head;
-               __u16   tail;
-       }link;
+       unsigned int irq;
+       struct list_head list;
 
        void __iomem *mask_base;
        struct pci_dev *dev;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index c020747..d43097d 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -190,6 +190,7 @@ struct pci_dev {
        struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file 
for resources */
 #ifdef CONFIG_PCI_MSI
        unsigned int first_msi_irq;
+       struct list_head msi_list;
 #endif
 };
 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to