diff options
author | Chao Xie <chao.xie@marvell.com> | 2012-07-10 10:07:05 +0800 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2012-08-23 11:04:16 +0300 |
commit | 60326ce377090541db9ba1a05a041316ab5b46ec (patch) | |
tree | 0a1e9013b9a8d1ffa93b8bb95ce32ea808f889e0 | |
parent | 583a7263c7ed05c9a625d50950551ba5749c9379 (diff) | |
download | linux-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.c | 21 |
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) |