diff options
author | Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com> | 2009-08-06 11:35:48 +0900 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2009-09-09 13:29:34 -0700 |
commit | d9d7070e6117651ecc8fa0ea60b1ff5b68d4db4f (patch) | |
tree | f178b044245ae0f66cf2d405f0d3cb06d218c77a /drivers | |
parent | 75cb3426878d479f792c751a95f5c75f27b13a2f (diff) | |
download | linux-d9d7070e6117651ecc8fa0ea60b1ff5b68d4db4f.tar.bz2 |
PCI MSI: MSI-X cleanup, msix_setup_entries()
Cleanup based on the prototype from Matthew Milcox.
Reviewed-by: Matthew Wilcox <willy@linux.intel.com>
Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/pci/msi.c | 59 |
1 files changed, 36 insertions, 23 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index ce08d0bffe08..14159cf7d38e 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -447,6 +447,37 @@ static void __iomem *msix_map_region(struct pci_dev *dev, unsigned pos, return ioremap_nocache(phys_addr, nr_entries * PCI_MSIX_ENTRY_SIZE); } +static int msix_setup_entries(struct pci_dev *dev, unsigned pos, + void __iomem *base, struct msix_entry *entries, + int nvec) +{ + struct msi_desc *entry; + int i; + + for (i = 0; i < nvec; i++) { + entry = alloc_msi_entry(dev); + if (!entry) { + if (!i) + iounmap(base); + else + free_msi_irqs(dev); + /* No enough memory. Don't try again */ + return -ENOMEM; + } + + entry->msi_attrib.is_msix = 1; + entry->msi_attrib.is_64 = 1; + entry->msi_attrib.entry_nr = entries[i].entry; + entry->msi_attrib.default_irq = dev->irq; + entry->msi_attrib.pos = pos; + entry->mask_base = base; + + list_add_tail(&entry->list, &dev->msi_list); + } + + return 0; +} + static void msix_program_entries(struct pci_dev *dev, struct msix_entry *entries) { @@ -478,8 +509,7 @@ static void msix_program_entries(struct pci_dev *dev, static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries, int nvec) { - struct msi_desc *entry; - int pos, i, j, ret; + int pos, ret; u16 control; void __iomem *base; @@ -495,27 +525,9 @@ static int msix_capability_init(struct pci_dev *dev, if (!base) return -ENOMEM; - for (i = 0; i < nvec; i++) { - entry = alloc_msi_entry(dev); - if (!entry) { - if (!i) - iounmap(base); - else - free_msi_irqs(dev); - /* No enough memory. Don't try again */ - return -ENOMEM; - } - - j = entries[i].entry; - entry->msi_attrib.is_msix = 1; - entry->msi_attrib.is_64 = 1; - entry->msi_attrib.entry_nr = j; - entry->msi_attrib.default_irq = dev->irq; - entry->msi_attrib.pos = pos; - entry->mask_base = base; - - list_add_tail(&entry->list, &dev->msi_list); - } + ret = msix_setup_entries(dev, pos, base, entries, nvec); + if (ret) + return ret; ret = arch_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSIX); if (ret) @@ -546,6 +558,7 @@ error: * If we had some success, report the number of irqs * we succeeded in setting up. */ + struct msi_desc *entry; int avail = 0; list_for_each_entry(entry, &dev->msi_list, list) { |