summaryrefslogtreecommitdiff
path: root/drivers/usb/gadget
diff options
context:
space:
mode:
authorFelipe Balbi <balbi@ti.com>2011-12-15 13:31:48 +0200
committerFelipe Balbi <balbi@ti.com>2012-02-28 14:48:23 +0200
commita698908d3b3be915ac20cd37faeff1216f6b4fe8 (patch)
tree208d35c5bc9d49ab5fcb65dd380429cc532426bd /drivers/usb/gadget
parentc15e03e1553d8fb334de26727b0edadd582a46e7 (diff)
usb: gadget: add generic map/unmap request utilities
such utilities are currently duplicated on all UDC drivers basically with the same structure. Let's group all implementations into one generic implementation and get rid of that duplication. Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r--drivers/usb/gadget/udc-core.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c
index 0b0d12ccc48..56da49f31d6 100644
--- a/drivers/usb/gadget/udc-core.c
+++ b/drivers/usb/gadget/udc-core.c
@@ -22,6 +22,7 @@
#include <linux/device.h>
#include <linux/list.h>
#include <linux/err.h>
+#include <linux/dma-mapping.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
@@ -49,6 +50,57 @@ static DEFINE_MUTEX(udc_lock);
/* ------------------------------------------------------------------------- */
+int usb_gadget_map_request(struct usb_gadget *gadget,
+ struct usb_request *req, int is_in)
+{
+ if (req->length == 0)
+ return 0;
+
+ if (req->num_sgs) {
+ int mapped;
+
+ mapped = dma_map_sg(&gadget->dev, req->sg, req->num_sgs,
+ is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+ if (mapped == 0) {
+ dev_err(&gadget->dev, "failed to map SGs\n");
+ return -EFAULT;
+ }
+
+ req->num_mapped_sgs = mapped;
+ } else {
+ req->dma = dma_map_single(&gadget->dev, req->buf, req->length,
+ is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+
+ if (dma_mapping_error(&gadget->dev, req->dma)) {
+ dev_err(&gadget->dev, "failed to map buffer\n");
+ return -EFAULT;
+ }
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(usb_gadget_map_request);
+
+void usb_gadget_unmap_request(struct usb_gadget *gadget,
+ struct usb_request *req, int is_in)
+{
+ if (req->length == 0)
+ return;
+
+ if (req->num_mapped_sgs) {
+ dma_unmap_sg(&gadget->dev, req->sg, req->num_mapped_sgs,
+ is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+
+ req->num_mapped_sgs = 0;
+ } else {
+ dma_unmap_single(&gadget->dev, req->dma, req->length,
+ is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+ }
+}
+EXPORT_SYMBOL_GPL(usb_gadget_unmap_request);
+
+/* ------------------------------------------------------------------------- */
+
/**
* usb_gadget_start - tells usb device controller to start up
* @gadget: The gadget we want to get started