static void dwc3_ep0_xfernotready(struct dwc3 *dwc, const struct dwc3_event_depevt *event) { switch (event->status) { case DEPEVT_STATUS_CONTROL_DATA: /* * We already have a DATA transfer in the controller's cache, * if we receive a XferNotReady(DATA) we will ignore it, unless * it's for the wrong direction. * * In that case, we must issue END_TRANSFER command to the Data * Phase we already have started and issue SetStall on the * control endpoint. */ if (dwc->ep0_expect_in != event->endpoint_number) { struct dwc3_ep *dep = dwc->eps[dwc->ep0_expect_in]; dev_err(dwc->dev, "unexpected direction for Data Phase\n"); dwc3_ep0_end_control_data(dwc, dep); dwc3_ep0_stall_and_restart(dwc); return; } break; case DEPEVT_STATUS_CONTROL_STATUS: if (dwc->ep0_next_event != DWC3_EP0_NRDY_STATUS) return; dwc->ep0state = EP0_STATUS_PHASE; if (dwc->delayed_status) { struct dwc3_ep *dep = dwc->eps[0]; WARN_ON_ONCE(event->endpoint_number != 1); /* * We should handle the delay STATUS phase here if the * request for handling delay STATUS has been queued * into the list. */ if (!list_empty(&dep->pending_list)) { dwc->delayed_status = false; usb_gadget_set_state(&dwc->gadget, USB_STATE_CONFIGURED); dwc3_ep0_do_control_status(dwc, event); } return; } dwc3_ep0_do_control_status(dwc, event); } }
static void dwc3_ep0_xfernotready(struct dwc3 *dwc, const struct dwc3_event_depevt *event) { switch (event->status) { case DEPEVT_STATUS_CONTROL_SETUP: dev_vdbg(dwc->dev, "Control Setup\n"); dwc3_ep0_do_control_setup(dwc, event); break; case DEPEVT_STATUS_CONTROL_DATA: dev_vdbg(dwc->dev, "Control Data\n"); if (dwc->ep0_next_event != DWC3_EP0_NRDY_DATA) { dev_vdbg(dwc->dev, "Expected %d got %d\n", dwc->ep0_next_event, DWC3_EP0_NRDY_DATA); dwc3_ep0_stall_and_restart(dwc); return; } /* * One of the possible error cases is when Host _does_ * request for Data Phase, but it does so on the wrong * direction. * * Here, we already know ep0_next_event is DATA (see above), * so we only need to check for direction. */ if (dwc->ep0_expect_in != event->endpoint_number) { dev_vdbg(dwc->dev, "Wrong direction for Data phase\n"); dwc3_ep0_stall_and_restart(dwc); return; } dwc3_ep0_do_control_data(dwc, event); break; case DEPEVT_STATUS_CONTROL_STATUS: dev_vdbg(dwc->dev, "Control Status\n"); if (dwc->ep0_next_event != DWC3_EP0_NRDY_STATUS) { dev_vdbg(dwc->dev, "Expected %d got %d\n", dwc->ep0_next_event, DWC3_EP0_NRDY_STATUS); dwc3_ep0_stall_and_restart(dwc); return; } dwc3_ep0_do_control_status(dwc, event); } }
static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep, struct dwc3_request *req) { struct dwc3 *dwc = dep->dwc; u32 type; int ret = 0; req->request.actual = 0; req->request.status = -EINPROGRESS; req->epnum = dep->number; list_add_tail(&req->list, &dep->request_list); /* * Gadget driver might not be quick enough to queue a request * before we get a Transfer Not Ready event on this endpoint. * * In that case, we will set DWC3_EP_PENDING_REQUEST. When that * flag is set, it's telling us that as soon as Gadget queues the * required request, we should kick the transfer here because the * IRQ we were waiting for is long gone. */ if (dep->flags & DWC3_EP_PENDING_REQUEST) { unsigned direction; direction = !!(dep->flags & DWC3_EP0_DIR_IN); if (dwc->ep0state == EP0_STATUS_PHASE) { type = dwc->three_stage_setup ? DWC3_TRBCTL_CONTROL_STATUS3 : DWC3_TRBCTL_CONTROL_STATUS2; } else if (dwc->ep0state == EP0_DATA_PHASE) { type = DWC3_TRBCTL_CONTROL_DATA; } else { /* should never happen */ WARN_ON(1); return 0; } ret = dwc3_ep0_start_trans(dwc, direction, req->request.dma, req->request.length, type); dep->flags &= ~(DWC3_EP_PENDING_REQUEST | DWC3_EP0_DIR_IN); } else if (dwc->delayed_status && (dwc->ep0state == EP0_STATUS_PHASE)) { dwc->delayed_status = false; dwc3_ep0_do_control_status(dwc, 1); } return ret; }
static void dwc3_ep0_xfernotready(struct dwc3 *dwc, const struct dwc3_event_depevt *event) { dwc->setup_packet_pending = true; switch (event->status) { case DEPEVT_STATUS_CONTROL_DATA: dwc3_trace(trace_dwc3_ep0, "Control Data"); /* * We already have a DATA transfer in the controller's cache, * if we receive a XferNotReady(DATA) we will ignore it, unless * it's for the wrong direction. * * In that case, we must issue END_TRANSFER command to the Data * Phase we already have started and issue SetStall on the * control endpoint. */ if (dwc->ep0_expect_in != event->endpoint_number) { struct dwc3_ep *dep = dwc->eps[dwc->ep0_expect_in]; dwc3_trace(trace_dwc3_ep0, "Wrong direction for Data phase"); dwc3_ep0_end_control_data(dwc, dep); dwc3_ep0_stall_and_restart(dwc); return; } break; case DEPEVT_STATUS_CONTROL_STATUS: if (dwc->ep0_next_event != DWC3_EP0_NRDY_STATUS) return; dwc3_trace(trace_dwc3_ep0, "Control Status"); dwc->ep0state = EP0_STATUS_PHASE; if (dwc->delayed_status) { WARN_ON_ONCE(event->endpoint_number != 1); dwc3_trace(trace_dwc3_ep0, "Delayed Status"); return; } dwc3_ep0_do_control_status(dwc, event); } }
static void dwc3_ep0_xfernotready(struct dwc3 *dwc, const struct dwc3_event_depevt *event) { dwc->setup_packet_pending = true; /* * This part is very tricky: If we has just handled * XferNotReady(Setup) and we're now expecting a * XferComplete but, instead, we receive another * XferNotReady(Setup), we should STALL and restart * the state machine. * * In all other cases, we just continue waiting * for the XferComplete event. * * We are a little bit unsafe here because we're * not trying to ensure that last event was, indeed, * XferNotReady(Setup). * * Still, we don't expect any condition where that * should happen and, even if it does, it would be * another error condition. */ if (dwc->ep0_next_event == DWC3_EP0_COMPLETE) { switch (event->status) { case DEPEVT_STATUS_CONTROL_SETUP: dev_vdbg(dwc->dev, "Unexpected XferNotReady(Setup)\n"); dwc3_ep0_stall_and_restart(dwc); break; case DEPEVT_STATUS_CONTROL_DATA: /* FALLTHROUGH */ case DEPEVT_STATUS_CONTROL_STATUS: /* FALLTHROUGH */ default: dev_vdbg(dwc->dev, "waiting for XferComplete\n"); } return; } switch (event->status) { case DEPEVT_STATUS_CONTROL_SETUP: dev_vdbg(dwc->dev, "Control Setup\n"); dwc->ep0state = EP0_SETUP_PHASE; dwc3_ep0_do_control_setup(dwc, event); break; case DEPEVT_STATUS_CONTROL_DATA: dev_vdbg(dwc->dev, "Control Data\n"); dwc->ep0state = EP0_DATA_PHASE; if (dwc->ep0_next_event != DWC3_EP0_NRDY_DATA) { dev_vdbg(dwc->dev, "Expected %d got %d\n", dwc->ep0_next_event, DWC3_EP0_NRDY_DATA); dwc3_ep0_stall_and_restart(dwc); return; } /* * One of the possible error cases is when Host _does_ * request for Data Phase, but it does so on the wrong * direction. * * Here, we already know ep0_next_event is DATA (see above), * so we only need to check for direction. */ if (dwc->ep0_expect_in != event->endpoint_number) { dev_vdbg(dwc->dev, "Wrong direction for Data phase\n"); dwc3_ep0_stall_and_restart(dwc); return; } dwc3_ep0_do_control_data(dwc, event); break; case DEPEVT_STATUS_CONTROL_STATUS: dev_vdbg(dwc->dev, "Control Status\n"); dwc->ep0state = EP0_STATUS_PHASE; if (dwc->ep0_next_event != DWC3_EP0_NRDY_STATUS) { dev_vdbg(dwc->dev, "Expected %d got %d\n", dwc->ep0_next_event, DWC3_EP0_NRDY_STATUS); dwc3_ep0_stall_and_restart(dwc); return; } if (dwc->delayed_status) { WARN_ON_ONCE(event->endpoint_number != 1); dev_vdbg(dwc->dev, "Mass Storage delayed status\n"); return; } dwc3_ep0_do_control_status(dwc, event->endpoint_number); } }
static void dwc3_ep0_xfernotready(struct dwc3 *dwc, const struct dwc3_event_depevt *event) { u8 epnum; int ret; dwc->setup_packet_pending = true; epnum = event->endpoint_number; switch (event->status) { case DEPEVT_STATUS_CONTROL_DATA: dev_vdbg(dwc->dev, "Control Data\n"); /* * We already have a DATA transfer in the controller's cache, * if we receive a XferNotReady(DATA) we will ignore it, unless * it's for the wrong direction. * * In that case, we must issue END_TRANSFER command to the Data * Phase we already have started and issue SetStall on the * control endpoint. */ if (dwc->ep0_expect_in != event->endpoint_number) { struct dwc3_ep *dep = dwc->eps[dwc->ep0_expect_in]; dev_vdbg(dwc->dev, "Wrong direction for Data phase\n"); dwc3_ep0_end_control_data(dwc, dep); dwc3_ep0_stall_and_restart(dwc); return; } if (zlp_required) { zlp_required = false; ret = dwc3_ep0_start_trans(dwc, epnum, dwc->ctrl_req_addr, 0, DWC3_TRBCTL_CONTROL_DATA); dbg_event(epnum, "ZLP", ret); WARN_ON(ret < 0); } break; case DEPEVT_STATUS_CONTROL_STATUS: if (dwc->ep0_next_event != DWC3_EP0_NRDY_STATUS) return; dev_vdbg(dwc->dev, "Control Status\n"); zlp_required = false; dwc->ep0state = EP0_STATUS_PHASE; if (dwc->delayed_status && list_empty(&dwc->eps[0]->request_list)) { WARN_ON_ONCE(event->endpoint_number != 1); dev_vdbg(dwc->dev, "Mass Storage delayed status\n"); return; } dwc->delayed_status = false; dwc3_ep0_do_control_status(dwc, event); } }
static void dwc3_ep0_xfernotready(struct dwc3 *dwc, const struct dwc3_event_depevt *event) { dwc->setup_packet_pending = true; switch (event->status) { case DEPEVT_STATUS_CONTROL_DATA: dev_vdbg(dwc->dev, "Control Data\n"); /* * We already have a DATA transfer in the controller's cache, * if we receive a XferNotReady(DATA) we will ignore it, unless * it's for the wrong direction. * * In that case, we must issue END_TRANSFER command to the Data * Phase we already have started and issue SetStall on the * control endpoint. */ if (dwc->ep0_expect_in != event->endpoint_number) { struct dwc3_ep *dep = dwc->eps[dwc->ep0_expect_in]; dev_vdbg(dwc->dev, "Wrong direction for Data phase\n"); dwc3_ep0_end_control_data(dwc, dep); dwc3_ep0_stall_and_restart(dwc); return; } /* * Per databook, if an XferNotready(Data) is received after * XferComplete(Data), one possible reason is host is trying * to complete data stage by moving a 0-length packet. * * REVISIT in case of other cases */ if (dwc->ep0_next_event == DWC3_EP0_NRDY_STATUS) { u32 size = 0; struct dwc3_ep *dep = dwc->eps[event->endpoint_number]; if (dep->number == 0) size = dep->endpoint.maxpacket; dwc3_ep0_start_trans(dwc, dep->number, dwc->ctrl_req_addr, size, DWC3_TRBCTL_CONTROL_DATA); } break; case DEPEVT_STATUS_CONTROL_STATUS: if (dwc->ep0_next_event != DWC3_EP0_NRDY_STATUS) return; dev_vdbg(dwc->dev, "Control Status\n"); dwc->ep0state = EP0_STATUS_PHASE; if (dwc->delayed_status) { WARN_ON_ONCE(event->endpoint_number != 1); dev_vdbg(dwc->dev, "Mass Storage delayed status\n"); if (list_empty(&dwc->eps[0]->request_list)) return; else dwc->delayed_status = false; } dwc3_ep0_do_control_status(dwc, event); } }