Loading drivers/usb/dwc3/gadget.c +33 −7 Original line number Diff line number Diff line Loading @@ -1163,7 +1163,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep) static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param) { struct dwc3_gadget_ep_cmd_params params; struct dwc3_request *req; struct dwc3_request *req, *req1, *n; struct dwc3 *dwc = dep->dwc; int starting; int ret; Loading Loading @@ -1193,6 +1193,30 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param) ret = dwc3_send_gadget_ep_cmd(dep, cmd, ¶ms); if (ret < 0) { if ((ret == -EAGAIN) && starting && usb_endpoint_xfer_isoc(dep->endpoint.desc)) { /* If bit13 in Command complete event is set, software * must issue ENDTRANDFER command and wait for * Xfernotready event to queue the requests again. */ if (!dep->resource_index) { dep->resource_index = dwc3_gadget_ep_get_transfer_index(dep); WARN_ON_ONCE(!dep->resource_index); } dwc3_stop_active_transfer(dwc, dep->number, true); list_for_each_entry_safe_reverse(req1, n, &dep->started_list, list) { req1->trb->ctrl &= ~DWC3_TRB_CTRL_HWO; req1->trb = NULL; dwc3_gadget_move_pending_list_front(req1); dwc3_ep_inc_deq(dep); } return ret; } /* * FIXME we need to iterate over the list of requests * here and stop, unmap, free and del each of the linked Loading Loading @@ -1240,7 +1264,7 @@ static void __dwc3_gadget_start_isoc(struct dwc3 *dwc, * Schedule the first trb for one interval in the future or at * least 4 microframes. */ uf = cur_uf + max_t(u32, 4, dep->interval); uf = cur_uf + max_t(u32, 16, dep->interval); ret = __dwc3_gadget_kick_transfer(dep, uf); if (ret < 0) Loading Loading @@ -2638,6 +2662,9 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, unsigned actual; int chain; if (req->trb->ctrl & DWC3_TRB_CTRL_HWO) return 0; length = req->request.length; chain = req->num_pending_sgs > 0; if (chain) { Loading Loading @@ -2696,18 +2723,17 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, if (usb_endpoint_xfer_isoc(dep->endpoint.desc) && list_empty(&dep->started_list)) { if (list_empty(&dep->pending_list)) { if (list_empty(&dep->pending_list)) /* * If there is no entry in request list then do * not issue END TRANSFER now. Just set PENDING * flag, so that END TRANSFER is issued when an * entry is added into request list. */ dep->flags = DWC3_EP_PENDING_REQUEST; } else { dep->flags |= DWC3_EP_PENDING_REQUEST; else dwc3_stop_active_transfer(dwc, dep->number, true); dep->flags = DWC3_EP_ENABLED; } dep->flags &= ~DWC3_EP_MISSED_ISOC; return 1; } Loading drivers/usb/dwc3/gadget.h +8 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,14 @@ static inline struct dwc3_request *next_request(struct list_head *list) return list_first_entry(list, struct dwc3_request, list); } static inline void dwc3_gadget_move_pending_list_front(struct dwc3_request *req) { struct dwc3_ep *dep = req->dep; req->started = false; list_move(&req->list, &dep->pending_list); } static inline void dwc3_gadget_move_started_request(struct dwc3_request *req) { struct dwc3_ep *dep = req->dep; Loading Loading
drivers/usb/dwc3/gadget.c +33 −7 Original line number Diff line number Diff line Loading @@ -1163,7 +1163,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep) static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param) { struct dwc3_gadget_ep_cmd_params params; struct dwc3_request *req; struct dwc3_request *req, *req1, *n; struct dwc3 *dwc = dep->dwc; int starting; int ret; Loading Loading @@ -1193,6 +1193,30 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param) ret = dwc3_send_gadget_ep_cmd(dep, cmd, ¶ms); if (ret < 0) { if ((ret == -EAGAIN) && starting && usb_endpoint_xfer_isoc(dep->endpoint.desc)) { /* If bit13 in Command complete event is set, software * must issue ENDTRANDFER command and wait for * Xfernotready event to queue the requests again. */ if (!dep->resource_index) { dep->resource_index = dwc3_gadget_ep_get_transfer_index(dep); WARN_ON_ONCE(!dep->resource_index); } dwc3_stop_active_transfer(dwc, dep->number, true); list_for_each_entry_safe_reverse(req1, n, &dep->started_list, list) { req1->trb->ctrl &= ~DWC3_TRB_CTRL_HWO; req1->trb = NULL; dwc3_gadget_move_pending_list_front(req1); dwc3_ep_inc_deq(dep); } return ret; } /* * FIXME we need to iterate over the list of requests * here and stop, unmap, free and del each of the linked Loading Loading @@ -1240,7 +1264,7 @@ static void __dwc3_gadget_start_isoc(struct dwc3 *dwc, * Schedule the first trb for one interval in the future or at * least 4 microframes. */ uf = cur_uf + max_t(u32, 4, dep->interval); uf = cur_uf + max_t(u32, 16, dep->interval); ret = __dwc3_gadget_kick_transfer(dep, uf); if (ret < 0) Loading Loading @@ -2638,6 +2662,9 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, unsigned actual; int chain; if (req->trb->ctrl & DWC3_TRB_CTRL_HWO) return 0; length = req->request.length; chain = req->num_pending_sgs > 0; if (chain) { Loading Loading @@ -2696,18 +2723,17 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep, if (usb_endpoint_xfer_isoc(dep->endpoint.desc) && list_empty(&dep->started_list)) { if (list_empty(&dep->pending_list)) { if (list_empty(&dep->pending_list)) /* * If there is no entry in request list then do * not issue END TRANSFER now. Just set PENDING * flag, so that END TRANSFER is issued when an * entry is added into request list. */ dep->flags = DWC3_EP_PENDING_REQUEST; } else { dep->flags |= DWC3_EP_PENDING_REQUEST; else dwc3_stop_active_transfer(dwc, dep->number, true); dep->flags = DWC3_EP_ENABLED; } dep->flags &= ~DWC3_EP_MISSED_ISOC; return 1; } Loading
drivers/usb/dwc3/gadget.h +8 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,14 @@ static inline struct dwc3_request *next_request(struct list_head *list) return list_first_entry(list, struct dwc3_request, list); } static inline void dwc3_gadget_move_pending_list_front(struct dwc3_request *req) { struct dwc3_ep *dep = req->dep; req->started = false; list_move(&req->list, &dep->pending_list); } static inline void dwc3_gadget_move_started_request(struct dwc3_request *req) { struct dwc3_ep *dep = req->dep; Loading