diff options
author | jmg <jmg@FreeBSD.org> | 2003-07-15 22:42:37 +0000 |
---|---|---|
committer | jmg <jmg@FreeBSD.org> | 2003-07-15 22:42:37 +0000 |
commit | 233167166ccd16e803e1d70287bf3a74c7e79c25 (patch) | |
tree | 432b2ece265fb55d907ec0301448b451531417cb | |
parent | 86f3663017520ac970979eacd86cb3753a8061dc (diff) | |
download | FreeBSD-src-233167166ccd16e803e1d70287bf3a74c7e79c25.zip FreeBSD-src-233167166ccd16e803e1d70287bf3a74c7e79c25.tar.gz |
make usb bus_dma aware.
Reviewed by: joe among others
-rw-r--r-- | sys/conf/files | 2 | ||||
-rw-r--r-- | sys/dev/usb/ehci.c | 14 | ||||
-rw-r--r-- | sys/dev/usb/ehci_pci.c | 1 | ||||
-rw-r--r-- | sys/dev/usb/ohci.c | 91 | ||||
-rw-r--r-- | sys/dev/usb/uhci.c | 5 | ||||
-rw-r--r-- | sys/dev/usb/usb_mem.c | 294 | ||||
-rw-r--r-- | sys/dev/usb/usb_mem.h | 45 | ||||
-rw-r--r-- | sys/dev/usb/usb_port.h | 8 | ||||
-rw-r--r-- | sys/dev/usb/usbdivar.h | 2 | ||||
-rw-r--r-- | sys/modules/usb/Makefile | 2 |
10 files changed, 362 insertions, 102 deletions
diff --git a/sys/conf/files b/sys/conf/files index 2565006..c14ef4c 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -813,7 +813,7 @@ dev/usb/uvisor.c optional uvisor ucom dev/usb/uvscom.c optional uvscom ucom dev/usb/usb.c optional usb dev/usb/usb_ethersubr.c optional usb -#dev/usb/usb_mem.c optional usb +dev/usb/usb_mem.c optional usb dev/usb/usb_quirks.c optional usb dev/usb/usb_subr.c optional usb dev/usb/usbdi.c optional usb diff --git a/sys/dev/usb/ehci.c b/sys/dev/usb/ehci.c index ec82b9b..ce069c4 100644 --- a/sys/dev/usb/ehci.c +++ b/sys/dev/usb/ehci.c @@ -55,8 +55,8 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/malloc.h> -#if defined(__NetBSD__) || defined(__OpenBSD__) #include <sys/kernel.h> +#if defined(__NetBSD__) || defined(__OpenBSD__) #include <sys/device.h> #include <sys/select.h> #elif defined(__FreeBSD__) @@ -65,6 +65,7 @@ #include <sys/bus.h> #include <machine/bus_pio.h> #include <machine/bus_memio.h> +#include <sys/lockmgr.h> #if defined(DIAGNOSTIC) && defined(__i386__) && defined(__FreeBSD__) #include <machine/cpu.h> #endif @@ -985,12 +986,9 @@ ehci_shutdown(void *v) usbd_status ehci_allocm(struct usbd_bus *bus, usb_dma_t *dma, u_int32_t size) { -#if defined(__NetBSD__) || defined(__OpenBSD__) - struct ehci_softc *sc = (struct ehci_softc *)bus; -#endif usbd_status err; - err = usb_allocmem(&sc->sc_bus, size, 0, dma); + err = usb_allocmem(bus, size, 0, dma); #ifdef USB_DEBUG if (err) printf("ehci_allocm: usb_allocmem()=%d\n", err); @@ -1001,11 +999,7 @@ ehci_allocm(struct usbd_bus *bus, usb_dma_t *dma, u_int32_t size) void ehci_freem(struct usbd_bus *bus, usb_dma_t *dma) { -#if defined(__NetBSD__) || defined(__OpenBSD__) - struct ehci_softc *sc = (struct ehci_softc *)bus; -#endif - - usb_freemem(&sc->sc_bus, dma); + usb_freemem(bus, dma); } usbd_xfer_handle diff --git a/sys/dev/usb/ehci_pci.c b/sys/dev/usb/ehci_pci.c index 1d6c745..efbcd4f 100644 --- a/sys/dev/usb/ehci_pci.c +++ b/sys/dev/usb/ehci_pci.c @@ -61,6 +61,7 @@ #include <sys/module.h> #include <sys/bus.h> #include <sys/queue.h> +#include <sys/lockmgr.h> #include <machine/bus.h> #include <sys/rman.h> #include <machine/resource.h> diff --git a/sys/dev/usb/ohci.c b/sys/dev/usb/ohci.c index f48d918..7af5dc0 100644 --- a/sys/dev/usb/ohci.c +++ b/sys/dev/usb/ohci.c @@ -64,8 +64,8 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/malloc.h> -#if defined(__NetBSD__) || defined(__OpenBSD__) #include <sys/kernel.h> +#if defined(__NetBSD__) || defined(__OpenBSD__) #include <sys/device.h> #include <sys/select.h> #elif defined(__FreeBSD__) @@ -501,8 +501,8 @@ ohci_alloc_std_chain(struct ohci_pipe *opipe, ohci_softc_t *sc, ohci_soft_td_t *sp, ohci_soft_td_t **ep) { ohci_soft_td_t *next, *cur; - ohci_physaddr_t dataphys, dataphysend; - u_int32_t intr, tdflags; + ohci_physaddr_t dataphys; + u_int32_t tdflags; int offset = 0; int len, curlen; usb_dma_t *dma = &xfer->dmabuf; @@ -513,12 +513,10 @@ ohci_alloc_std_chain(struct ohci_pipe *opipe, ohci_softc_t *sc, len = alen; cur = sp; - dataphys = DMAADDR(dma, 0); - dataphysend = OHCI_PAGE(DMAADDR(dma, len - 1)); - tdflags = ( + tdflags = htole32( (rd ? OHCI_TD_IN : OHCI_TD_OUT) | (flags & USBD_SHORT_XFER_OK ? OHCI_TD_R : 0) | - OHCI_TD_NOCC | OHCI_TD_TOGGLE_CARRY); + OHCI_TD_NOCC | OHCI_TD_TOGGLE_CARRY | OHCI_TD_NOINTR); for (;;) { next = ohci_alloc_std(sc); @@ -527,20 +525,27 @@ ohci_alloc_std_chain(struct ohci_pipe *opipe, ohci_softc_t *sc, dataphys = DMAADDR(dma, offset); - /* The OHCI hardware can handle at most one page crossing. */ -#if defined(__NetBSD__) || defined(__OpenBSD__) - if (OHCI_PAGE(dataphys) == dataphysend || - OHCI_PAGE(dataphys) + OHCI_PAGE_SIZE == dataphysend) -#elif defined(__FreeBSD__) - /* XXX This is pretty broken: Because we do not allocate - * a contiguous buffer (contiguous in physical pages) we - * can only transfer one page in one go. - * So check whether the start and end of the buffer are on - * the same page. + /* + * The OHCI hardware can handle at most one 4k crossing. + * XXX - currently we only allocate contigous buffers, but + * the OHCI spec says: If during the data transfer the buffer + * address contained in the HC's working copy of + * CurrentBufferPointer crosses a 4K boundary, the upper 20 + * bits of Buffer End are copied to the working value of + * CurrentBufferPointer causing the next buffer address to + * be the 0th byte in the same 4K page that contains the + * last byte of the buffer (the 4K boundary crossing may + * occur within a data packet transfer.) + * + * If/when dma has multiple segments, this will need to + * properly handle fragmenting TD's. + * + * We can describe the above using maxsegsz = 4k and nsegs = 2 + * in the future. */ - if (OHCI_PAGE(dataphys) == dataphysend) -#endif - { + if (OHCI_PAGE(dataphys) == OHCI_PAGE(DMAADDR(dma, offset + + len - 1)) || len - (OHCI_PAGE_SIZE - + OHCI_PAGE_OFFSET(dataphys)) <= OHCI_PAGE_SIZE) { /* we can handle it in this TD */ curlen = len; } else { @@ -551,38 +556,36 @@ ohci_alloc_std_chain(struct ohci_pipe *opipe, ohci_softc_t *sc, * the case of an mbuf cluster). You'll get an early * short packet. */ -#if defined(__NetBSD__) || defined(__OpenBSD__) /* must use multiple TDs, fill as much as possible. */ curlen = 2 * OHCI_PAGE_SIZE - - OHCI_PAGE_MASK(dataphys); - if (curlen > len) /* may have fit in one page */ - curlen = len; -#elif defined(__FreeBSD__) - /* See comment above (XXX) */ - curlen = OHCI_PAGE_SIZE - - OHCI_PAGE_MASK(dataphys); + OHCI_PAGE_OFFSET(dataphys); + /* the length must be a multiple of the max size */ + curlen -= curlen % + UGETW(opipe->pipe.endpoint->edesc->wMaxPacketSize); +#ifdef DIAGNOSTIC + if (curlen == 0) + panic("ohci_alloc_std: curlen == 0"); #endif } DPRINTFN(4,("ohci_alloc_std_chain: dataphys=0x%08x " - "dataphysend=0x%08x len=%d curlen=%d\n", - dataphys, dataphysend, - len, curlen)); + "len=%d curlen=%d\n", + dataphys, len, curlen)); len -= curlen; - intr = len == 0 ? OHCI_TD_SET_DI(1) : OHCI_TD_NOINTR; - cur->td.td_flags = htole32(tdflags | intr); + cur->td.td_flags = tdflags; cur->td.td_cbp = htole32(dataphys); cur->nexttd = next; cur->td.td_nexttd = htole32(next->physaddr); - cur->td.td_be = htole32(dataphys + curlen - 1); + cur->td.td_be = htole32(DMAADDR(dma, curlen - 1)); cur->len = curlen; cur->flags = OHCI_ADD_LEN; + cur->xfer = xfer; DPRINTFN(10,("ohci_alloc_std_chain: cbp=0x%08x be=0x%08x\n", dataphys, dataphys + curlen - 1)); if (len == 0) break; if (len < 0) - panic("Length went negative: %d curlen %d dma %p offset %08x", len, curlen, *dma, (int)offset); + panic("Length went negative: %d curlen %d dma %p offset %08x", len, curlen, dma, (int)0); DPRINTFN(10,("ohci_alloc_std_chain: extend chain\n")); offset += curlen; @@ -592,14 +595,13 @@ ohci_alloc_std_chain(struct ohci_pipe *opipe, ohci_softc_t *sc, alen % UGETW(opipe->pipe.endpoint->edesc->wMaxPacketSize) == 0) { /* Force a 0 length transfer at the end. */ - cur->td.td_flags = htole32(tdflags | OHCI_TD_NOINTR); cur = next; next = ohci_alloc_std(sc); if (next == NULL) goto nomem; - cur->td.td_flags = htole32(tdflags | OHCI_TD_SET_DI(1)); + cur->td.td_flags = tdflags; cur->td.td_cbp = 0; /* indicate 0 length packet */ cur->nexttd = next; cur->td.td_nexttd = htole32(next->physaddr); @@ -609,8 +611,7 @@ ohci_alloc_std_chain(struct ohci_pipe *opipe, ohci_softc_t *sc, cur->xfer = xfer; DPRINTFN(2,("ohci_alloc_std_chain: add 0 xfer\n")); } - cur->flags = OHCI_CALL_DONE | OHCI_ADD_LEN; - *ep = next; + *ep = cur; return (USBD_NORMAL_COMPLETION); @@ -944,21 +945,13 @@ ohci_init(ohci_softc_t *sc) usbd_status ohci_allocm(struct usbd_bus *bus, usb_dma_t *dma, u_int32_t size) { -#if defined(__NetBSD__) || defined(__OpenBSD__) - struct ohci_softc *sc = (struct ohci_softc *)bus; -#endif - - return (usb_allocmem(&sc->sc_bus, size, 0, dma)); + return (usb_allocmem(bus, size, 0, dma)); } void ohci_freem(struct usbd_bus *bus, usb_dma_t *dma) { -#if defined(__NetBSD__) || defined(__OpenBSD__) - struct ohci_softc *sc = (struct ohci_softc *)bus; -#endif - - usb_freemem(&sc->sc_bus, dma); + usb_freemem(bus, dma); } usbd_xfer_handle diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c index cacd810..af4fd4a 100644 --- a/sys/dev/usb/uhci.c +++ b/sys/dev/usb/uhci.c @@ -610,14 +610,13 @@ uhci_detach(struct uhci_softc *sc, int flags) usbd_status uhci_allocm(struct usbd_bus *bus, usb_dma_t *dma, u_int32_t size) { - return (usb_allocmem(&((struct uhci_softc *)bus)->sc_bus, size, 0, - dma)); + return (usb_allocmem(bus, size, 0, dma)); } void uhci_freem(struct usbd_bus *bus, usb_dma_t *dma) { - usb_freemem(&((struct uhci_softc *)bus)->sc_bus, dma); + usb_freemem(bus, dma); } usbd_xfer_handle diff --git a/sys/dev/usb/usb_mem.c b/sys/dev/usb/usb_mem.c new file mode 100644 index 0000000..f96574f --- /dev/null +++ b/sys/dev/usb/usb_mem.c @@ -0,0 +1,294 @@ +/* $NetBSD: usb_mem.c,v 1.26 2003/02/01 06:23:40 thorpej Exp $ */ +/* $FreeBSD$ */ + +/* + * Copyright (c) 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Lennart Augustsson (lennart@augustsson.net) at + * Carlstedt Research & Technology. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * USB DMA memory allocation. + * We need to allocate a lot of small (many 8 byte, some larger) + * memory blocks that can be used for DMA. Using the bus_dma + * routines directly would incur large overheads in space and time. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/malloc.h> +#include <sys/kernel.h> +#if defined(__NetBSD__) || defined(__OpenBSD__) +#include <sys/device.h> /* for usbdivar.h */ +#include <machine/bus.h> +#elif defined(__FreeBSD__) +#include <sys/endian.h> +#include <sys/module.h> +#include <sys/bus.h> +#endif +#include <sys/queue.h> + +#include <machine/bus.h> +#include <machine/endian.h> + +#ifdef DIAGNOSTIC +#include <sys/proc.h> +#endif + +#include <dev/usb/usb.h> +#include <dev/usb/usbdi.h> +#include <dev/usb/usbdivar.h> /* just for usb_dma_t */ +#include <dev/usb/usb_mem.h> + +#ifdef USB_DEBUG +#define DPRINTF(x) if (usbdebug) logprintf x +#define DPRINTFN(n,x) if (usbdebug>(n)) logprintf x +extern int usbdebug; +#else +#define DPRINTF(x) +#define DPRINTFN(n,x) +#endif + +#define USB_MEM_SMALL 64 +#define USB_MEM_CHUNKS (PAGE_SIZE / 64) +#define USB_MEM_BLOCK (USB_MEM_SMALL * USB_MEM_CHUNKS) + +/* This struct is overlayed on free fragments. */ +struct usb_frag_dma { + usb_dma_block_t *block; + u_int offs; + LIST_ENTRY(usb_frag_dma) next; +}; + +Static bus_dmamap_callback_t usbmem_callback; +Static usbd_status usb_block_allocmem(bus_dma_tag_t, size_t, size_t, + usb_dma_block_t **); +Static void usb_block_freemem(usb_dma_block_t *); + +Static LIST_HEAD(, usb_dma_block) usb_blk_freelist = + LIST_HEAD_INITIALIZER(usb_blk_freelist); +Static int usb_blk_nfree = 0; +/* XXX should have different free list for different tags (for speed) */ +Static LIST_HEAD(, usb_frag_dma) usb_frag_freelist = + LIST_HEAD_INITIALIZER(usb_frag_freelist); + +Static void +usbmem_callback(void *arg, bus_dma_segment_t *segs, int nseg, int error) +{ + int i; + usb_dma_block_t *p = arg; + + if (error == EFBIG) { + printf("usb: mapping to large\n"); + return; + } + + p->nsegs = nseg; + for (i = 0; i < nseg && i < sizeof p->segs / sizeof *p->segs; i++) + p->segs[i] = segs[i]; +} + +Static usbd_status +usb_block_allocmem(bus_dma_tag_t tag, size_t size, size_t align, + usb_dma_block_t **dmap) +{ + usb_dma_block_t *p; + int s; + + DPRINTFN(5, ("usb_block_allocmem: size=%lu align=%lu\n", + (u_long)size, (u_long)align)); + +#ifdef DIAGNOSTIC + if (!curproc) { + printf("usb_block_allocmem: in interrupt context, size=%lu\n", + (unsigned long) size); + } +#endif + + s = splusb(); + /* First check the free list. */ + for (p = LIST_FIRST(&usb_blk_freelist); p; p = LIST_NEXT(p, next)) { + if (p->tag == tag && p->size >= size && p->align >= align) { + LIST_REMOVE(p, next); + usb_blk_nfree--; + splx(s); + *dmap = p; + DPRINTFN(6,("usb_block_allocmem: free list size=%lu\n", + (u_long)p->size)); + return (USBD_NORMAL_COMPLETION); + } + } + splx(s); + +#ifdef DIAGNOSTIC + if (!curproc) { + printf("usb_block_allocmem: in interrupt context, failed\n"); + return (USBD_NOMEM); + } +#endif + + DPRINTFN(6, ("usb_block_allocmem: no free\n")); + p = malloc(sizeof *p, M_USB, M_NOWAIT); + if (p == NULL) + return (USBD_NOMEM); + + if (bus_dma_tag_create(tag, align, 0, + BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, + size, sizeof(p->segs) / sizeof(p->segs[0]), size, + BUS_DMA_ALLOCNOW, NULL, NULL, &p->tag) == ENOMEM) { + goto free; + } + + p->size = size; + p->align = align; + if (bus_dmamem_alloc(p->tag, &p->kaddr, + BUS_DMA_NOWAIT|BUS_DMA_COHERENT, &p->map)) + goto tagfree; + + if (bus_dmamap_load(p->tag, p->map, p->kaddr, p->size, + usbmem_callback, p, 0)) + goto memfree; + + *dmap = p; + return (USBD_NORMAL_COMPLETION); + + /* + * XXX - do we need to _unload? is the order of _free and _destroy + * correct? + */ +memfree: + bus_dmamem_free(p->tag, p->kaddr, p->map); +tagfree: + bus_dma_tag_destroy(p->tag); +free: + free(p, M_USB); + return (USBD_NOMEM); +} + +/* + * Do not free the memory unconditionally since we might be called + * from an interrupt context and that is BAD. + * XXX when should we really free? + */ +Static void +usb_block_freemem(usb_dma_block_t *p) +{ + int s; + + DPRINTFN(6, ("usb_block_freemem: size=%lu\n", (u_long)p->size)); + s = splusb(); + LIST_INSERT_HEAD(&usb_blk_freelist, p, next); + usb_blk_nfree++; + splx(s); +} + +usbd_status +usb_allocmem(usbd_bus_handle bus, size_t size, size_t align, usb_dma_t *p) +{ + bus_dma_tag_t tag = bus->dmatag; + usbd_status err; + struct usb_frag_dma *f; + usb_dma_block_t *b; + int i; + int s; + + /* compat w/ Net/OpenBSD */ + if (align == 0) + align = 1; + + /* If the request is large then just use a full block. */ + if (size > USB_MEM_SMALL || align > USB_MEM_SMALL) { + DPRINTFN(1, ("usb_allocmem: large alloc %d\n", (int)size)); + size = (size + USB_MEM_BLOCK - 1) & ~(USB_MEM_BLOCK - 1); + err = usb_block_allocmem(tag, size, align, &p->block); + if (!err) { + p->block->fullblock = 1; + p->offs = 0; + p->len = size; + } + return (err); + } + + s = splusb(); + /* Check for free fragments. */ + for (f = LIST_FIRST(&usb_frag_freelist); f; f = LIST_NEXT(f, next)) + if (f->block->tag == tag) + break; + if (f == NULL) { + DPRINTFN(1, ("usb_allocmem: adding fragments\n")); + err = usb_block_allocmem(tag, USB_MEM_BLOCK, USB_MEM_SMALL,&b); + if (err) { + splx(s); + return (err); + } + b->fullblock = 0; + for (i = 0; i < USB_MEM_BLOCK; i += USB_MEM_SMALL) { + f = (struct usb_frag_dma *)((char *)b->kaddr + i); + f->block = b; + f->offs = i; + LIST_INSERT_HEAD(&usb_frag_freelist, f, next); + } + f = LIST_FIRST(&usb_frag_freelist); + } + p->block = f->block; + p->offs = f->offs; + p->len = USB_MEM_SMALL; + LIST_REMOVE(f, next); + splx(s); + DPRINTFN(5, ("usb_allocmem: use frag=%p size=%d\n", f, (int)size)); + return (USBD_NORMAL_COMPLETION); +} + +void +usb_freemem(usbd_bus_handle bus, usb_dma_t *p) +{ + struct usb_frag_dma *f; + int s; + + if (p->block->fullblock) { + DPRINTFN(1, ("usb_freemem: large free\n")); + usb_block_freemem(p->block); + return; + } + f = KERNADDR(p, 0); + f->block = p->block; + f->offs = p->offs; + s = splusb(); + LIST_INSERT_HEAD(&usb_frag_freelist, f, next); + splx(s); + DPRINTFN(5, ("usb_freemem: frag=%p\n", f)); +} diff --git a/sys/dev/usb/usb_mem.h b/sys/dev/usb/usb_mem.h index 3889b5d..fa95716 100644 --- a/sys/dev/usb/usb_mem.h +++ b/sys/dev/usb/usb_mem.h @@ -38,11 +38,14 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#if defined(__NetBSD__) || defined(__OpenBSD__) typedef struct usb_dma_block { bus_dma_tag_t tag; bus_dmamap_t map; +#ifdef __FreeBSD__ + void *kaddr; +#else caddr_t kaddr; +#endif bus_dma_segment_t segs[1]; int nsegs; size_t size; @@ -51,41 +54,13 @@ typedef struct usb_dma_block { LIST_ENTRY(usb_dma_block) next; } usb_dma_block_t; -#define DMAADDR(dma, o) ((dma)->block->map->dm_segs[0].ds_addr + (dma)->offs + (o)) +#ifdef __FreeBSD__ +#define DMAADDR(dma, o) ((uint32_t)(uintptr_t)(((char *)(dma)->block->segs[0].ds_addr) + (dma)->offs + (o))) +#else +#define DMAADDR(dma, o) (((char *)(dma)->block->map->dm_segs[0].ds_addr) + (dma)->offs + (o)) +#endif #define KERNADDR(dma, o) \ - ((void *)((char *)((dma)->block->kaddr + (dma)->offs) + (o))) + ((void *)((char *)((dma)->block->kaddr) + (dma)->offs + (o))) usbd_status usb_allocmem(usbd_bus_handle,size_t,size_t, usb_dma_t *); void usb_freemem(usbd_bus_handle, usb_dma_t *); - -#elif defined(__FreeBSD__) - -/* - * FreeBSD does not have special functions for dma memory, so let's keep it - * simple for now. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/queue.h> -#include <sys/proc.h> -#include <sys/bio.h> -#include <sys/buf.h> -#include <sys/malloc.h> -#include <sys/kernel.h> -#include <vm/vm.h> -#include <vm/pmap.h> - -#include <machine/pmap.h> /* for vtophys */ - -#define usb_allocmem(t,s,a,p) (*(p) = malloc(s, M_USB, M_NOWAIT), (*(p) == NULL? USBD_NOMEM: USBD_NORMAL_COMPLETION)) -#define usb_freemem(t,p) (free(*(p), M_USB)) - -#ifdef __alpha__ -#define DMAADDR(dma, o) (alpha_XXX_dmamap((vm_offset_t) *(dma) + (o))) -#else -#define DMAADDR(dma, o) (vtophys(*(dma) + (o))) -#endif -#define KERNADDR(dma, o) ((void *) ((char *)*(dma) + (o))) -#endif /* __FreeBSD__ */ - diff --git a/sys/dev/usb/usb_port.h b/sys/dev/usb/usb_port.h index 82bee01..c48c582 100644 --- a/sys/dev/usb/usb_port.h +++ b/sys/dev/usb/usb_port.h @@ -360,7 +360,13 @@ MALLOC_DECLARE(M_USBHC); #define USBDEVUNIT(bdev) device_get_unit(bdev) #define USBGETSOFTC(bdev) (device_get_softc(bdev)) -#define DECLARE_USB_DMA_T typedef char * usb_dma_t +#define DECLARE_USB_DMA_T \ + struct usb_dma_block; \ + typedef struct { \ + struct usb_dma_block *block; \ + u_int offs; \ + u_int len; \ + } usb_dma_t typedef struct thread *usb_proc_ptr; diff --git a/sys/dev/usb/usbdivar.h b/sys/dev/usb/usbdivar.h index 0054780..ae2c092 100644 --- a/sys/dev/usb/usbdivar.h +++ b/sys/dev/usb/usbdivar.h @@ -124,9 +124,7 @@ struct usbd_bus { #endif #endif -#if defined(__NetBSD__) || defined(__OpenBSD__) bus_dma_tag_t dmatag; /* DMA tag */ -#endif }; struct usbd_device { diff --git a/sys/modules/usb/Makefile b/sys/modules/usb/Makefile index 6070199..9865f4a 100644 --- a/sys/modules/usb/Makefile +++ b/sys/modules/usb/Makefile @@ -13,7 +13,7 @@ SRCS= bus_if.h device_if.h usb_if.h usb_if.c \ hid.c hid.h usbhid.h \ uhub.c \ usb.c usb.h \ - usb_mem.h \ + usb_mem.c usb_mem.h \ usb_port.h \ usb_quirks.c usb_quirks.h \ usb_subr.c \ |