diff options
Diffstat (limited to 'drivers/pci/msi.c')
-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 ce08d0bffe0..14159cf7d38 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) { |