Index: ohci.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/dev/usb/ohci.c,v retrieving revision 1.170 diff -u -r1.170 ohci.c --- ohci.c 20 Jun 2007 05:10:52 -0000 1.170 +++ ohci.c 23 Jun 2007 20:00:35 -0000 @@ -378,6 +378,7 @@ offs = i * OHCI_SED_SIZE; sed = KERNADDR(&dma, offs); sed->physaddr = DMAADDR(&dma, offs); + sed->dmablock = DMABLOCKPTR(&dma); sed->next = sc->sc_freeeds; sc->sc_freeeds = sed; } @@ -416,6 +417,7 @@ offs = i * OHCI_STD_SIZE; std = KERNADDR(&dma, offs); std->physaddr = DMAADDR(&dma, offs); + std->dmablock = DMABLOCKPTR(&dma); std->nexttd = sc->sc_freetds; sc->sc_freetds = std; } @@ -633,6 +635,7 @@ offs = i * OHCI_SITD_SIZE; sitd = KERNADDR(&dma, offs); sitd->physaddr = DMAADDR(&dma, offs); + sitd->dmablock = DMABLOCKPTR(&dma); sitd->nextitd = sc->sc_freeitds; sc->sc_freeitds = sitd; } @@ -1668,7 +1671,7 @@ usb_device_request_t *req = &xfer->request; usbd_device_handle dev = opipe->pipe.device; ohci_softc_t *sc = (ohci_softc_t *)dev->bus; - ohci_soft_td_t *setup, *stat, *next, *tail; + ohci_soft_td_t *setup, *stat, *next, *p, *tail; ohci_soft_ed_t *sed; int isread; int len; @@ -1749,8 +1752,16 @@ /* Insert ED in schedule */ s = splusb(); + for (p = setup; p != NULL; p = p->nexttd) { + bus_dmamap_sync(p->dmablock->tag, p->dmablock->map, + BUS_DMASYNC_PREWRITE); + } + bus_dmamap_sync(opipe->u.ctl.reqdma.block->tag, + opipe->u.ctl.reqdma.block->map, BUS_DMASYNC_PREWRITE); sed->ed.ed_tailp = htole32(tail->physaddr); opipe->tail.td = tail; + bus_dmamap_sync(sed->dmablock->tag, sed->dmablock->map, + BUS_DMASYNC_PREWRITE); OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF); if (xfer->timeout && !sc->sc_bus.use_polling) { callout_reset(&xfer->timeout_handle, MS_TO_TICKS(xfer->timeout), @@ -1793,8 +1804,12 @@ SPLUSBCHECK; sed->next = head->next; sed->ed.ed_nexted = head->ed.ed_nexted; + bus_dmamap_sync(sed->dmablock->tag, sed->dmablock->map, + BUS_DMASYNC_PREWRITE); head->next = sed; head->ed.ed_nexted = htole32(sed->physaddr); + bus_dmamap_sync(head->dmablock->tag, head->dmablock->map, + BUS_DMASYNC_PREWRITE); } /* @@ -1814,6 +1829,8 @@ panic("ohci_rem_ed: ED not found"); p->next = sed->next; p->ed.ed_nexted = sed->ed.ed_nexted; + bus_dmamap_sync(p->dmablock->tag, p->dmablock->map, + BUS_DMASYNC_PREWRITE); } /* @@ -2250,6 +2267,8 @@ splx(s); DPRINTFN(1,("ohci_abort_xfer: stop ed=%p\n", sed)); sed->ed.ed_flags |= htole32(OHCI_ED_SKIP); /* force hardware skip */ + bus_dmamap_sync(sed->dmablock->tag, sed->dmablock->map, + BUS_DMASYNC_PREWRITE); /* * Step 2: Wait until we know hardware has finished any possible @@ -2311,6 +2330,8 @@ * Step 4: Turn on hardware again. */ sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP); /* remove hardware skip */ + bus_dmamap_sync(sed->dmablock->tag, sed->dmablock->map, + BUS_DMASYNC_PREWRITE); /* * Step 5: Execute callback. @@ -2960,11 +2981,17 @@ /* Insert ED in schedule */ s = splusb(); for (tdp = data; tdp != tail; tdp = tdp->nexttd) { + bus_dmamap_sync(tdp->dmablock->tag, tdp->dmablock->map, + BUS_DMASYNC_PREWRITE); tdp->xfer = xfer; } + bus_dmamap_sync(tail->dmablock->tag, tail->dmablock->map, + BUS_DMASYNC_PREWRITE); sed->ed.ed_tailp = htole32(tail->physaddr); opipe->tail.td = tail; sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP); + bus_dmamap_sync(sed->dmablock->tag, sed->dmablock->map, + BUS_DMASYNC_PREWRITE); OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_BLF); if (xfer->timeout && !sc->sc_bus.use_polling) { callout_reset(&xfer->timeout_handle, MS_TO_TICKS(xfer->timeout), @@ -3052,6 +3079,8 @@ return (err); sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP); + bus_dmamap_sync(sed->dmablock->tag, sed->dmablock->map, + BUS_DMASYNC_PREWRITE); return (USBD_IN_PROGRESS); } @@ -3125,7 +3154,13 @@ /* Insert ED in schedule */ s = splusb(); + bus_dmamap_sync(data->dmablock->tag, data->dmablock->map, + BUS_DMASYNC_PREWRITE); + bus_dmamap_sync(tail->dmablock->tag, tail->dmablock->map, + BUS_DMASYNC_PREWRITE); sed->ed.ed_tailp = htole32(tail->physaddr); + bus_dmamap_sync(sed->dmablock->tag, sed->dmablock->map, + BUS_DMASYNC_PREWRITE); opipe->tail.td = tail; splx(s); @@ -3285,7 +3320,7 @@ ohci_soft_ed_t *sed = opipe->sed; struct iso *iso = &opipe->u.iso; struct usb_dma_mapping *dma = &xfer->dmamap; - ohci_soft_itd_t *sitd, *nsitd; + ohci_soft_itd_t *sitd, *nsitd, *p; ohci_physaddr_t dataphys, bp0, physend, prevpage; int curlen, i, len, ncur, nframes, npages, seg, segoff; int s; @@ -3423,9 +3458,15 @@ #endif s = splusb(); + for (p = opipe->tail.itd; p != NULL; p = p->nextitd) { + bus_dmamap_sync(p->dmablock->tag, p->dmablock->map, + BUS_DMASYNC_PREWRITE); + } opipe->tail.itd = sitd; sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP); sed->ed.ed_tailp = htole32(sitd->physaddr); + bus_dmamap_sync(sed->dmablock->tag, sed->dmablock->map, + BUS_DMASYNC_PREWRITE); splx(s); #ifdef USB_DEBUG @@ -3462,6 +3503,8 @@ s = splusb(); sed = opipe->sed; /* Turn off ED skip-bit to start processing */ sed->ed.ed_flags &= htole32(~OHCI_ED_SKIP); /* ED's ITD list.*/ + bus_dmamap_sync(sed->dmablock->tag, sed->dmablock->map, + BUS_DMASYNC_PREWRITE); splx(s); return (USBD_IN_PROGRESS); Index: ohcivar.h =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/dev/usb/ohcivar.h,v retrieving revision 1.47 diff -u -r1.47 ohcivar.h --- ohcivar.h 14 Jun 2007 16:23:31 -0000 1.47 +++ ohcivar.h 23 Jun 2007 20:00:35 -0000 @@ -42,6 +42,7 @@ ohci_ed_t ed; struct ohci_soft_ed *next; ohci_physaddr_t physaddr; + struct usb_dma_block *dmablock; } ohci_soft_ed_t; #define OHCI_SED_SIZE ((sizeof (struct ohci_soft_ed) + OHCI_ED_ALIGN - 1) / OHCI_ED_ALIGN * OHCI_ED_ALIGN) #define OHCI_SED_CHUNK (PAGE_SIZE / OHCI_SED_SIZE) @@ -51,6 +52,7 @@ struct ohci_soft_td *nexttd; /* mirrors nexttd in TD */ struct ohci_soft_td *dnext; /* next in done list */ ohci_physaddr_t physaddr; + struct usb_dma_block *dmablock; LIST_ENTRY(ohci_soft_td) hnext; usbd_xfer_handle xfer; u_int16_t len; @@ -66,6 +68,7 @@ struct ohci_soft_itd *nextitd; /* mirrors nexttd in ITD */ struct ohci_soft_itd *dnext; /* next in done list */ ohci_physaddr_t physaddr; + struct usb_dma_block *dmablock; LIST_ENTRY(ohci_soft_itd) hnext; usbd_xfer_handle xfer; u_int16_t flags; Index: usb_mem.h =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/dev/usb/usb_mem.h,v retrieving revision 1.22 diff -u -r1.22 usb_mem.h --- usb_mem.h 13 Jun 2007 05:45:48 -0000 1.22 +++ usb_mem.h 23 Jun 2007 20:00:35 -0000 @@ -53,6 +53,7 @@ #define DMAADDR(dma, o) ((dma)->block->segs[0].ds_addr + (dma)->offs + (o)) #define KERNADDR(dma, o) \ ((void *)((char *)((dma)->block->kaddr) + (dma)->offs + (o))) +#define DMABLOCKPTR(dma) ((dma)->block) usbd_status usb_allocmem(usbd_bus_handle,size_t,size_t, usb_dma_t *); void usb_freemem(usbd_bus_handle, usb_dma_t *); Index: usbdi.c =================================================================== RCS file: /dump/FreeBSD-CVS/src/sys/dev/usb/usbdi.c,v retrieving revision 1.104 diff -u -r1.104 usbdi.c --- usbdi.c 12 Feb 2008 11:03:29 -0000 1.104 +++ usbdi.c 12 Mar 2008 20:26:41 -0000 @@ -364,27 +364,14 @@ } dmap->nsegs = nseg; - if (nseg > 0) { - if (!usbd_xfer_isread(xfer)) { - /* - * Copy data if it is not already in the correct - * buffer. - */ - if (!(xfer->flags & USBD_NO_COPY) && - xfer->allocbuf != NULL && - xfer->buffer != xfer->allocbuf) - memcpy(xfer->allocbuf, xfer->buffer, - xfer->length); - bus_dmamap_sync(tag, dmap->map, BUS_DMASYNC_PREWRITE); - } else if (xfer->rqflags & URQ_REQUEST) { - /* - * Even if we have no data portion we still need to - * sync the dmamap for the request data in the SETUP - * packet. - */ - bus_dmamap_sync(tag, dmap->map, BUS_DMASYNC_PREWRITE); - } else - bus_dmamap_sync(tag, dmap->map, BUS_DMASYNC_PREREAD); + if (nseg > 0 && !usbd_xfer_isread(xfer)) { + /* + * Copy data if it is not already in the correct buffer. + */ + if (!(xfer->flags & USBD_NO_COPY) && xfer->allocbuf != NULL && + xfer->buffer != xfer->allocbuf) + memcpy(xfer->allocbuf, xfer->buffer, xfer->length); + bus_dmamap_sync(tag, dmap->map, BUS_DMASYNC_PREWRITE); } err = pipe->methods->transfer(xfer); if (err != USBD_IN_PROGRESS && err) {