usb: gadget: core: unmap request from DMA only if previously mapped
In the SG case this is already handled since a non-zero request->num_mapped_sgs is a clear indicator that dma_map_sg() had been called. While it would be nice to do the same for the singly mapped case by simply checking for non-zero request->dma, it's conceivable that 0 is a valid dma_addr_t handle. Hence add a flag 'dma_mapped' to struct usb_request and use this to determine the need to call dma_unmap_single(). Otherwise, if a request is not DMA mapped then the result of calling usb_request_unmap_request() would safely be a no-op. Signed-off-by: Jack Pham <jackp@codeaurora.org> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
This commit is contained in:
parent
f8faa3bf5f
commit
31fe084ffa
|
@ -812,6 +812,8 @@ int usb_gadget_map_request_by_dev(struct device *dev,
|
|||
dev_err(dev, "failed to map buffer\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
req->dma_mapped = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -836,9 +838,10 @@ void usb_gadget_unmap_request_by_dev(struct device *dev,
|
|||
is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
|
||||
|
||||
req->num_mapped_sgs = 0;
|
||||
} else {
|
||||
} else if (req->dma_mapped) {
|
||||
dma_unmap_single(dev, req->dma, req->length,
|
||||
is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
|
||||
req->dma_mapped = 0;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_gadget_unmap_request_by_dev);
|
||||
|
|
|
@ -48,6 +48,7 @@ struct usb_ep;
|
|||
* by adding a zero length packet as needed;
|
||||
* @short_not_ok: When reading data, makes short packets be
|
||||
* treated as errors (queue stops advancing till cleanup).
|
||||
* @dma_mapped: Indicates if request has been mapped to DMA (internal)
|
||||
* @complete: Function called when request completes, so this request and
|
||||
* its buffer may be re-used. The function will always be called with
|
||||
* interrupts disabled, and it must not sleep.
|
||||
|
@ -103,6 +104,7 @@ struct usb_request {
|
|||
unsigned no_interrupt:1;
|
||||
unsigned zero:1;
|
||||
unsigned short_not_ok:1;
|
||||
unsigned dma_mapped:1;
|
||||
|
||||
void (*complete)(struct usb_ep *ep,
|
||||
struct usb_request *req);
|
||||
|
|
Loading…
Reference in a new issue