Commit 31fe084f authored by Jack Pham's avatar Jack Pham Committed by Felipe Balbi

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: default avatarJack Pham <jackp@codeaurora.org>
Signed-off-by: default avatarFelipe Balbi <felipe.balbi@linux.intel.com>
parent f8faa3bf
...@@ -812,6 +812,8 @@ int usb_gadget_map_request_by_dev(struct device *dev, ...@@ -812,6 +812,8 @@ int usb_gadget_map_request_by_dev(struct device *dev,
dev_err(dev, "failed to map buffer\n"); dev_err(dev, "failed to map buffer\n");
return -EFAULT; return -EFAULT;
} }
req->dma_mapped = 1;
} }
return 0; return 0;
...@@ -836,9 +838,10 @@ void usb_gadget_unmap_request_by_dev(struct device *dev, ...@@ -836,9 +838,10 @@ void usb_gadget_unmap_request_by_dev(struct device *dev,
is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
req->num_mapped_sgs = 0; req->num_mapped_sgs = 0;
} else { } else if (req->dma_mapped) {
dma_unmap_single(dev, req->dma, req->length, dma_unmap_single(dev, req->dma, req->length,
is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
req->dma_mapped = 0;
} }
} }
EXPORT_SYMBOL_GPL(usb_gadget_unmap_request_by_dev); EXPORT_SYMBOL_GPL(usb_gadget_unmap_request_by_dev);
......
...@@ -48,6 +48,7 @@ struct usb_ep; ...@@ -48,6 +48,7 @@ struct usb_ep;
* by adding a zero length packet as needed; * by adding a zero length packet as needed;
* @short_not_ok: When reading data, makes short packets be * @short_not_ok: When reading data, makes short packets be
* treated as errors (queue stops advancing till cleanup). * 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 * @complete: Function called when request completes, so this request and
* its buffer may be re-used. The function will always be called with * its buffer may be re-used. The function will always be called with
* interrupts disabled, and it must not sleep. * interrupts disabled, and it must not sleep.
...@@ -103,6 +104,7 @@ struct usb_request { ...@@ -103,6 +104,7 @@ struct usb_request {
unsigned no_interrupt:1; unsigned no_interrupt:1;
unsigned zero:1; unsigned zero:1;
unsigned short_not_ok:1; unsigned short_not_ok:1;
unsigned dma_mapped:1;
void (*complete)(struct usb_ep *ep, void (*complete)(struct usb_ep *ep,
struct usb_request *req); struct usb_request *req);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment