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
signature.asc
Description: Digital signature
