Hi,

(using private email as I'm having issue with company's VPN, will get
that sorted out by tomorrow hopefully)

> On Thu, 8 May 2014, Zhuang Jin Can wrote:
> > > dwc3 _cannot_ return NYET to a SETUP packet.  The USB protocol does
> > > not 
> > > allow it.  A device must always respond to SETUP with ACK.
> > It true that device can not return NYET to a SETUP packet.
> > A device must always respond to SETUP with ACK _if_ the SETUP packet
> > is
> > correctly received. Because there's no buffer prepared in ep0 for dwc3
> > to receive the SETUP packet, I guess there will be no handshake
> > returned to host. I can confirm this by doing an experiment tomorrow:)
> 
> The dwc3 driver should always prepare a buffer for the next ep0 SETUP
> packet as soon as it retrieves the information for the current SETUP 
> packet from the buffer.
> 
> Otherwise, as you described it, if the gadget driver never sends its 
> delayed status response then the UDC will never respond to any more 
> control transfers.

we _do_ prepare transfers for setup packet everytime a Status phase is
completed (we also restart ep0 in case of stalls):

| static void dwc3_ep0_stall_and_restart(struct dwc3 *dwc)
| {
|       struct dwc3_ep          *dep;
| 
|       /* reinitialize physical ep1 */
|       dep = dwc->eps[1];
|       dep->flags = DWC3_EP_ENABLED;
| 
|       /* stall is always issued on EP0 */
|       dep = dwc->eps[0];
|       __dwc3_gadget_ep_set_halt(dep, 1);
|       dep->flags = DWC3_EP_ENABLED;
|       dwc->delayed_status = false;
| 
|       if (!list_empty(&dep->request_list)) {
|               struct dwc3_request     *req;
| 
|               req = next_request(&dep->request_list);
|               dwc3_gadget_giveback(dep, req, -ECONNRESET);
|       }
| 
|       dwc->ep0state = EP0_SETUP_PHASE;
|       dwc3_ep0_out_start(dwc);
| }

[ ... ]

| void dwc3_ep0_out_start(struct dwc3 *dwc)
| {
|       int                             ret;
| 
|       ret = dwc3_ep0_start_trans(dwc, 0, dwc->ctrl_req_addr, 8,
|                       DWC3_TRBCTL_CONTROL_SETUP);
|       WARN_ON(ret < 0);
| }

[ ... ]

| static void dwc3_ep0_complete_status(struct dwc3 *dwc,
|               const struct dwc3_event_depevt *event)
| {
|       struct dwc3_request     *r;
|       struct dwc3_ep          *dep;
|       struct dwc3_trb         *trb;
|       u32                     status;
| 
|       dep = dwc->eps[0];
|       trb = dwc->ep0_trb;
| 
|       if (!list_empty(&dep->request_list)) {
|               r = next_request(&dep->request_list);
| 
|               dwc3_gadget_giveback(dep, r, 0);
|       }
| 
|       if (dwc->test_mode) {
|               int ret;
| 
|               ret = dwc3_gadget_set_test_mode(dwc, dwc->test_mode_nr);
|               if (ret < 0) {
|                       dev_dbg(dwc->dev, "Invalid Test #%d\n",
|                                       dwc->test_mode_nr);
|                       dwc3_ep0_stall_and_restart(dwc);
|                       return;
|               }
|       }
| 
|       status = DWC3_TRB_SIZE_TRBSTS(trb->size);
|       if (status == DWC3_TRBSTS_SETUP_PENDING)
|               dev_dbg(dwc->dev, "Setup Pending received\n");
| 
|       dwc->ep0state = EP0_SETUP_PHASE;
|       dwc3_ep0_out_start(dwc);
| }

-- 
balbi

Attachment: signature.asc
Description: Digital signature

Reply via email to