mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-17 01:04:19 +08:00
usb: dwc3: use ep0_next_event field
Start tracking the next expected event and act on the error conditions as suggested by databook. Signed-off-by: Felipe Balbi <balbi@ti.com>
This commit is contained in:
parent
b53c772d16
commit
1ddcb218b5
@ -120,6 +120,8 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,
|
|||||||
dep->res_trans_idx = dwc3_gadget_ep_get_transfer_index(dwc,
|
dep->res_trans_idx = dwc3_gadget_ep_get_transfer_index(dwc,
|
||||||
dep->number);
|
dep->number);
|
||||||
|
|
||||||
|
dwc->ep0_next_event = DWC3_EP0_COMPLETE;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,7 +252,6 @@ static void dwc3_ep0_send_status_response(struct dwc3 *dwc)
|
|||||||
dwc3_ep0_start_trans(dwc, 1, dwc->setup_buf_addr,
|
dwc3_ep0_start_trans(dwc, 1, dwc->setup_buf_addr,
|
||||||
dwc->ep0_usb_req.length,
|
dwc->ep0_usb_req.length,
|
||||||
DWC3_TRBCTL_CONTROL_DATA);
|
DWC3_TRBCTL_CONTROL_DATA);
|
||||||
dwc->ep0_status_pending = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -295,7 +296,7 @@ static int dwc3_ep0_handle_status(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl
|
|||||||
response_pkt = (__le16 *) dwc->setup_buf;
|
response_pkt = (__le16 *) dwc->setup_buf;
|
||||||
*response_pkt = cpu_to_le16(usb_status);
|
*response_pkt = cpu_to_le16(usb_status);
|
||||||
dwc->ep0_usb_req.length = sizeof(*response_pkt);
|
dwc->ep0_usb_req.length = sizeof(*response_pkt);
|
||||||
dwc3_ep0_send_status_response(dwc);
|
dwc->ep0_status_pending = 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -526,10 +527,13 @@ static void dwc3_ep0_inspect_setup(struct dwc3 *dwc,
|
|||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
len = le16_to_cpu(ctrl->wLength);
|
len = le16_to_cpu(ctrl->wLength);
|
||||||
if (!len)
|
if (!len) {
|
||||||
dwc->three_stage_setup = 0;
|
dwc->three_stage_setup = 0;
|
||||||
else
|
dwc->ep0_next_event = DWC3_EP0_NRDY_STATUS;
|
||||||
|
} else {
|
||||||
dwc->three_stage_setup = 1;
|
dwc->three_stage_setup = 1;
|
||||||
|
dwc->ep0_next_event = DWC3_EP0_NRDY_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD)
|
if ((ctrl->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD)
|
||||||
ret = dwc3_ep0_std_request(dwc, ctrl);
|
ret = dwc3_ep0_std_request(dwc, ctrl);
|
||||||
@ -556,6 +560,8 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
|
|||||||
epnum = event->endpoint_number;
|
epnum = event->endpoint_number;
|
||||||
dep = dwc->eps[epnum];
|
dep = dwc->eps[epnum];
|
||||||
|
|
||||||
|
dwc->ep0_next_event = DWC3_EP0_NRDY_STATUS;
|
||||||
|
|
||||||
if (!dwc->ep0_status_pending) {
|
if (!dwc->ep0_status_pending) {
|
||||||
r = next_request(&dwc->eps[0]->request_list);
|
r = next_request(&dwc->eps[0]->request_list);
|
||||||
ur = &r->request;
|
ur = &r->request;
|
||||||
@ -655,6 +661,11 @@ static void dwc3_ep0_do_control_data(struct dwc3 *dwc,
|
|||||||
dep = dwc->eps[0];
|
dep = dwc->eps[0];
|
||||||
dwc->ep0state = EP0_DATA_PHASE;
|
dwc->ep0state = EP0_DATA_PHASE;
|
||||||
|
|
||||||
|
if (dwc->ep0_status_pending) {
|
||||||
|
dwc3_ep0_send_status_response(dwc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (list_empty(&dep->request_list)) {
|
if (list_empty(&dep->request_list)) {
|
||||||
dev_vdbg(dwc->dev, "pending request for EP0 Data phase\n");
|
dev_vdbg(dwc->dev, "pending request for EP0 Data phase\n");
|
||||||
dep->flags |= DWC3_EP_PENDING_REQUEST;
|
dep->flags |= DWC3_EP_PENDING_REQUEST;
|
||||||
@ -724,12 +735,33 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc,
|
|||||||
dev_vdbg(dwc->dev, "Control Setup\n");
|
dev_vdbg(dwc->dev, "Control Setup\n");
|
||||||
dwc3_ep0_do_control_setup(dwc, event);
|
dwc3_ep0_do_control_setup(dwc, event);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DEPEVT_STATUS_CONTROL_DATA:
|
case DEPEVT_STATUS_CONTROL_DATA:
|
||||||
dev_vdbg(dwc->dev, "Control Data\n");
|
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",
|
||||||
|
DEPEVT_STATUS_CONTROL_DATA,
|
||||||
|
event->status);
|
||||||
|
|
||||||
|
dwc3_ep0_stall_and_restart(dwc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
dwc3_ep0_do_control_data(dwc, event);
|
dwc3_ep0_do_control_data(dwc, event);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DEPEVT_STATUS_CONTROL_STATUS:
|
case DEPEVT_STATUS_CONTROL_STATUS:
|
||||||
dev_vdbg(dwc->dev, "Control Status\n");
|
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",
|
||||||
|
DEPEVT_STATUS_CONTROL_STATUS,
|
||||||
|
event->status);
|
||||||
|
|
||||||
|
dwc3_ep0_stall_and_restart(dwc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
dwc3_ep0_do_control_status(dwc, event);
|
dwc3_ep0_do_control_status(dwc, event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user