diff options
author | Michael S. Tsirkin <mst@redhat.com> | 2013-05-28 22:22:21 -0400 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2015-01-21 00:58:49 -0500 |
commit | eb29d8d2aad70636ea23810b4868693673d630d5 (patch) | |
tree | f62b6c19f812b6f731dc90b3ae9989822b3749e6 | |
parent | 54cfe08b5f352d9aa4979e2434e85907c84af07a (diff) |
pci: add pci_iomap_range
Virtio drivers should map the part of the BAR they need, not necessarily
all of it.
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: linux-pci@vger.kernel.org
Acked-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
-rw-r--r-- | include/asm-generic/pci_iomap.h | 10 | ||||
-rw-r--r-- | lib/pci_iomap.c | 35 |
2 files changed, 40 insertions, 5 deletions
diff --git a/include/asm-generic/pci_iomap.h b/include/asm-generic/pci_iomap.h index ce37349860fe..7389c87116a0 100644 --- a/include/asm-generic/pci_iomap.h +++ b/include/asm-generic/pci_iomap.h | |||
@@ -15,6 +15,9 @@ struct pci_dev; | |||
15 | #ifdef CONFIG_PCI | 15 | #ifdef CONFIG_PCI |
16 | /* Create a virtual mapping cookie for a PCI BAR (memory or IO) */ | 16 | /* Create a virtual mapping cookie for a PCI BAR (memory or IO) */ |
17 | extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max); | 17 | extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max); |
18 | extern void __iomem *pci_iomap_range(struct pci_dev *dev, int bar, | ||
19 | unsigned long offset, | ||
20 | unsigned long maxlen); | ||
18 | /* Create a virtual mapping cookie for a port on a given PCI device. | 21 | /* Create a virtual mapping cookie for a port on a given PCI device. |
19 | * Do not call this directly, it exists to make it easier for architectures | 22 | * Do not call this directly, it exists to make it easier for architectures |
20 | * to override */ | 23 | * to override */ |
@@ -30,6 +33,13 @@ static inline void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned lon | |||
30 | { | 33 | { |
31 | return NULL; | 34 | return NULL; |
32 | } | 35 | } |
36 | |||
37 | static inline void __iomem *pci_iomap_range(struct pci_dev *dev, int bar, | ||
38 | unsigned long offset, | ||
39 | unsigned long maxlen) | ||
40 | { | ||
41 | return NULL; | ||
42 | } | ||
33 | #endif | 43 | #endif |
34 | 44 | ||
35 | #endif /* __ASM_GENERIC_IO_H */ | 45 | #endif /* __ASM_GENERIC_IO_H */ |
diff --git a/lib/pci_iomap.c b/lib/pci_iomap.c index 0d83ea8a9605..bcce5f149310 100644 --- a/lib/pci_iomap.c +++ b/lib/pci_iomap.c | |||
@@ -10,10 +10,11 @@ | |||
10 | 10 | ||
11 | #ifdef CONFIG_PCI | 11 | #ifdef CONFIG_PCI |
12 | /** | 12 | /** |
13 | * pci_iomap - create a virtual mapping cookie for a PCI BAR | 13 | * pci_iomap_range - create a virtual mapping cookie for a PCI BAR |
14 | * @dev: PCI device that owns the BAR | 14 | * @dev: PCI device that owns the BAR |
15 | * @bar: BAR number | 15 | * @bar: BAR number |
16 | * @maxlen: length of the memory to map | 16 | * @offset: map memory at the given offset in BAR |
17 | * @maxlen: max length of the memory to map | ||
17 | * | 18 | * |
18 | * Using this function you will get a __iomem address to your device BAR. | 19 | * Using this function you will get a __iomem address to your device BAR. |
19 | * You can access it using ioread*() and iowrite*(). These functions hide | 20 | * You can access it using ioread*() and iowrite*(). These functions hide |
@@ -21,16 +22,21 @@ | |||
21 | * you expect from them in the correct way. | 22 | * you expect from them in the correct way. |
22 | * | 23 | * |
23 | * @maxlen specifies the maximum length to map. If you want to get access to | 24 | * @maxlen specifies the maximum length to map. If you want to get access to |
24 | * the complete BAR without checking for its length first, pass %0 here. | 25 | * the complete BAR from offset to the end, pass %0 here. |
25 | * */ | 26 | * */ |
26 | void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) | 27 | void __iomem *pci_iomap_range(struct pci_dev *dev, |
28 | int bar, | ||
29 | unsigned long offset, | ||
30 | unsigned long maxlen) | ||
27 | { | 31 | { |
28 | resource_size_t start = pci_resource_start(dev, bar); | 32 | resource_size_t start = pci_resource_start(dev, bar); |
29 | resource_size_t len = pci_resource_len(dev, bar); | 33 | resource_size_t len = pci_resource_len(dev, bar); |
30 | unsigned long flags = pci_resource_flags(dev, bar); | 34 | unsigned long flags = pci_resource_flags(dev, bar); |
31 | 35 | ||
32 | if (!len || !start) | 36 | if (len <= offset || !start) |
33 | return NULL; | 37 | return NULL; |
38 | len -= offset; | ||
39 | start += offset; | ||
34 | if (maxlen && len > maxlen) | 40 | if (maxlen && len > maxlen) |
35 | len = maxlen; | 41 | len = maxlen; |
36 | if (flags & IORESOURCE_IO) | 42 | if (flags & IORESOURCE_IO) |
@@ -43,6 +49,25 @@ void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) | |||
43 | /* What? */ | 49 | /* What? */ |
44 | return NULL; | 50 | return NULL; |
45 | } | 51 | } |
52 | EXPORT_SYMBOL(pci_iomap_range); | ||
46 | 53 | ||
54 | /** | ||
55 | * pci_iomap - create a virtual mapping cookie for a PCI BAR | ||
56 | * @dev: PCI device that owns the BAR | ||
57 | * @bar: BAR number | ||
58 | * @maxlen: length of the memory to map | ||
59 | * | ||
60 | * Using this function you will get a __iomem address to your device BAR. | ||
61 | * You can access it using ioread*() and iowrite*(). These functions hide | ||
62 | * the details if this is a MMIO or PIO address space and will just do what | ||
63 | * you expect from them in the correct way. | ||
64 | * | ||
65 | * @maxlen specifies the maximum length to map. If you want to get access to | ||
66 | * the complete BAR without checking for its length first, pass %0 here. | ||
67 | * */ | ||
68 | void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) | ||
69 | { | ||
70 | return pci_iomap_range(dev, bar, 0, maxlen); | ||
71 | } | ||
47 | EXPORT_SYMBOL(pci_iomap); | 72 | EXPORT_SYMBOL(pci_iomap); |
48 | #endif /* CONFIG_PCI */ | 73 | #endif /* CONFIG_PCI */ |