aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-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 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,
447 return ioremap_nocache(phys_addr, nr_entries * PCI_MSIX_ENTRY_SIZE); 447 return ioremap_nocache(phys_addr, nr_entries * PCI_MSIX_ENTRY_SIZE);
448} 448}
449 449
450static int msix_setup_entries(struct pci_dev *dev, unsigned pos,
451 void __iomem *base, struct msix_entry *entries,
452 int nvec)
453{
454 struct msi_desc *entry;
455 int i;
456
457 for (i = 0; i < nvec; i++) {
458 entry = alloc_msi_entry(dev);
459 if (!entry) {
460 if (!i)
461 iounmap(base);
462 else
463 free_msi_irqs(dev);
464 /* No enough memory. Don't try again */
465 return -ENOMEM;
466 }
467
468 entry->msi_attrib.is_msix = 1;
469 entry->msi_attrib.is_64 = 1;
470 entry->msi_attrib.entry_nr = entries[i].entry;
471 entry->msi_attrib.default_irq = dev->irq;
472 entry->msi_attrib.pos = pos;
473 entry->mask_base = base;
474
475 list_add_tail(&entry->list, &dev->msi_list);
476 }
477
478 return 0;
479}
480
450static void msix_program_entries(struct pci_dev *dev, 481static void msix_program_entries(struct pci_dev *dev,
451 struct msix_entry *entries) 482 struct msix_entry *entries)
452{ 483{
@@ -478,8 +509,7 @@ static void msix_program_entries(struct pci_dev *dev,
478static int msix_capability_init(struct pci_dev *dev, 509static int msix_capability_init(struct pci_dev *dev,
479 struct msix_entry *entries, int nvec) 510 struct msix_entry *entries, int nvec)
480{ 511{
481 struct msi_desc *entry; 512 int pos, ret;
482 int pos, i, j, ret;
483 u16 control; 513 u16 control;
484 void __iomem *base; 514 void __iomem *base;
485 515
@@ -495,27 +525,9 @@ static int msix_capability_init(struct pci_dev *dev,
495 if (!base) 525 if (!base)
496 return -ENOMEM; 526 return -ENOMEM;
497 527
498 for (i = 0; i < nvec; i++) { 528 ret = msix_setup_entries(dev, pos, base, entries, nvec);
499 entry = alloc_msi_entry(dev); 529 if (ret)
500 if (!entry) { 530 return ret;
501 if (!i)
502 iounmap(base);
503 else
504 free_msi_irqs(dev);
505 /* No enough memory. Don't try again */
506 return -ENOMEM;
507 }
508
509 j = entries[i].entry;
510 entry->msi_attrib.is_msix = 1;
511 entry->msi_attrib.is_64 = 1;
512 entry->msi_attrib.entry_nr = j;
513 entry->msi_attrib.default_irq = dev->irq;
514 entry->msi_attrib.pos = pos;
515 entry->mask_base = base;
516
517 list_add_tail(&entry->list, &dev->msi_list);
518 }
519 531
520 ret = arch_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSIX); 532 ret = arch_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSIX);
521 if (ret) 533 if (ret)
@@ -546,6 +558,7 @@ error:
546 * If we had some success, report the number of irqs 558 * If we had some success, report the number of irqs
547 * we succeeded in setting up. 559 * we succeeded in setting up.
548 */ 560 */
561 struct msi_desc *entry;
549 int avail = 0; 562 int avail = 0;
550 563
551 list_for_each_entry(entry, &dev->msi_list, list) { 564 list_for_each_entry(entry, &dev->msi_list, list) {