Date: Sat, 29 Dec 2012 03:28:56 +0000 (UTC) From: Jeff Roberson <jeff@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r244810 - in projects/physbio/sys: arm/arm ia64/ia64 kern mips/mips powerpc/powerpc sys x86/x86 Message-ID: <201212290328.qBT3SuSv063255@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201212290328.qBT3SuSv063255>