From owner-p4-projects@FreeBSD.ORG Sat Dec 6 12:07:45 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 709DC1065670; Sat, 6 Dec 2008 12:07:45 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 1C9B71065673 for ; Sat, 6 Dec 2008 12:07:45 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 0AF918FC0A for ; Sat, 6 Dec 2008 12:07:45 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id mB6C7isq064200 for ; Sat, 6 Dec 2008 12:07:44 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id mB6C7iS1064198 for perforce@freebsd.org; Sat, 6 Dec 2008 12:07:44 GMT (envelope-from hselasky@FreeBSD.org) Date: Sat, 6 Dec 2008 12:07:44 GMT Message-Id: <200812061207.mB6C7iS1064198@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky To: Perforce Change Reviews Cc: Subject: PERFORCE change 154181 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 06 Dec 2008 12:07:45 -0000 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 #include +#define USB_DEBUG_VAR usb2_debug + #include #include #include #include #include #include +#include #include #include @@ -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