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@xxxxxx> --- drivers/usb/gadget/udc-core.c | 58 +++++++++++++++++++++++++++++++++++++++++ include/linux/usb/gadget.h | 12 ++++++++ 2 files changed, 70 insertions(+), 0 deletions(-) diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index 0b0d12c..7e0bbfe 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,63 @@ static DEFINE_MUTEX(udc_lock); /* ------------------------------------------------------------------------- */ +void usb_gadget_map_request(struct usb_gadget *gadget, + struct usb_request *req, int direction) +{ + if (req->length == 0) + return; + + if (req->num_sgs) { + int mapped; + + mapped = dma_map_sg(&gadget->dev, req->sg, req->num_sgs, + direction ? DMA_TO_DEVICE + : DMA_FROM_DEVICE); + if (mapped < 0) { + dev_err(&gadget->dev, "failed to map SGs\n"); + return; + } + + req->num_mapped_sgs = mapped; + return; + } + + if (req->dma == DMA_ADDR_INVALID) { + req->dma = dma_map_single(&gadget->dev, req->buf, req->length, + direction ? DMA_TO_DEVICE : DMA_FROM_DEVICE); + + WARN_ON(dma_mapping_error(&gadget->dev, req->dma)); + } +} +EXPORT_SYMBOL_GPL(usb_gadget_map_request); + +void usb_gadget_unmap_request(struct usb_gadget *gadget, + struct usb_request *req, int direction) +{ + if (req->length == 0) { + req->dma = DMA_ADDR_INVALID; + return; + } + + if (req->num_mapped_sgs) { + req->dma = DMA_ADDR_INVALID; + dma_unmap_sg(&gadget->dev, req->sg, req->num_sgs, + direction ? DMA_TO_DEVICE : DMA_FROM_DEVICE); + + req->num_mapped_sgs = 0; + return; + } + + if (req->dma != DMA_ADDR_INVALID) { + dma_unmap_single(&gadget->dev, req->dma, req->length, + direction ? DMA_TO_DEVICE : DMA_FROM_DEVICE); + req->dma = DMA_ADDR_INVALID; + } +} +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 diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 7b5a72c..c3794d6 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -950,6 +950,18 @@ static inline void usb_free_descriptors(struct usb_descriptor_header **v) /*-------------------------------------------------------------------------*/ +/* utility to simplify map/unmap of usb_requests to/from DMA */ + +#define DMA_ADDR_INVALID (~(dma_addr_t) 0) + +extern void usb_gadget_map_request(struct usb_gadget *gadget, + struct usb_request *req, int direction); + +extern void usb_gadget_unmap_request(struct usb_gadget *gadget, + struct usb_request *req, int direction); + +/*-------------------------------------------------------------------------*/ + /* utility wrapping a simple endpoint selection policy */ extern struct usb_ep *usb_ep_autoconfig(struct usb_gadget *, -- 1.7.8.rc3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html