USB: gadget: ci13xxx_udc: Fix bug in nuking the control OUT endpoint
ci13xxx_udc controller driver exposes EP0 In as control endpoint to
function drivers. Function drivers request both IN and OUT control
data transfers on EP0 In. Controller driver internally uses EP0 Out
for queuing/retiring OUT control endpoint requests by checking the
control transfer direction. Do the same for nuking and dequeuing.
CRs-Fixed: 305866
Signed-off-by: Pavankumar Kondeti <pkondeti@codeaurora.org>
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index b3fc5e7..7cf888c 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -1745,6 +1745,8 @@
__releases(mEp->lock)
__acquires(mEp->lock)
{
+ struct ci13xxx_ep *mEpTemp = mEp;
+
trace("%p", mEp);
if (mEp == NULL)
@@ -1763,7 +1765,10 @@
if (mReq->req.complete != NULL) {
spin_unlock(mEp->lock);
- mReq->req.complete(&mEp->ep, &mReq->req);
+ if ((mEp->type == USB_ENDPOINT_XFER_CONTROL) &&
+ mReq->req.length)
+ mEpTemp = &_udc->ep0in;
+ mReq->req.complete(&mEpTemp->ep, &mReq->req);
spin_lock(mEp->lock);
}
}
@@ -2492,6 +2497,7 @@
static int ep_dequeue(struct usb_ep *ep, struct usb_request *req)
{
struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
+ struct ci13xxx_ep *mEpTemp = mEp;
struct ci13xxx_req *mReq = container_of(req, struct ci13xxx_req, req);
unsigned long flags;
@@ -2520,7 +2526,10 @@
if (mReq->req.complete != NULL) {
spin_unlock(mEp->lock);
- mReq->req.complete(&mEp->ep, &mReq->req);
+ if ((mEp->type == USB_ENDPOINT_XFER_CONTROL) &&
+ mReq->req.length)
+ mEpTemp = &_udc->ep0in;
+ mReq->req.complete(&mEpTemp->ep, &mReq->req);
spin_lock(mEp->lock);
}