summaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/msi.c59
1 files changed, 36 insertions, 23 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index ce08d0b..14159cf 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) {
OpenPOWER on IntegriCloud