svn commit: r244810 - in projects/physbio/sys: arm/arm ia64/ia64 kern mips/mips powerpc/powerpc sys x86/x86
Jeff Roberson
jeff at FreeBSD.org
Sat Dec 29 03:28:58 UTC 2012
Author: jeff
Date: Sat Dec 29 03:28:55 2012
New Revision: 244810
URL: http://svnweb.freebsd.org/changeset/base/244810
Log:
- Add support for bouncing physical pages via two new physical memory copy
routines: physcopyin and physcopyout. These are implemented using the
existing uiomove_fromphys() support. The phys map functions have not yet
been converted to bounce.
Sponsored by: EMC / Isilon Storage Division
Modified:
projects/physbio/sys/arm/arm/busdma_machdep-v6.c
projects/physbio/sys/arm/arm/busdma_machdep.c
projects/physbio/sys/ia64/ia64/busdma_machdep.c
projects/physbio/sys/kern/subr_busdma.c
projects/physbio/sys/kern/subr_uio.c
projects/physbio/sys/mips/mips/busdma_machdep.c
projects/physbio/sys/powerpc/powerpc/busdma_machdep.c
projects/physbio/sys/sys/uio.h
projects/physbio/sys/x86/x86/busdma_machdep.c
Modified: projects/physbio/sys/arm/arm/busdma_machdep-v6.c
==============================================================================
--- projects/physbio/sys/arm/arm/busdma_machdep-v6.c Sat Dec 29 02:36:08 2012 (r244809)
+++ projects/physbio/sys/arm/arm/busdma_machdep-v6.c Sat Dec 29 03:28:55 2012 (r244810)
@@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include <sys/proc.h>
#include <sys/mutex.h>
#include <sys/sysctl.h>
+#include <sys/uio.h>
#include <vm/vm.h>
#include <vm/vm_page.h>
@@ -98,6 +99,7 @@ struct bounce_page {
vm_offset_t vaddr; /* kva of bounce buffer */
bus_addr_t busaddr; /* Physical address */
vm_offset_t datavaddr; /* kva of client data */
+ bus_addr_t dataaddr; /* client physical address */
bus_size_t datacount; /* client data count */
STAILQ_ENTRY(bounce_page) links;
};
@@ -160,7 +162,8 @@ static int alloc_bounce_pages(bus_dma_ta
static int reserve_bounce_pages(bus_dma_tag_t dmat, bus_dmamap_t map,
int commit);
static bus_addr_t add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map,
- vm_offset_t vaddr, bus_size_t size);
+ vm_offset_t vaddr, bus_addr_t addr,
+ bus_size_t size);
static void free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage);
int run_filter(bus_dma_tag_t dmat, bus_addr_t paddr);
static int _bus_dmamap_count_pages(bus_dma_tag_t dmat, bus_dmamap_t map,
@@ -858,7 +861,8 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dm
if (((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0) &&
map->pagesneeded != 0 && run_filter(dmat, curaddr)) {
- curaddr = add_bounce_page(dmat, map, vaddr, sgsize);
+ curaddr = add_bounce_page(dmat, map, vaddr, curaddr,
+ sgsize);
} else {
sl = &map->slist[map->sync_count - 1];
if (map->sync_count == 0 ||
@@ -1021,9 +1025,14 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus
if (op & BUS_DMASYNC_PREWRITE) {
while (bpage != NULL) {
- bcopy((void *)bpage->datavaddr,
- (void *)bpage->vaddr,
- bpage->datacount);
+ if (bpage->datavaddr != 0)
+ bcopy((void *)bpage->datavaddr,
+ (void *)bpage->vaddr,
+ bpage->datacount);
+ else
+ physcopyout(page->dataaddr,
+ (void *)bpage->vaddr,
+ bpage->datacount);
cpu_dcache_wb_range((vm_offset_t)bpage->vaddr,
bpage->datacount);
l2cache_wb_range((vm_offset_t)bpage->vaddr,
@@ -1060,9 +1069,14 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus
arm_dcache_align;
cpu_dcache_inv_range(startv, len);
l2cache_inv_range(startv, startp, len);
- bcopy((void *)bpage->vaddr,
- (void *)bpage->datavaddr,
- bpage->datacount);
+ if (bpage->datavaddr != 0)
+ bcopy((void *)bpage->vaddr,
+ (void *)bpage->datavaddr,
+ bpage->datacount);
+ else
+ physcopyin((void *)bpage->vaddr,
+ bpage->dataaddr,
+ bpage->datacount);
bpage = STAILQ_NEXT(bpage, links);
}
dmat->bounce_zone->total_bounced++;
@@ -1346,7 +1360,7 @@ reserve_bounce_pages(bus_dma_tag_t dmat,
static bus_addr_t
add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, vm_offset_t vaddr,
- bus_size_t size)
+ bus_addr_t addr, bus_size_t size)
{
struct bounce_zone *bz;
struct bounce_page *bpage;
@@ -1380,6 +1394,7 @@ add_bounce_page(bus_dma_tag_t dmat, bus_
bpage->busaddr |= vaddr & PAGE_MASK;
}
bpage->datavaddr = vaddr;
+ bpage->dataaddr = addr;
bpage->datacount = size;
STAILQ_INSERT_TAIL(&(map->bpages), bpage, links);
return (bpage->busaddr);
Modified: projects/physbio/sys/arm/arm/busdma_machdep.c
==============================================================================
--- projects/physbio/sys/arm/arm/busdma_machdep.c Sat Dec 29 02:36:08 2012 (r244809)
+++ projects/physbio/sys/arm/arm/busdma_machdep.c Sat Dec 29 03:28:55 2012 (r244810)
@@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include <sys/ktr.h>
#include <sys/kernel.h>
#include <sys/sysctl.h>
+#include <sys/uio.h>
#include <vm/vm.h>
#include <vm/vm_page.h>
@@ -96,6 +97,7 @@ struct bounce_page {
vm_offset_t vaddr_nocache; /* kva of bounce buffer uncached */
bus_addr_t busaddr; /* Physical address */
vm_offset_t datavaddr; /* kva of client data */
+ bus_addr_t dataaddr; /* client physical address */
bus_size_t datacount; /* client data count */
STAILQ_ENTRY(bounce_page) links;
};
@@ -173,7 +175,8 @@ static int alloc_bounce_pages(bus_dma_ta
static int reserve_bounce_pages(bus_dma_tag_t dmat, bus_dmamap_t map,
int commit);
static bus_addr_t add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map,
- vm_offset_t vaddr, bus_size_t size);
+ vm_offset_t vaddr, bus_addr_t addr,
+ bus_size_t size);
static void free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage);
/* Default tag, as most drivers provide no parent tag. */
@@ -930,7 +933,8 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dm
if (((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0) &&
map->pagesneeded != 0 && run_filter(dmat, curaddr)) {
- curaddr = add_bounce_page(dmat, map, vaddr, sgsize);
+ curaddr = add_bounce_page(dmat, map, vaddr, curaddr,
+ sgsize);
} else {
sl = &map->slist[map->sync_count - 1];
if (map->sync_count == 0 ||
@@ -1059,10 +1063,18 @@ _bus_dmamap_sync_bp(bus_dma_tag_t dmat,
STAILQ_FOREACH(bpage, &map->bpages, links) {
if (op & BUS_DMASYNC_PREWRITE) {
- bcopy((void *)bpage->datavaddr,
- (void *)(bpage->vaddr_nocache != 0 ?
- bpage->vaddr_nocache : bpage->vaddr),
- bpage->datacount);
+ if (bpage->datavaddr != 0)
+ bcopy((void *)bpage->datavaddr,
+ (void *)(bpage->vaddr_nocache != 0 ?
+ bpage->vaddr_nocache :
+ bpage->vaddr),
+ bpage->datacount);
+ else
+ physcopyout(bpage->dataaddr,
+ (void *)(bpage->vaddr_nocache != 0 ?
+ bpage->vaddr_nocache :
+ bpage->vaddr),
+ bpage->datacount);
if (bpage->vaddr_nocache == 0) {
cpu_dcache_wb_range(bpage->vaddr,
bpage->datacount);
@@ -1078,9 +1090,14 @@ _bus_dmamap_sync_bp(bus_dma_tag_t dmat,
cpu_l2cache_inv_range(bpage->vaddr,
bpage->datacount);
}
- bcopy((void *)(bpage->vaddr_nocache != 0 ?
- bpage->vaddr_nocache : bpage->vaddr),
- (void *)bpage->datavaddr, bpage->datacount);
+ if (bpage->datavaddr != 0)
+ bcopy((void *)(bpage->vaddr_nocache != 0 ?
+ bpage->vaddr_nocache : bpage->vaddr),
+ (void *)bpage->datavaddr, bpage->datacount);
+ else
+ physcopyin((void *)(bpage->vaddr_nocache != 0 ?
+ bpage->vaddr_nocache : bpage->vaddr),
+ bpage->dataaddr, bpage->datacount);
dmat->bounce_zone->total_bounced++;
}
}
@@ -1265,7 +1282,7 @@ reserve_bounce_pages(bus_dma_tag_t dmat,
static bus_addr_t
add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, vm_offset_t vaddr,
- bus_size_t size)
+ bus_addr_t addr, bus_size_t size)
{
struct bounce_zone *bz;
struct bounce_page *bpage;
@@ -1298,6 +1315,7 @@ add_bounce_page(bus_dma_tag_t dmat, bus_
bpage->busaddr |= vaddr & PAGE_MASK;
}
bpage->datavaddr = vaddr;
+ bpage->dataaddr = addr;
bpage->datacount = size;
STAILQ_INSERT_TAIL(&(map->bpages), bpage, links);
return (bpage->busaddr);
Modified: projects/physbio/sys/ia64/ia64/busdma_machdep.c
==============================================================================
--- projects/physbio/sys/ia64/ia64/busdma_machdep.c Sat Dec 29 02:36:08 2012 (r244809)
+++ projects/physbio/sys/ia64/ia64/busdma_machdep.c Sat Dec 29 03:28:55 2012 (r244810)
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <sys/interrupt.h>
#include <sys/proc.h>
#include <sys/sysctl.h>
+#include <sys/uio.h>
#include <vm/vm.h>
#include <vm/vm_page.h>
@@ -71,6 +72,7 @@ struct bounce_page {
vm_offset_t vaddr; /* kva of bounce buffer */
bus_addr_t busaddr; /* Physical address */
vm_offset_t datavaddr; /* kva of client data */
+ bus_addr_t dataaddr; /* client physical address */
bus_size_t datacount; /* client data count */
STAILQ_ENTRY(bounce_page) links;
};
@@ -120,7 +122,7 @@ static int alloc_bounce_pages(bus_dma_ta
static int reserve_bounce_pages(bus_dma_tag_t dmat, bus_dmamap_t map,
int commit);
static bus_addr_t add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map,
- vm_offset_t vaddr, bus_size_t size);
+ vm_offset_t vaddr, bus_addr_t addr, bus_size_t size);
static void free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage);
static __inline int run_filter(bus_dma_tag_t dmat, bus_addr_t paddr,
bus_size_t len);
@@ -641,7 +643,8 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dm
sgsize = buflen;
if (map->pagesneeded != 0 && run_filter(dmat, curaddr, sgsize))
- curaddr = add_bounce_page(dmat, map, vaddr, sgsize);
+ curaddr = add_bounce_page(dmat, map, vaddr, curaddr,
+ sgsize);
sgsize = _bus_dmamap_addseg(dmat, map, curaddr, sgsize, segs,
segp);
@@ -709,8 +712,14 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus
if (op & BUS_DMASYNC_PREWRITE) {
while (bpage != NULL) {
- bcopy((void *)bpage->datavaddr,
- (void *)bpage->vaddr, bpage->datacount);
+ if (bpage->datavaddr != 0)
+ bcopy((void *)bpage->datavaddr,
+ (void *)bpage->vaddr,
+ bpage->datacount);
+ else
+ physcopyout(bpage->dataaddr,
+ (void *)bpage->vaddr,
+ bpage->datacount);
bpage = STAILQ_NEXT(bpage, links);
}
total_bounced++;
@@ -718,8 +727,14 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus
if (op & BUS_DMASYNC_POSTREAD) {
while (bpage != NULL) {
- bcopy((void *)bpage->vaddr,
- (void *)bpage->datavaddr, bpage->datacount);
+ if (bpage->datavaddr != 0)
+ bcopy((void *)bpage->vaddr,
+ (void *)bpage->datavaddr,
+ bpage->datacount);
+ else
+ physcopyin((void *)bpage->vaddr,
+ bpage->dataaddr,
+ bpage->datacount);
bpage = STAILQ_NEXT(bpage, links);
}
total_bounced++;
@@ -792,7 +807,7 @@ reserve_bounce_pages(bus_dma_tag_t dmat,
static bus_addr_t
add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, vm_offset_t vaddr,
- bus_size_t size)
+ bus_addr_t addr, bus_size_t size)
{
struct bounce_page *bpage;
@@ -823,6 +838,7 @@ add_bounce_page(bus_dma_tag_t dmat, bus_
bpage->busaddr |= vaddr & PAGE_MASK;
}
bpage->datavaddr = vaddr;
+ bpage->dataaddr = addr;
bpage->datacount = size;
STAILQ_INSERT_TAIL(&(map->bpages), bpage, links);
return (bpage->busaddr);
Modified: projects/physbio/sys/kern/subr_busdma.c
==============================================================================
--- projects/physbio/sys/kern/subr_busdma.c Sat Dec 29 02:36:08 2012 (r244809)
+++ projects/physbio/sys/kern/subr_busdma.c Sat Dec 29 03:28:55 2012 (r244810)
@@ -173,8 +173,9 @@ _bus_dmamap_load_ccb(bus_dma_tag_t dmat,
kernel_pmap, flags, NULL, nsegs);
break;
case CAM_DATA_PADDR:
- error = _bus_dmamap_load_phys(dmat, map, (vm_paddr_t)data_ptr,
- dxfer_len, flags, NULL, nsegs);
+ error = _bus_dmamap_load_phys(dmat, map,
+ (vm_paddr_t)(uintptr_t)data_ptr, dxfer_len, flags, NULL,
+ nsegs);
break;
case CAM_DATA_SG:
error = _bus_dmamap_load_vlist(dmat, map,
Modified: projects/physbio/sys/kern/subr_uio.c
==============================================================================
--- projects/physbio/sys/kern/subr_uio.c Sat Dec 29 02:36:08 2012 (r244809)
+++ projects/physbio/sys/kern/subr_uio.c Sat Dec 29 03:28:55 2012 (r244810)
@@ -152,6 +152,52 @@ copyout_nofault(const void *kaddr, void
return (error);
}
+#define PHYS_PAGE_COUNT(len) (howmany(len, PAGE_SIZE) + 1)
+
+int
+physcopyin(void *src, vm_paddr_t dst, size_t len)
+{
+ vm_page_t m[PHYS_PAGE_COUNT(len)];
+ struct iovec iov[1];
+ struct uio uio;
+ int i;
+
+ iov[0].iov_base = src;
+ iov[0].iov_len = len;
+ uio.uio_iov = iov;
+ uio.uio_iovcnt = 1;
+ uio.uio_offset = 0;
+ uio.uio_resid = len;
+ uio.uio_segflg = UIO_SYSSPACE;
+ uio.uio_rw = UIO_WRITE;
+ for (i = 0; i < PHYS_PAGE_COUNT(len); i++, dst += PAGE_SIZE)
+ m[i] = PHYS_TO_VM_PAGE(dst);
+ return uiomove_fromphys(m, dst & PAGE_MASK, len, &uio);
+}
+
+int
+physcopyout(vm_paddr_t src, void *dst, size_t len)
+{
+ vm_page_t m[PHYS_PAGE_COUNT(len)];
+ struct iovec iov[1];
+ struct uio uio;
+ int i;
+
+ iov[0].iov_base = dst;
+ iov[0].iov_len = len;
+ uio.uio_iov = iov;
+ uio.uio_iovcnt = 1;
+ uio.uio_offset = 0;
+ uio.uio_resid = len;
+ uio.uio_segflg = UIO_SYSSPACE;
+ uio.uio_rw = UIO_WRITE;
+ for (i = 0; i < PHYS_PAGE_COUNT(len); i++, src += PAGE_SIZE)
+ m[i] = PHYS_TO_VM_PAGE(src);
+ return uiomove_fromphys(m, src & PAGE_MASK, len, &uio);
+}
+
+#undef PHYS_PAGE_COUNT
+
int
uiomove(void *cp, int n, struct uio *uio)
{
Modified: projects/physbio/sys/mips/mips/busdma_machdep.c
==============================================================================
--- projects/physbio/sys/mips/mips/busdma_machdep.c Sat Dec 29 02:36:08 2012 (r244809)
+++ projects/physbio/sys/mips/mips/busdma_machdep.c Sat Dec 29 03:28:55 2012 (r244810)
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include <sys/ktr.h>
#include <sys/kernel.h>
#include <sys/sysctl.h>
+#include <sys/uio.h>
#include <vm/vm.h>
#include <vm/vm_page.h>
@@ -87,6 +88,7 @@ struct bounce_page {
vm_offset_t vaddr_nocache; /* kva of bounce buffer uncached */
bus_addr_t busaddr; /* Physical address */
vm_offset_t datavaddr; /* kva of client data */
+ bus_addr_t dataaddr; /* client physical address */
bus_size_t datacount; /* client data count */
STAILQ_ENTRY(bounce_page) links;
};
@@ -166,7 +168,8 @@ static int alloc_bounce_pages(bus_dma_ta
static int reserve_bounce_pages(bus_dma_tag_t dmat, bus_dmamap_t map,
int commit);
static bus_addr_t add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map,
- vm_offset_t vaddr, bus_size_t size);
+ vm_offset_t vaddr, bus_addr_t addr,
+ bus_size_t size);
static void free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage);
/* Default tag, as most drivers provide no parent tag. */
@@ -875,7 +878,8 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dm
if (((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0) &&
map->pagesneeded != 0 && run_filter(dmat, curaddr)) {
- curaddr = add_bounce_page(dmat, map, vaddr, sgsize);
+ curaddr = add_bounce_page(dmat, map, vaddr, curaddr,
+ sgsize);
} else {
sl = &map->slist[map->sync_count - 1];
if (map->sync_count == 0 ||
@@ -1045,10 +1049,18 @@ _bus_dmamap_sync_bp(bus_dma_tag_t dmat,
STAILQ_FOREACH(bpage, &map->bpages, links) {
if (op & BUS_DMASYNC_PREWRITE) {
- bcopy((void *)bpage->datavaddr,
- (void *)(bpage->vaddr_nocache != 0 ?
- bpage->vaddr_nocache : bpage->vaddr),
- bpage->datacount);
+ if (bpage->datavaddr != 0)
+ bcopy((void *)bpage->datavaddr,
+ (void *)(bpage->vaddr_nocache != 0 ?
+ bpage->vaddr_nocache :
+ bpage->vaddr),
+ bpage->datacount);
+ else
+ physcopyout(bpage->dataaddr,
+ (void *)(bpage->vaddr_nocache != 0 ?
+ bpage->vaddr_nocache :
+ bpage->vaddr),
+ bpage->datacount);
if (bpage->vaddr_nocache == 0) {
mips_dcache_wb_range(bpage->vaddr,
bpage->datacount);
@@ -1060,9 +1072,14 @@ _bus_dmamap_sync_bp(bus_dma_tag_t dmat,
mips_dcache_inv_range(bpage->vaddr,
bpage->datacount);
}
- bcopy((void *)(bpage->vaddr_nocache != 0 ?
- bpage->vaddr_nocache : bpage->vaddr),
- (void *)bpage->datavaddr, bpage->datacount);
+ if (bpage->datavaddr != 0)
+ bcopy((void *)(bpage->vaddr_nocache != 0 ?
+ bpage->vaddr_nocache : bpage->vaddr),
+ (void *)bpage->datavaddr, bpage->datacount);
+ else
+ physcopyin((void *)(bpage->vaddr_nocache != 0 ?
+ bpage->vaddr_nocache : bpage->vaddr),
+ bpage->dataaddr, bpage->datacount);
dmat->bounce_zone->total_bounced++;
}
}
@@ -1251,7 +1268,7 @@ reserve_bounce_pages(bus_dma_tag_t dmat,
static bus_addr_t
add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, vm_offset_t vaddr,
- bus_size_t size)
+ bus_addr_t addr, bus_size_t size)
{
struct bounce_zone *bz;
struct bounce_page *bpage;
@@ -1284,6 +1301,7 @@ add_bounce_page(bus_dma_tag_t dmat, bus_
bpage->busaddr |= vaddr & PAGE_MASK;
}
bpage->datavaddr = vaddr;
+ bpage->dataaddr = addr;
bpage->datacount = size;
STAILQ_INSERT_TAIL(&(map->bpages), bpage, links);
return (bpage->busaddr);
Modified: projects/physbio/sys/powerpc/powerpc/busdma_machdep.c
==============================================================================
--- projects/physbio/sys/powerpc/powerpc/busdma_machdep.c Sat Dec 29 02:36:08 2012 (r244809)
+++ projects/physbio/sys/powerpc/powerpc/busdma_machdep.c Sat Dec 29 03:28:55 2012 (r244810)
@@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
#include <sys/proc.h>
#include <sys/mutex.h>
#include <sys/sysctl.h>
+#include <sys/uio.h>
#include <vm/vm.h>
#include <vm/vm_extern.h>
@@ -85,6 +86,7 @@ struct bounce_page {
vm_offset_t vaddr; /* kva of bounce buffer */
bus_addr_t busaddr; /* Physical address */
vm_offset_t datavaddr; /* kva of client data */
+ bus_addr_t dataaddr; /* client physical address */
bus_size_t datacount; /* client data count */
STAILQ_ENTRY(bounce_page) links;
};
@@ -141,7 +143,8 @@ static int alloc_bounce_pages(bus_dma_ta
static int reserve_bounce_pages(bus_dma_tag_t dmat, bus_dmamap_t map,
int commit);
static bus_addr_t add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map,
- vm_offset_t vaddr, bus_size_t size);
+ vm_offset_t vaddr, bus_addr_t addr,
+ bus_size_t size);
static void free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage);
static __inline int run_filter(bus_dma_tag_t dmat, bus_addr_t paddr);
@@ -735,7 +738,8 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dm
if (map->pagesneeded != 0 && run_filter(dmat, curaddr)) {
sgsize = roundup2(sgsize, dmat->alignment);
sgsize = MIN(sgsize, max_sgsize);
- curaddr = add_bounce_page(dmat, map, vaddr, sgsize);
+ curaddr = add_bounce_page(dmat, map, vaddr, curaddr,
+ sgsize);
} else {
sgsize = MIN(sgsize, max_sgsize);
}
@@ -821,9 +825,14 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus
if (op & BUS_DMASYNC_PREWRITE) {
while (bpage != NULL) {
- bcopy((void *)bpage->datavaddr,
- (void *)bpage->vaddr,
- bpage->datacount);
+ if (page->datavaddr != 0)
+ bcopy((void *)bpage->datavaddr,
+ (void *)bpage->vaddr,
+ bpage->datacount);
+ else
+ physcopyout(page->dataaddr,
+ (void *)bpage->vaddr,
+ bpage->datacount);
bpage = STAILQ_NEXT(bpage, links);
}
dmat->bounce_zone->total_bounced++;
@@ -831,9 +840,13 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus
if (op & BUS_DMASYNC_POSTREAD) {
while (bpage != NULL) {
- bcopy((void *)bpage->vaddr,
- (void *)bpage->datavaddr,
- bpage->datacount);
+ if (page->datavaddr != 0)
+ bcopy((void *)bpage->vaddr,
+ (void *)bpage->datavaddr,
+ bpage->datacount);
+ else
+ physcopyin((void *)bpage->vaddr,
+ bpage->dataaddr, bpage->datacount);
bpage = STAILQ_NEXT(bpage, links);
}
dmat->bounce_zone->total_bounced++;
@@ -1000,7 +1013,7 @@ reserve_bounce_pages(bus_dma_tag_t dmat,
static bus_addr_t
add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, vm_offset_t vaddr,
- bus_size_t size)
+ bus_addr_t addr, bus_size_t size)
{
struct bounce_zone *bz;
struct bounce_page *bpage;
@@ -1032,6 +1045,7 @@ add_bounce_page(bus_dma_tag_t dmat, bus_
bpage->busaddr |= vaddr & PAGE_MASK;
}
bpage->datavaddr = vaddr;
+ bpage->dataaddr = addr;
bpage->datacount = size;
STAILQ_INSERT_TAIL(&(map->bpages), bpage, links);
return (bpage->busaddr);
Modified: projects/physbio/sys/sys/uio.h
==============================================================================
--- projects/physbio/sys/sys/uio.h Sat Dec 29 02:36:08 2012 (r244809)
+++ projects/physbio/sys/sys/uio.h Sat Dec 29 03:28:55 2012 (r244810)
@@ -96,6 +96,8 @@ int copyinstrfrom(const void * __restric
int copyinuio(const struct iovec *iovp, u_int iovcnt, struct uio **uiop);
int copyout_map(struct thread *td, vm_offset_t *addr, size_t sz);
int copyout_unmap(struct thread *td, vm_offset_t addr, size_t sz);
+int physcopyin(void *src, vm_paddr_t dst, size_t len);
+int physcopyout(vm_paddr_t src, void *dst, size_t len);
int uiomove(void *cp, int n, struct uio *uio);
int uiomove_frombuf(void *buf, int buflen, struct uio *uio);
int uiomove_fromphys(struct vm_page *ma[], vm_offset_t offset, int n,
Modified: projects/physbio/sys/x86/x86/busdma_machdep.c
==============================================================================
--- projects/physbio/sys/x86/x86/busdma_machdep.c Sat Dec 29 02:36:08 2012 (r244809)
+++ projects/physbio/sys/x86/x86/busdma_machdep.c Sat Dec 29 03:28:55 2012 (r244810)
@@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
#include <sys/proc.h>
#include <sys/mutex.h>
#include <sys/sysctl.h>
+#include <sys/uio.h>
#include <vm/vm.h>
#include <vm/vm_extern.h>
@@ -84,6 +85,7 @@ struct bounce_page {
vm_offset_t vaddr; /* kva of bounce buffer */
bus_addr_t busaddr; /* Physical address */
vm_offset_t datavaddr; /* kva of client data */
+ bus_addr_t dataaddr; /* client physical address */
bus_size_t datacount; /* client data count */
STAILQ_ENTRY(bounce_page) links;
};
@@ -138,7 +140,8 @@ static int alloc_bounce_pages(bus_dma_ta
static int reserve_bounce_pages(bus_dma_tag_t dmat, bus_dmamap_t map,
int commit);
static bus_addr_t add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map,
- vm_offset_t vaddr, bus_size_t size);
+ vm_offset_t vaddr, bus_addr_t addr,
+ bus_size_t size);
static void free_bounce_page(bus_dma_tag_t dmat, struct bounce_page *bpage);
int run_filter(bus_dma_tag_t dmat, bus_addr_t paddr);
int _bus_dmamap_count_pages(bus_dma_tag_t dmat, bus_dmamap_t map, pmap_t pmap,
@@ -774,12 +777,13 @@ _bus_dmamap_load_buffer(bus_dma_tag_t dm
map->pagesneeded != 0 && run_filter(dmat, curaddr)) {
sgsize = roundup2(sgsize, dmat->alignment);
sgsize = MIN(sgsize, max_sgsize);
- curaddr = add_bounce_page(dmat, map, vaddr, sgsize);
+ curaddr = add_bounce_page(dmat, map, vaddr, curaddr,
+ sgsize);
} else {
sgsize = MIN(sgsize, max_sgsize);
}
sgsize = _bus_dmamap_addseg(dmat, map, curaddr, sgsize, segs,
- segp);
+ segp);
if (sgsize == 0)
break;
vaddr += sgsize;
@@ -845,9 +849,14 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus
if (op & BUS_DMASYNC_PREWRITE) {
while (bpage != NULL) {
- bcopy((void *)bpage->datavaddr,
- (void *)bpage->vaddr,
- bpage->datacount);
+ if (bpage->datavaddr != 0)
+ bcopy((void *)bpage->datavaddr,
+ (void *)bpage->vaddr,
+ bpage->datacount);
+ else
+ physcopyout(bpage->dataaddr,
+ (void *)bpage->vaddr,
+ bpage->datacount);
bpage = STAILQ_NEXT(bpage, links);
}
dmat->bounce_zone->total_bounced++;
@@ -855,9 +864,14 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus
if (op & BUS_DMASYNC_POSTREAD) {
while (bpage != NULL) {
- bcopy((void *)bpage->vaddr,
- (void *)bpage->datavaddr,
- bpage->datacount);
+ if (bpage->datavaddr != 0)
+ bcopy((void *)bpage->vaddr,
+ (void *)bpage->datavaddr,
+ bpage->datacount);
+ else
+ physcopyin((void *)bpage->vaddr,
+ bpage->dataaddr,
+ bpage->datacount);
bpage = STAILQ_NEXT(bpage, links);
}
dmat->bounce_zone->total_bounced++;
@@ -1029,7 +1043,7 @@ reserve_bounce_pages(bus_dma_tag_t dmat,
static bus_addr_t
add_bounce_page(bus_dma_tag_t dmat, bus_dmamap_t map, vm_offset_t vaddr,
- bus_size_t size)
+ bus_addr_t addr, bus_size_t size)
{
struct bounce_zone *bz;
struct bounce_page *bpage;
@@ -1063,6 +1077,7 @@ add_bounce_page(bus_dma_tag_t dmat, bus_
bpage->busaddr |= vaddr & PAGE_MASK;
}
bpage->datavaddr = vaddr;
+ bpage->dataaddr = addr;
bpage->datacount = size;
STAILQ_INSERT_TAIL(&(map->bpages), bpage, links);
return (bpage->busaddr);
More information about the svn-src-projects
mailing list