aboutsummaryrefslogtreecommitdiffstats
path: root/lib/iomap.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/iomap.c')
-rw-r--r--lib/iomap.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/lib/iomap.c b/lib/iomap.c
index 3214028141da..4990c736bc4b 100644
--- a/lib/iomap.c
+++ b/lib/iomap.c
@@ -498,3 +498,56 @@ void pcim_iounmap(struct pci_dev *pdev, void __iomem *addr)
498 WARN_ON(1); 498 WARN_ON(1);
499} 499}
500EXPORT_SYMBOL(pcim_iounmap); 500EXPORT_SYMBOL(pcim_iounmap);
501
502/**
503 * pcim_iomap_regions - Request and iomap PCI BARs
504 * @pdev: PCI device to map IO resources for
505 * @mask: Mask of BARs to request and iomap
506 * @name: Name used when requesting regions
507 *
508 * Request and iomap regions specified by @mask.
509 */
510int pcim_iomap_regions(struct pci_dev *pdev, u16 mask, const char *name)
511{
512 void __iomem * const *iomap;
513 int i, rc;
514
515 iomap = pcim_iomap_table(pdev);
516 if (!iomap)
517 return -ENOMEM;
518
519 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
520 unsigned long len;
521
522 if (!(mask & (1 << i)))
523 continue;
524
525 rc = -EINVAL;
526 len = pci_resource_len(pdev, i);
527 if (!len)
528 goto err_inval;
529
530 rc = pci_request_region(pdev, i, name);
531 if (rc)
532 goto err_region;
533
534 rc = -ENOMEM;
535 if (!pcim_iomap(pdev, i, 0))
536 goto err_iomap;
537 }
538
539 return 0;
540
541 err_iomap:
542 pcim_iounmap(pdev, iomap[i]);
543 err_region:
544 pci_release_region(pdev, i);
545 err_inval:
546 while (--i >= 0) {
547 pcim_iounmap(pdev, iomap[i]);
548 pci_release_region(pdev, i);
549 }
550
551 return rc;
552}
553EXPORT_SYMBOL(pcim_iomap_regions);