From: Michael S Tsirkin <mst@redhat.com>
Cc: Arnd Bergmann <arnd@arndb.de>,
Rusty Russell <rusty@rustcorp.com.au>,
"Michael S. Tsirkin" <mst@redhat.com>,
Jonas Bonn <jonas@southpole.se>,
linux-arch@vger.kernel.org, linux-kernel@vger.kernel.org,
Jesse Barnes <jbarnes@virtuousgeek.org>
Subject: [PATCHv2 RFC] pci: add pci_iomap_range
Date: Mon, 26 Dec 2011 16:05:55 +0200 [thread overview]
Message-ID: <20111226140449.GA18077@redhat.com> (raw)
In-Reply-To: <87wr9xp9cr.fsf@rustcorp.com.au>
Virtio drivers should map the part of the range they need, not necessarily
all of it. They also need non-cacheable mapping even for
prefetchable BARs.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
---
>Rusty Russell wrote:
>> I think that we should add a forcenocache flag.
>> This will let devices put the cap structure in
>> the prefetcheable BAR. That has an advantage that
>> it can be located anywhere in the 2^64 space,
>> while non-prefetcheable BARs are limited to lower 4G
>> for devices behind a PCI-to-PCI bridge.
>OK, want to respin that patch (or patch on top and I'll fold?)
Here comes (warning - untested). This is on top of master.
As I'm moving this function for portability into
a separate file, it might be a good idea for this
to be rebased on top of my linux-next tree?
The whole mmio rework is not 3.3 material yes, is it?
include/asm-generic/io.h | 5 ++++
include/asm-generic/iomap.h | 13 ++++++++++++
lib/iomap.c | 46 +++++++++++++++++++++++++++++++++++++-----
3 files changed, 58 insertions(+), 6 deletions(-)
diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h
index 9120887..78aa159 100644
--- a/include/asm-generic/io.h
+++ b/include/asm-generic/io.h
@@ -286,6 +286,11 @@ static inline void writesb(const void __iomem *addr, const void *buf, int len)
/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
struct pci_dev;
extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
+extern void __iomem *pci_iomap_range(struct pci_dev *dev, int bar,
+ unsigned offset,
+ unsigned long minlen,
+ unsigned long maxlen,
+ bool force_nocache);
static inline void pci_iounmap(struct pci_dev *dev, void __iomem *p)
{
}
diff --git a/include/asm-generic/iomap.h b/include/asm-generic/iomap.h
index 98dcd76..584a2b6 100644
--- a/include/asm-generic/iomap.h
+++ b/include/asm-generic/iomap.h
@@ -70,8 +70,21 @@ extern void ioport_unmap(void __iomem *);
/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
struct pci_dev;
extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
+extern void __iomem *pci_iomap_range(struct pci_dev *dev, int bar,
+ unsigned offset,
+ unsigned long minlen,
+ unsigned long maxlen,
+ bool force_nocache);
extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
#else
+static inline void __iomem *pci_iomap_range(struct pci_dev *dev, int bar,
+ unsigned offset,
+ unsigned long minlen,
+ unsigned long maxlen,
+ bool force_nocache);
+{
+ return NULL;
+}
struct pci_dev;
static inline void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max)
{
diff --git a/lib/iomap.c b/lib/iomap.c
index 5dbcb4b..efa7c29 100644
--- a/lib/iomap.c
+++ b/lib/iomap.c
@@ -243,33 +243,47 @@ EXPORT_SYMBOL(ioport_unmap);
#ifdef CONFIG_PCI
/**
- * pci_iomap - create a virtual mapping cookie for a PCI BAR
+ * pci_iomap_range - create a virtual mapping cookie for a PCI BAR
* @dev: PCI device that owns the BAR
* @bar: BAR number
- * @maxlen: length of the memory to map
+ * @offset: map memory at the given offset in BAR
+ * @minlen: min length of the memory to map
+ * @maxlen: max length of the memory to map
*
* Using this function you will get a __iomem address to your device BAR.
* You can access it using ioread*() and iowrite*(). These functions hide
* the details if this is a MMIO or PIO address space and will just do what
* you expect from them in the correct way.
*
+ * @minlen specifies the minimum length to map. We check that BAR is
+ * large enough.
* @maxlen specifies the maximum length to map. If you want to get access to
- * the complete BAR without checking for its length first, pass %0 here.
+ * the complete BAR from offset to the end, pass %0 here.
+ * @force_nocache makes the mapping noncacheable even if the BAR
+ * is prefetcheable. It has no effect otherwise.
* */
-void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
+void __iomem *pci_iomap_range(struct pci_dev *dev, int bar,
+ unsigned offset,
+ unsigned long minlen,
+ unsigned long maxlen,
+ bool force_nocache)
{
resource_size_t start = pci_resource_start(dev, bar);
resource_size_t len = pci_resource_len(dev, bar);
unsigned long flags = pci_resource_flags(dev, bar);
- if (!len || !start)
+ if (len <= offset || !start)
+ return NULL;
+ len -= offset;
+ start += offset;
+ if (len < minlen)
return NULL;
if (maxlen && len > maxlen)
len = maxlen;
if (flags & IORESOURCE_IO)
return ioport_map(start, len);
if (flags & IORESOURCE_MEM) {
- if (flags & IORESOURCE_CACHEABLE)
+ if (!force_nocache && (flags & IORESOURCE_CACHEABLE))
return ioremap(start, len);
return ioremap_nocache(start, len);
}
@@ -277,10 +291,30 @@ void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
return NULL;
}
+/**
+ * pci_iomap - create a virtual mapping cookie for a PCI BAR
+ * @dev: PCI device that owns the BAR
+ * @bar: BAR number
+ * @maxlen: length of the memory to map
+ *
+ * Using this function you will get a __iomem address to your device BAR.
+ * You can access it using ioread*() and iowrite*(). These functions hide
+ * the details if this is a MMIO or PIO address space and will just do what
+ * you expect from them in the correct way.
+ *
+ * @maxlen specifies the maximum length to map. If you want to get access to
+ * the complete BAR without checking for its length first, pass %0 here.
+ * */
+void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
+{
+ return pci_iomap_range(dev, bar, 0, 0, maxlen, false);
+}
+
void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
{
IO_COND(addr, /* nothing */, iounmap(addr));
}
EXPORT_SYMBOL(pci_iomap);
+EXPORT_SYMBOL(pci_iomap_range);
EXPORT_SYMBOL(pci_iounmap);
#endif /* CONFIG_PCI */
--
1.7.8.382.g3daff
WARNING: multiple messages have this Message-ID (diff)
From: Michael S Tsirkin <mst@redhat.com>
To: unlisted-recipients:; (no To-header on input)
Cc: Arnd Bergmann <arnd@arndb.de>,
Rusty Russell <rusty@rustcorp.com.au>,
"Michael S. Tsirkin" <mst@redhat.com>,
Jonas Bonn <jonas@southpole.se>,
linux-arch@vger.kernel.org, linux-kernel@vger.kernel.org,
Jesse Barnes <jbarnes@virtuousgeek.org>
Subject: [PATCHv2 RFC] pci: add pci_iomap_range
Date: Mon, 26 Dec 2011 16:05:55 +0200 [thread overview]
Message-ID: <20111226140449.GA18077@redhat.com> (raw)
In-Reply-To: <87wr9xp9cr.fsf@rustcorp.com.au>
Virtio drivers should map the part of the range they need, not necessarily
all of it. They also need non-cacheable mapping even for
prefetchable BARs.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
---
>Rusty Russell wrote:
>> I think that we should add a forcenocache flag.
>> This will let devices put the cap structure in
>> the prefetcheable BAR. That has an advantage that
>> it can be located anywhere in the 2^64 space,
>> while non-prefetcheable BARs are limited to lower 4G
>> for devices behind a PCI-to-PCI bridge.
>OK, want to respin that patch (or patch on top and I'll fold?)
Here comes (warning - untested). This is on top of master.
As I'm moving this function for portability into
a separate file, it might be a good idea for this
to be rebased on top of my linux-next tree?
The whole mmio rework is not 3.3 material yes, is it?
include/asm-generic/io.h | 5 ++++
include/asm-generic/iomap.h | 13 ++++++++++++
lib/iomap.c | 46 +++++++++++++++++++++++++++++++++++++-----
3 files changed, 58 insertions(+), 6 deletions(-)
diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h
index 9120887..78aa159 100644
--- a/include/asm-generic/io.h
+++ b/include/asm-generic/io.h
@@ -286,6 +286,11 @@ static inline void writesb(const void __iomem *addr, const void *buf, int len)
/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
struct pci_dev;
extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
+extern void __iomem *pci_iomap_range(struct pci_dev *dev, int bar,
+ unsigned offset,
+ unsigned long minlen,
+ unsigned long maxlen,
+ bool force_nocache);
static inline void pci_iounmap(struct pci_dev *dev, void __iomem *p)
{
}
diff --git a/include/asm-generic/iomap.h b/include/asm-generic/iomap.h
index 98dcd76..584a2b6 100644
--- a/include/asm-generic/iomap.h
+++ b/include/asm-generic/iomap.h
@@ -70,8 +70,21 @@ extern void ioport_unmap(void __iomem *);
/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
struct pci_dev;
extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
+extern void __iomem *pci_iomap_range(struct pci_dev *dev, int bar,
+ unsigned offset,
+ unsigned long minlen,
+ unsigned long maxlen,
+ bool force_nocache);
extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
#else
+static inline void __iomem *pci_iomap_range(struct pci_dev *dev, int bar,
+ unsigned offset,
+ unsigned long minlen,
+ unsigned long maxlen,
+ bool force_nocache);
+{
+ return NULL;
+}
struct pci_dev;
static inline void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max)
{
diff --git a/lib/iomap.c b/lib/iomap.c
index 5dbcb4b..efa7c29 100644
--- a/lib/iomap.c
+++ b/lib/iomap.c
@@ -243,33 +243,47 @@ EXPORT_SYMBOL(ioport_unmap);
#ifdef CONFIG_PCI
/**
- * pci_iomap - create a virtual mapping cookie for a PCI BAR
+ * pci_iomap_range - create a virtual mapping cookie for a PCI BAR
* @dev: PCI device that owns the BAR
* @bar: BAR number
- * @maxlen: length of the memory to map
+ * @offset: map memory at the given offset in BAR
+ * @minlen: min length of the memory to map
+ * @maxlen: max length of the memory to map
*
* Using this function you will get a __iomem address to your device BAR.
* You can access it using ioread*() and iowrite*(). These functions hide
* the details if this is a MMIO or PIO address space and will just do what
* you expect from them in the correct way.
*
+ * @minlen specifies the minimum length to map. We check that BAR is
+ * large enough.
* @maxlen specifies the maximum length to map. If you want to get access to
- * the complete BAR without checking for its length first, pass %0 here.
+ * the complete BAR from offset to the end, pass %0 here.
+ * @force_nocache makes the mapping noncacheable even if the BAR
+ * is prefetcheable. It has no effect otherwise.
* */
-void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
+void __iomem *pci_iomap_range(struct pci_dev *dev, int bar,
+ unsigned offset,
+ unsigned long minlen,
+ unsigned long maxlen,
+ bool force_nocache)
{
resource_size_t start = pci_resource_start(dev, bar);
resource_size_t len = pci_resource_len(dev, bar);
unsigned long flags = pci_resource_flags(dev, bar);
- if (!len || !start)
+ if (len <= offset || !start)
+ return NULL;
+ len -= offset;
+ start += offset;
+ if (len < minlen)
return NULL;
if (maxlen && len > maxlen)
len = maxlen;
if (flags & IORESOURCE_IO)
return ioport_map(start, len);
if (flags & IORESOURCE_MEM) {
- if (flags & IORESOURCE_CACHEABLE)
+ if (!force_nocache && (flags & IORESOURCE_CACHEABLE))
return ioremap(start, len);
return ioremap_nocache(start, len);
}
@@ -277,10 +291,30 @@ void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
return NULL;
}
+/**
+ * pci_iomap - create a virtual mapping cookie for a PCI BAR
+ * @dev: PCI device that owns the BAR
+ * @bar: BAR number
+ * @maxlen: length of the memory to map
+ *
+ * Using this function you will get a __iomem address to your device BAR.
+ * You can access it using ioread*() and iowrite*(). These functions hide
+ * the details if this is a MMIO or PIO address space and will just do what
+ * you expect from them in the correct way.
+ *
+ * @maxlen specifies the maximum length to map. If you want to get access to
+ * the complete BAR without checking for its length first, pass %0 here.
+ * */
+void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen)
+{
+ return pci_iomap_range(dev, bar, 0, 0, maxlen, false);
+}
+
void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
{
IO_COND(addr, /* nothing */, iounmap(addr));
}
EXPORT_SYMBOL(pci_iomap);
+EXPORT_SYMBOL(pci_iomap_range);
EXPORT_SYMBOL(pci_iounmap);
#endif /* CONFIG_PCI */
--
1.7.8.382.g3daff
next prev parent reply other threads:[~2011-12-26 14:04 UTC|newest]
Thread overview: 106+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-12-08 10:22 [PATCH 0/11] RFC: PCI using capabilitities Rusty Russell
2011-12-08 10:30 ` [RFC 1/11] virtio: use u32, not bitmap for struct virtio_device's features Rusty Russell
2011-12-08 10:31 ` [RFC 2/11] virtio: add support for 64 bit features Rusty Russell
2011-12-08 10:32 ` [PATCH 0/11] RFC: PCI using capabilitities Sasha Levin
2011-12-08 10:32 ` [RFC 3/11] pci: add pci_iomap_range Rusty Russell
2011-12-15 8:30 ` Michael S. Tsirkin
2011-12-16 1:56 ` Rusty Russell
2011-12-26 14:05 ` Michael S Tsirkin [this message]
2011-12-26 14:05 ` [PATCHv2 RFC] " Michael S Tsirkin
2011-12-08 10:34 ` [RFC 4/11] virtio-pci: define layout for virtio vendor-specific capabilities Rusty Russell
2011-12-10 21:14 ` Sasha Levin
2011-12-08 10:35 ` [RFC 6/11] virtio_pci: move old defines to legacy, introduce new structure Rusty Russell
2011-12-08 10:38 ` [RFC 6/11] virtio_pci: don't use the legacy driver if we find the new PCI capabilities Rusty Russell
2011-12-10 21:18 ` Sasha Levin
2011-12-11 5:15 ` Rusty Russell
2011-12-11 9:37 ` Michael S. Tsirkin
2011-12-08 10:39 ` [RFC 7/11] virtio_pci: new, capability-aware driver Rusty Russell
2011-12-11 9:42 ` Michael S. Tsirkin
2011-12-11 22:45 ` Rusty Russell
2011-12-12 11:49 ` Michael S. Tsirkin
2011-12-12 18:10 ` Don Dutile
2011-12-16 1:58 ` Rusty Russell
2013-05-28 7:56 ` Michael S. Tsirkin
2013-05-29 1:17 ` Rusty Russell
2013-05-29 10:21 ` Michael S. Tsirkin
2013-05-30 2:17 ` Rusty Russell
2011-12-12 18:25 ` Michael S. Tsirkin
2011-12-13 2:21 ` Rusty Russell
2011-12-15 8:27 ` Michael S. Tsirkin
2011-12-16 1:50 ` Rusty Russell
2011-12-18 10:18 ` Michael S. Tsirkin
2011-12-19 6:06 ` Rusty Russell
2011-12-19 9:13 ` Michael S. Tsirkin
2011-12-19 11:08 ` Rusty Russell
2011-12-20 11:37 ` Michael S. Tsirkin
2011-12-21 0:33 ` Rusty Russell
2011-12-21 9:19 ` Michael S. Tsirkin
2012-01-10 17:03 ` Michael S. Tsirkin
2012-01-11 0:25 ` Rusty Russell
2012-01-11 1:48 ` Benjamin Herrenschmidt
2012-01-11 8:47 ` Stefan Hajnoczi
2012-01-11 9:10 ` Benjamin Herrenschmidt
2012-01-11 14:28 ` Stefan Hajnoczi
2012-01-11 15:39 ` Michael S. Tsirkin
2012-01-11 17:21 ` Stefan Hajnoczi
2012-01-11 18:34 ` Michael S. Tsirkin
2012-01-11 20:56 ` Benjamin Herrenschmidt
2012-01-11 20:46 ` Benjamin Herrenschmidt
2012-01-12 10:37 ` Stefan Hajnoczi
2012-01-11 10:21 ` Michael S. Tsirkin
2012-01-11 21:13 ` Benjamin Herrenschmidt
2012-01-11 22:13 ` Michael S. Tsirkin
2012-01-11 22:19 ` Benjamin Herrenschmidt
2012-01-11 22:56 ` Benjamin Herrenschmidt
2012-01-12 5:29 ` Michael S. Tsirkin
2012-01-12 6:13 ` Benjamin Herrenschmidt
2012-01-12 6:37 ` Michael S. Tsirkin
2012-01-12 2:01 ` Rusty Russell
2012-01-12 4:31 ` Benjamin Herrenschmidt
2012-01-12 6:09 ` Michael S. Tsirkin
2012-01-12 6:28 ` Benjamin Herrenschmidt
2012-01-12 6:51 ` Michael S. Tsirkin
2012-01-12 7:03 ` Benjamin Herrenschmidt
2012-01-12 6:00 ` Michael S. Tsirkin
2012-01-13 3:22 ` Rusty Russell
2012-01-11 13:30 ` Anthony Liguori
2012-01-11 15:12 ` Michael S. Tsirkin
2012-01-11 15:15 ` Anthony Liguori
2012-01-11 15:21 ` Michael S. Tsirkin
2012-01-11 15:28 ` Anthony Liguori
2012-01-11 15:45 ` Michael S. Tsirkin
2012-01-11 16:02 ` Anthony Liguori
2012-01-11 17:08 ` Michael S. Tsirkin
2012-01-11 19:42 ` Anthony Liguori
2012-01-11 20:14 ` Michael S. Tsirkin
2012-01-11 20:26 ` Anthony Liguori
2012-01-11 21:02 ` Benjamin Herrenschmidt
2012-01-11 22:02 ` Michael S. Tsirkin
2012-01-11 22:16 ` Benjamin Herrenschmidt
2012-01-12 1:42 ` Rusty Russell
2012-01-13 2:19 ` Michael S. Tsirkin
2012-01-13 2:32 ` Benjamin Herrenschmidt
2012-01-18 15:29 ` Michael S. Tsirkin
2012-01-22 22:53 ` Rusty Russell
2012-01-18 4:52 ` Rusty Russell
2012-01-11 21:58 ` Michael S. Tsirkin
2012-01-11 20:59 ` Benjamin Herrenschmidt
2012-01-11 20:51 ` Benjamin Herrenschmidt
2012-01-11 20:50 ` Benjamin Herrenschmidt
2012-01-12 1:35 ` Rusty Russell
2011-12-08 10:40 ` [RFC 8/11] virtio_pci: share structure between legacy and modern Rusty Russell
2011-12-08 10:41 ` [RFC 9/11] virtio_pci: share interrupt/notify handlers " Rusty Russell
2011-12-08 10:42 ` [RFC 10/11] virtio_pci: share virtqueue setup/teardown between modern and legacy driver Rusty Russell
2011-12-08 10:44 ` [RFC 11/11] virtio_pci: simplify common helpers Rusty Russell
2011-12-08 15:37 ` [PATCH 0/11] RFC: PCI using capabilitities Sasha Levin
2011-12-09 6:17 ` Rusty Russell
2011-12-10 21:32 ` Sasha Levin
2011-12-11 9:05 ` Avi Kivity
2011-12-11 10:03 ` Sasha Levin
2011-12-11 12:30 ` Michael S. Tsirkin
2011-12-11 12:48 ` Sasha Levin
2011-12-11 12:48 ` Sasha Levin
2011-12-11 12:47 ` Michael S. Tsirkin
2011-12-11 12:53 ` Sasha Levin
2011-12-11 12:53 ` Sasha Levin
2011-12-08 15:37 ` Sasha Levin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20111226140449.GA18077@redhat.com \
--to=mst@redhat.com \
--cc=arnd@arndb.de \
--cc=jbarnes@virtuousgeek.org \
--cc=jonas@southpole.se \
--cc=linux-arch@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=rusty@rustcorp.com.au \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.