Hi, On Thu, May 03, 2012 at 10:55:02AM +0530, Pratyush Anand wrote: > If transfer not ready is received before ep queue is called for control > out transfer then pending flag is set. Handling of this case was not > correct. > TRB size must be max packet for all control out transfer. > dma sync function should also be called before start transfer. > > Signed-off-by: Pratyush Anand <pratyush.anand@xxxxxx> few things I need to complain about... > --- > drivers/usb/dwc3/ep0.c | 32 ++++++++++++++++++++++++++++++-- > 1 files changed, 30 insertions(+), 2 deletions(-) > > diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c > index c6c9b8a..ed1f728 100644 > --- a/drivers/usb/dwc3/ep0.c > +++ b/drivers/usb/dwc3/ep0.c > @@ -142,6 +142,8 @@ static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep, > */ > if (dep->flags & DWC3_EP_PENDING_REQUEST) { > unsigned direction; > + unsigned transfer_size; > + dma_addr_t dma_addr; > > direction = !!(dep->flags & DWC3_EP0_DIR_IN); > > @@ -150,9 +152,35 @@ static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep, > return 0; > } > > + transfer_size = req->request.length; > + > + if (!direction && !IS_ALIGNED((u32)transfer_size, > + dep->endpoint.maxpacket)) { > + /* > + * REVISIT in case request length is bigger than EP0 > + * wMaxPacketSize, we will need two chained TRBs to > + * handle the transfer. > + */ > + WARN_ON(transfer_size > dep->endpoint.maxpacket); > + > + dwc->ep0_bounced = true; > + transfer_size = roundup(transfer_size, > + (u32)dep->endpoint.maxpacket); > + dma_addr = dwc->ep0_bounce_addr; > + } else { > + dma_addr = req->request.dma; > + } > + > + ret = usb_gadget_map_request(&dwc->gadget, &req->request, > + direction); > + if (ret) { > + dev_dbg(dwc->dev, "failed to map request\n"); > + return ret; > + } indentation is completely wrong here... > + > ret = dwc3_ep0_start_trans(dwc, direction, > - req->request.dma, req->request.length, > - DWC3_TRBCTL_CONTROL_DATA); > + dma_addr, transfer_size, > + DWC3_TRBCTL_CONTROL_DATA); > dep->flags &= ~(DWC3_EP_PENDING_REQUEST | > DWC3_EP0_DIR_IN); > } else if (dwc->delayed_status) { This patch is pretty much duplicating dwc3_ep0_do_control_data() function, so just re-factor that function into something that can be used from an event and from when you already know which endpoint to use, then call it from __dwc3_gadget_ep0_queue(). That will look much nicer. -- balbi
Attachment:
signature.asc
Description: Digital signature