summaryrefslogtreecommitdiff
path: root/drivers/usb/gadget/udc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/udc')
-rw-r--r--drivers/usb/gadget/udc/udc-core.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c
index c6859fdd74bc..3454e263fd82 100644
--- a/drivers/usb/gadget/udc/udc-core.c
+++ b/drivers/usb/gadget/udc/udc-core.c
@@ -76,7 +76,7 @@ int usb_gadget_map_request(struct usb_gadget *gadget,
}
req->num_mapped_sgs = mapped;
- } else {
+ } else if (!req->dma_pre_mapped) {
req->dma = dma_map_single(dev, req->buf, req->length,
is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
@@ -101,9 +101,15 @@ void usb_gadget_unmap_request(struct usb_gadget *gadget,
is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
req->num_mapped_sgs = 0;
- } else {
+ } else if (!req->dma_pre_mapped && req->dma != DMA_ERROR_CODE) {
+ /*
+ * If the DMA address has not been mapped by a higher layer,
+ * then unmap it here. Otherwise, the DMA address will be
+ * unmapped by the upper layer (where the request was queued).
+ */
dma_unmap_single(gadget->dev.parent, req->dma, req->length,
is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+ req->dma = DMA_ERROR_CODE;
}
}
EXPORT_SYMBOL_GPL(usb_gadget_unmap_request);