From 98581b0d78e7aee349266d643c2fef407c22ba7c Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 20 Jan 2007 16:00:28 +0900 Subject: [PATCH] --- yaml --- r: 47369 b: refs/heads/master c: d24bbbf251e70bf984cbaa9b1fcadc5f56fc3ae9 h: refs/heads/master i: 47367: e70ee5cf42b1a8aa5a938a16728a90beef8abc03 v: v3 --- [refs] | 2 +- trunk/include/linux/io.h | 2 ++ trunk/lib/iomap.c | 53 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 73e1483ce09b..7f903975bd49 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: b878ca5d37953ad1c4578b225a13a3c3e7e743b7 +refs/heads/master: d24bbbf251e70bf984cbaa9b1fcadc5f56fc3ae9 diff --git a/trunk/include/linux/io.h b/trunk/include/linux/io.h index f5edf9c5de0a..45a9c944cb0a 100644 --- a/trunk/include/linux/io.h +++ b/trunk/include/linux/io.h @@ -45,6 +45,8 @@ void __iomem * pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen); void pcim_iounmap(struct pci_dev *pdev, void __iomem *addr); void __iomem * const * pcim_iomap_table(struct pci_dev *pdev); +int pcim_iomap_regions(struct pci_dev *pdev, u16 mask, const char *name); + /** * check_signature - find BIOS signatures * @io_addr: mmio address to check diff --git a/trunk/lib/iomap.c b/trunk/lib/iomap.c index 3214028141da..4990c736bc4b 100644 --- a/trunk/lib/iomap.c +++ b/trunk/lib/iomap.c @@ -498,3 +498,56 @@ void pcim_iounmap(struct pci_dev *pdev, void __iomem *addr) WARN_ON(1); } EXPORT_SYMBOL(pcim_iounmap); + +/** + * pcim_iomap_regions - Request and iomap PCI BARs + * @pdev: PCI device to map IO resources for + * @mask: Mask of BARs to request and iomap + * @name: Name used when requesting regions + * + * Request and iomap regions specified by @mask. + */ +int pcim_iomap_regions(struct pci_dev *pdev, u16 mask, const char *name) +{ + void __iomem * const *iomap; + int i, rc; + + iomap = pcim_iomap_table(pdev); + if (!iomap) + return -ENOMEM; + + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { + unsigned long len; + + if (!(mask & (1 << i))) + continue; + + rc = -EINVAL; + len = pci_resource_len(pdev, i); + if (!len) + goto err_inval; + + rc = pci_request_region(pdev, i, name); + if (rc) + goto err_region; + + rc = -ENOMEM; + if (!pcim_iomap(pdev, i, 0)) + goto err_iomap; + } + + return 0; + + err_iomap: + pcim_iounmap(pdev, iomap[i]); + err_region: + pci_release_region(pdev, i); + err_inval: + while (--i >= 0) { + pcim_iounmap(pdev, iomap[i]); + pci_release_region(pdev, i); + } + + return rc; +} +EXPORT_SYMBOL(pcim_iomap_regions);