summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/amd64/amd64/busdma_machdep.c7
-rw-r--r--sys/arm/arm/busdma_machdep.c7
-rw-r--r--sys/dev/usb2/core/usb2_busdma.c2
-rw-r--r--sys/i386/i386/busdma_machdep.c7
-rw-r--r--sys/ia64/ia64/busdma_machdep.c7
-rw-r--r--sys/sys/bus_dma.h7
6 files changed, 36 insertions, 1 deletions
diff --git a/sys/amd64/amd64/busdma_machdep.c b/sys/amd64/amd64/busdma_machdep.c
index f68e90b..c8f689a 100644
--- a/sys/amd64/amd64/busdma_machdep.c
+++ b/sys/amd64/amd64/busdma_machdep.c
@@ -1128,6 +1128,13 @@ add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, vm_offset_t vaddr,
bz->active_bpages++;
mtx_unlock(&bounce_lock);
+ if (dmat->flags & BUS_DMA_KEEP_PG_OFFSET) {
+ /* page offset needs to be preserved */
+ bpage->vaddr &= ~PAGE_MASK;
+ bpage->busaddr &= ~PAGE_MASK;
+ bpage->vaddr |= vaddr & PAGE_MASK;
+ bpage->busaddr |= vaddr & PAGE_MASK;
+ }
bpage->datavaddr = vaddr;
bpage->datacount = size;
STAILQ_INSERT_TAIL(&(map->bpages), bpage, links);
diff --git a/sys/arm/arm/busdma_machdep.c b/sys/arm/arm/busdma_machdep.c
index f53a47b..fb14ab0 100644
--- a/sys/arm/arm/busdma_machdep.c
+++ b/sys/arm/arm/busdma_machdep.c
@@ -1417,6 +1417,13 @@ add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, vm_offset_t vaddr,
bz->active_bpages++;
mtx_unlock(&bounce_lock);
+ if (dmat->flags & BUS_DMA_KEEP_PG_OFFSET) {
+ /* page offset needs to be preserved */
+ bpage->vaddr &= ~PAGE_MASK;
+ bpage->busaddr &= ~PAGE_MASK;
+ bpage->vaddr |= vaddr & PAGE_MASK;
+ bpage->busaddr |= vaddr & PAGE_MASK;
+ }
bpage->datavaddr = vaddr;
bpage->datacount = size;
STAILQ_INSERT_TAIL(&(map->bpages), bpage, links);
diff --git a/sys/dev/usb2/core/usb2_busdma.c b/sys/dev/usb2/core/usb2_busdma.c
index 6c1f182e3..8254e6e 100644
--- a/sys/dev/usb2/core/usb2_busdma.c
+++ b/sys/dev/usb2/core/usb2_busdma.c
@@ -351,7 +351,7 @@ usb2_dma_tag_create(struct usb2_dma_tag *udt,
(2 + (size / USB_PAGE_SIZE)) : 1,
/* maxsegsz */ (align == 1) ?
USB_PAGE_SIZE : size,
- /* flags */ 0,
+ /* flags */ BUS_DMA_KEEP_PG_OFFSET,
/* lockfn */ &usb2_dma_lock_cb,
/* lockarg */ NULL,
&tag)) {
diff --git a/sys/i386/i386/busdma_machdep.c b/sys/i386/i386/busdma_machdep.c
index 4ff4f92..04844f9 100644
--- a/sys/i386/i386/busdma_machdep.c
+++ b/sys/i386/i386/busdma_machdep.c
@@ -1146,6 +1146,13 @@ add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, vm_offset_t vaddr,
bz->active_bpages++;
mtx_unlock(&bounce_lock);
+ if (dmat->flags & BUS_DMA_KEEP_PG_OFFSET) {
+ /* page offset needs to be preserved */
+ bpage->vaddr &= ~PAGE_MASK;
+ bpage->busaddr &= ~PAGE_MASK;
+ bpage->vaddr |= vaddr & PAGE_MASK;
+ bpage->busaddr |= vaddr & PAGE_MASK;
+ }
bpage->datavaddr = vaddr;
bpage->datacount = size;
STAILQ_INSERT_TAIL(&(map->bpages), bpage, links);
diff --git a/sys/ia64/ia64/busdma_machdep.c b/sys/ia64/ia64/busdma_machdep.c
index 6cc2988..659db52 100644
--- a/sys/ia64/ia64/busdma_machdep.c
+++ b/sys/ia64/ia64/busdma_machdep.c
@@ -936,6 +936,13 @@ add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, vm_offset_t vaddr,
active_bpages++;
mtx_unlock(&bounce_lock);
+ if (dmat->flags & BUS_DMA_KEEP_PG_OFFSET) {
+ /* page offset needs to be preserved */
+ bpage->vaddr &= ~PAGE_MASK;
+ bpage->busaddr &= ~PAGE_MASK;
+ bpage->vaddr |= vaddr & PAGE_MASK;
+ bpage->busaddr |= vaddr & PAGE_MASK;
+ }
bpage->datavaddr = vaddr;
bpage->datacount = size;
STAILQ_INSERT_TAIL(&(map->bpages), bpage, links);
diff --git a/sys/sys/bus_dma.h b/sys/sys/bus_dma.h
index f89d522..0dad326 100644
--- a/sys/sys/bus_dma.h
+++ b/sys/sys/bus_dma.h
@@ -102,6 +102,13 @@
#define BUS_DMA_NOWRITE 0x100
#define BUS_DMA_NOCACHE 0x200
+/*
+ * The following flag is a DMA tag hint that the page offset of the
+ * loaded kernel virtual address must be preserved in the first
+ * physical segment address, when the KVA is loaded into DMA.
+ */
+#define BUS_DMA_KEEP_PG_OFFSET 0x400
+
/* Forwards needed by prototypes below. */
struct mbuf;
struct uio;
OpenPOWER on IntegriCloud