diff options
author | imp <imp@FreeBSD.org> | 2006-11-22 17:56:36 +0000 |
---|---|---|
committer | imp <imp@FreeBSD.org> | 2006-11-22 17:56:36 +0000 |
commit | b163ab721d36eb09ac8452878f52637d4b5708ae (patch) | |
tree | 06b1e9daec7586ebcb0084748cdce8a6cf7f9fcf /sys | |
parent | c380f600ad6c50f307bb89da92cbe5d4ff29cfe1 (diff) | |
download | FreeBSD-src-b163ab721d36eb09ac8452878f52637d4b5708ae.zip FreeBSD-src-b163ab721d36eb09ac8452878f52637d4b5708ae.tar.gz |
Fix coherency issue. From submitter:
I have been debugging the usb problems some more. Your were
right in your assumption (thanks for the pointer) about lack
of calls to bus_dmamap_sync(). In usbdi.c bus_dmamap_sync()
does get used for transfers that move data from PC to USB and
it is used for transfers that move data from USB to PC. But
someone forgot that control transfers consist of possibly two
data chunks : the request itself and optionally a buffer of
data that should be transfered to or from the USB device. On
requests to the control endpoint without additional data
bus_dmamap_sync() didn't get called. For some reason my first
tests with umass worked (due to enough cache poisening I
guess). The attached patch adds a call to bus_dmamap_sync()
to usbdi.c and now all devices I have tried work out of the
box. I have successfully transfered large files using the
if_axe driver and I have mounted several different umass
devices.
submitted by: Daan Vreeken
sponsored by: Vitsch Electronics
reviewed by: cognet@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/usb/usbdi.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/sys/dev/usb/usbdi.c b/sys/dev/usb/usbdi.c index a322f3a..026e4f2 100644 --- a/sys/dev/usb/usbdi.c +++ b/sys/dev/usb/usbdi.c @@ -377,6 +377,13 @@ usbd_start_transfer(void *arg, bus_dma_segment_t *segs, int nseg, int error) xfer->buffer != xfer->allocbuf) memcpy(xfer->allocbuf, xfer->buffer, xfer->length); bus_dmamap_sync(tag, dmap->map, BUS_DMASYNC_PREWRITE); + } else { + /* + * Even if we have no data portion we still need to sync the + * dmamap for the request data in the SETUP packet + */ + if (xfer->rqflags & URQ_REQUEST) + bus_dmamap_sync(tag, dmap->map, BUS_DMASYNC_PREWRITE); } err = pipe->methods->transfer(xfer); if (err != USBD_IN_PROGRESS && err) { |