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
This commit is contained in:
Marius Strobl 2006-11-27 18:39:02 +00:00
parent 80e1af292e
commit 10d8cebc7a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=164683

View File

@ -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) {