PERFORCE change 154181 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Sat Dec 6 04:07:45 PST 2008
http://perforce.freebsd.org/chv.cgi?CH=154181
Change 154181 by hselasky at 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
More information about the p4-projects
mailing list