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:
parent
80e1af292e
commit
10d8cebc7a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=164683
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user