summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb
diff options
context:
space:
mode:
authormarius <marius@FreeBSD.org>2006-11-27 18:39:02 +0000
committermarius <marius@FreeBSD.org>2006-11-27 18:39:02 +0000
commitb92c02c4c737fdf42c084a51fde89a9bafc1cf7e (patch)
tree2875c8fef4ae52f7b74a86fa304c7b3deeb50140 /sys/dev/usb
parent2300703ff0d27c5cb6d468e069be12a286688555 (diff)
downloadFreeBSD-src-b92c02c4c737fdf42c084a51fde89a9bafc1cf7e.zip
FreeBSD-src-b92c02c4c737fdf42c084a51fde89a9bafc1cf7e.tar.gz
Refine the previous change to only call bus_dmamap_sync() in case of
an URQ_REQUEST when DMA segments are passed to usbd_start_transfer(); when the request doesn't include the optional data buffer the size of the transfer (xfer->length) is 0, in which case usbd_transfer() won't create a DMA map but call usbd_start_transfer() with no DMA segments. With the previous change this could result in the bus_dmamap_sync() implementation dereferencing the NULL-pointer passed as the DMA map argument. While at it fix what appears to be a typo in usbd_start_transfer(); in order to determine wheter usbd_start_transfer() was called with DMA segments check whether the number of segments is > 0 rather than the pointer to them being > 0. OK'ed by: imp
Diffstat (limited to 'sys/dev/usb')
-rw-r--r--sys/dev/usb/usbdi.c31
1 files changed, 19 insertions, 12 deletions
diff --git a/sys/dev/usb/usbdi.c b/sys/dev/usb/usbdi.c
index 026e4f2..a507eec 100644
--- a/sys/dev/usb/usbdi.c
+++ b/sys/dev/usb/usbdi.c
@@ -371,19 +371,26 @@ usbd_start_transfer(void *arg, bus_dma_segment_t *segs, int nseg, int error)
}
dmap->nsegs = nseg;
- if (segs > 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);
- } 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)
+ 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);
+ }
}
err = pipe->methods->transfer(xfer);
if (err != USBD_IN_PROGRESS && err) {
OpenPOWER on IntegriCloud