Date: Sat, 6 Dec 2008 12:07:44 GMT From: Hans Petter Selasky <hselasky@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 154181 for review Message-ID: <200812061207.mB6C7iS1064198@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=154181 Change 154181 by hselasky@hselasky_laptop001 on 2008/12/06 12:07:36 Fix problem with busdma, bounce pages and USB. Needs review. Affected files ... .. //depot/projects/usb/src/sys/amd64/amd64/busdma_machdep.c#9 edit .. //depot/projects/usb/src/sys/arm/arm/busdma_machdep.c#10 edit .. //depot/projects/usb/src/sys/dev/usb2/core/usb2_busdma.c#14 edit .. //depot/projects/usb/src/sys/i386/i386/busdma_machdep.c#12 edit .. //depot/projects/usb/src/sys/ia64/ia64/busdma_machdep.c#8 edit .. //depot/projects/usb/src/sys/sys/bus_dma.h#6 edit Differences ... ==== //depot/projects/usb/src/sys/amd64/amd64/busdma_machdep.c#9 (text+ko) ==== @@ -1128,6 +1128,17 @@ bz->active_bpages++; mtx_unlock(&bounce_lock); + /* reset page offset */ + bpage->vaddr &= ~PAGE_MASK; + bpage->busaddr &= ~PAGE_MASK; + + if (BUS_DMA_NO_REALIGN(dmat->alignment, dmat->boundary, + dmat->maxsegsz)) { + /* preserve page offset */ + bpage->vaddr |= vaddr & PAGE_MASK; + bpage->busaddr |= vaddr & PAGE_MASK; + } + bpage->datavaddr = vaddr; bpage->datacount = size; STAILQ_INSERT_TAIL(&(map->bpages), bpage, links); ==== //depot/projects/usb/src/sys/arm/arm/busdma_machdep.c#10 (text+ko) ==== @@ -1416,6 +1416,17 @@ bz->active_bpages++; mtx_unlock(&bounce_lock); + /* reset page offset */ + bpage->vaddr &= ~PAGE_MASK; + bpage->busaddr &= ~PAGE_MASK; + + if (BUS_DMA_NO_REALIGN(dmat->alignment, dmat->boundary, + dmat->maxsegsz)) { + /* preserve page offset */ + bpage->vaddr |= vaddr & PAGE_MASK; + bpage->busaddr |= vaddr & PAGE_MASK; + } + bpage->datavaddr = vaddr; bpage->datacount = size; STAILQ_INSERT_TAIL(&(map->bpages), bpage, links); ==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_busdma.c#14 (text+ko) ==== @@ -29,12 +29,15 @@ #include <dev/usb2/include/usb2_standard.h> #include <dev/usb2/include/usb2_defs.h> +#define USB_DEBUG_VAR usb2_debug + #include <dev/usb2/core/usb2_core.h> #include <dev/usb2/core/usb2_busdma.h> #include <dev/usb2/core/usb2_process.h> #include <dev/usb2/core/usb2_transfer.h> #include <dev/usb2/core/usb2_device.h> #include <dev/usb2/core/usb2_util.h> +#include <dev/usb2/core/usb2_debug.h> #include <dev/usb2/controller/usb2_controller.h> #include <dev/usb2/controller/usb2_bus.h> @@ -428,7 +431,16 @@ pc->page_offset_buf = rem; pc->page_offset_end += rem; nseg--; - +#if (USB_DEBUG != 0) + if (rem != (USB_P2U(pc->buffer) & (USB_PAGE_SIZE - 1))) { + /* + * This check verifies that the physical address is correct: + */ + DPRINTFN(0, "Page offset was not preserved!\n"); + error = 1; + goto done; + } +#endif while (nseg > 0) { nseg--; segs++; @@ -805,7 +817,16 @@ ext_seg = 0; } nseg--; - +#if (USB_DEBUG != 0) + if (rem != (USB_P2U(pc->buffer) & (USB_PAGE_SIZE - 1))) { + /* + * This check verifies that the physical address is correct: + */ + DPRINTFN(0, "Page offset was not preserved!\n"); + error = 1; + goto done; + } +#endif while (nseg > 0) { nseg--; segs++; ==== //depot/projects/usb/src/sys/i386/i386/busdma_machdep.c#12 (text+ko) ==== @@ -1146,6 +1146,17 @@ bz->active_bpages++; mtx_unlock(&bounce_lock); + /* reset page offset */ + bpage->vaddr &= ~PAGE_MASK; + bpage->busaddr &= ~PAGE_MASK; + + if (BUS_DMA_NO_REALIGN(dmat->alignment, dmat->boundary, + dmat->maxsegsz)) { + /* preserve page offset */ + bpage->vaddr |= vaddr & PAGE_MASK; + bpage->busaddr |= vaddr & PAGE_MASK; + } + bpage->datavaddr = vaddr; bpage->datacount = size; STAILQ_INSERT_TAIL(&(map->bpages), bpage, links); ==== //depot/projects/usb/src/sys/ia64/ia64/busdma_machdep.c#8 (text+ko) ==== @@ -936,6 +936,17 @@ active_bpages++; mtx_unlock(&bounce_lock); + /* reset page offset */ + bpage->vaddr &= ~PAGE_MASK; + bpage->busaddr &= ~PAGE_MASK; + + if (BUS_DMA_NO_REALIGN(dmat->alignment, dmat->boundary, + dmat->maxsegsz)) { + /* preserve page offset */ + bpage->vaddr |= vaddr & PAGE_MASK; + bpage->busaddr |= vaddr & PAGE_MASK; + } + bpage->datavaddr = vaddr; bpage->datacount = size; STAILQ_INSERT_TAIL(&(map->bpages), bpage, links); ==== //depot/projects/usb/src/sys/sys/bus_dma.h#6 (text+ko) ==== @@ -133,6 +133,23 @@ #define BUS_DMASYNC_POSTWRITE 8 /* + * Background: Some kinds of DMA hardware only store the full + * physical address of the first memory page when multiple memory + * pages are loaded into DMA. For consecutive memory pages, only the + * non-offset part of the physical address is updated. The hardware + * computes the amount of data that should be stored in the first + * memory page from the minimum of the total transfer length and + * PAGE_SIZE, minus the initial page offset. When the initial page + * offset is not preserved, the hardware ends up transferring an + * invalid number of bytes to or from the initial memory page. + * + * The following macro returns true when the initial page offset must + * be preserved: + */ +#define BUS_DMA_NO_REALIGN(align,boundary,maxsegsz) \ + (((align) == 1) && ((boundary) == PAGE_SIZE) && ((maxsegsz) == PAGE_SIZE)) + +/* * bus_dma_segment_t * * Describes a single contiguous DMA transaction. Values
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200812061207.mB6C7iS1064198>