summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChao Xie <chao.xie@marvell.com>2012-07-10 10:07:05 +0800
committerFelipe Balbi <balbi@ti.com>2012-08-23 11:04:16 +0300
commit60326ce377090541db9ba1a05a041316ab5b46ec (patch)
tree0a1e9013b9a8d1ffa93b8bb95ce32ea808f889e0
parent583a7263c7ed05c9a625d50950551ba5749c9379 (diff)
downloadlinux-3.10-60326ce377090541db9ba1a05a041316ab5b46ec.tar.gz
linux-3.10-60326ce377090541db9ba1a05a041316ab5b46ec.tar.bz2
linux-3.10-60326ce377090541db9ba1a05a041316ab5b46ec.zip
usb: gadget: mv_udc: add iso support
In order to support iso, we need do the following things: 1. fix length for one dtd 2. allow req contains multiple packets for a ISO transfer Signed-off-by: Chao Xie <chao.xie@marvell.com> Signed-off-by: Yu Xu <yuxu@marvell.com> Signed-off-by: Neil Zhang <zhangwm@marvell.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
-rw-r--r--drivers/usb/gadget/mv_udc_core.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c
index 4d3a4136b37..ff6154d1816 100644
--- a/drivers/usb/gadget/mv_udc_core.c
+++ b/drivers/usb/gadget/mv_udc_core.c
@@ -355,17 +355,24 @@ done:
return retval;
}
-
static struct mv_dtd *build_dtd(struct mv_req *req, unsigned *length,
dma_addr_t *dma, int *is_last)
{
- u32 temp;
struct mv_dtd *dtd;
struct mv_udc *udc;
+ struct mv_dqh *dqh;
+ u32 temp, mult = 0;
/* how big will this transfer be? */
- *length = min(req->req.length - req->req.actual,
- (unsigned)EP_MAX_LENGTH_TRANSFER);
+ if (usb_endpoint_xfer_isoc(req->ep->ep.desc)) {
+ dqh = req->ep->dqh;
+ mult = (dqh->max_packet_length >> EP_QUEUE_HEAD_MULT_POS)
+ & 0x3;
+ *length = min(req->req.length - req->req.actual,
+ (unsigned)(mult * req->ep->ep.maxpacket));
+ } else
+ *length = min(req->req.length - req->req.actual,
+ (unsigned)EP_MAX_LENGTH_TRANSFER);
udc = req->ep->udc;
@@ -407,6 +414,8 @@ static struct mv_dtd *build_dtd(struct mv_req *req, unsigned *length,
if (*is_last && !req->req.no_interrupt)
temp |= DTD_IOC;
+ temp |= mult << 10;
+
dtd->size_ioc_sts = temp;
mb();
@@ -718,10 +727,6 @@ mv_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
dev_err(&udc->dev->dev, "%s, bad ep", __func__);
return -EINVAL;
}
- if (ep->ep.desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
- if (req->req.length > ep->ep.maxpacket)
- return -EMSGSIZE;
- }
udc = ep->udc;
if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN)