mirror of
https://github.com/torvalds/linux.git
synced 2024-11-16 17:12:06 +00:00
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>
This commit is contained in:
parent
c15e03e155
commit
a698908d3b
@ -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
|
||||
|
@ -950,6 +950,16 @@ static inline void usb_free_descriptors(struct usb_descriptor_header **v)
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* utility to simplify map/unmap of usb_requests to/from DMA */
|
||||
|
||||
extern int usb_gadget_map_request(struct usb_gadget *gadget,
|
||||
struct usb_request *req, int is_in);
|
||||
|
||||
extern void usb_gadget_unmap_request(struct usb_gadget *gadget,
|
||||
struct usb_request *req, int is_in);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/* utility wrapping a simple endpoint selection policy */
|
||||
|
||||
extern struct usb_ep *usb_ep_autoconfig(struct usb_gadget *,
|
||||
|
Loading…
Reference in New Issue
Block a user