Loading drivers/usb/dwc3/gadget.c +38 −36 Original line number Diff line number Diff line Loading @@ -1339,6 +1339,8 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep) } } static void dwc3_gadget_ep_cleanup_cancelled_requests(struct dwc3_ep *dep); static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep) { struct dwc3_gadget_ep_cmd_params params; Loading Loading @@ -1380,14 +1382,20 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep) ret = dwc3_send_gadget_ep_cmd(dep, cmd, ¶ms); if (ret < 0) { /* * FIXME we need to iterate over the list of requests * here and stop, unmap, free and del each of the linked * requests instead of what we do now. */ if (req->trb) memset(req->trb, 0, sizeof(struct dwc3_trb)); dwc3_gadget_del_and_unmap_request(dep, req, ret); struct dwc3_request *tmp; if (ret == -EAGAIN) return ret; dwc3_stop_active_transfer(dep, true, true); list_for_each_entry_safe(req, tmp, &dep->started_list, list) dwc3_gadget_move_cancelled_request(req); /* If ep isn't started, then there's no end transfer pending */ if (!(dep->flags & DWC3_EP_END_TRANSFER_PENDING)) dwc3_gadget_ep_cleanup_cancelled_requests(dep); return ret; } Loading Loading @@ -1679,27 +1687,33 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, } trace_dwc3_ep_dequeue(req); dbg_ep_dequeue(dep->number, req); spin_lock_irqsave(&dwc->lock, flags); list_for_each_entry(r, &dep->cancelled_list, list) { if (r == req) goto out0; if (r == req) { dbg_log_string("req:%pK found cancelled list", &req->request); goto out; } } list_for_each_entry(r, &dep->pending_list, list) { if (r == req) break; if (r == req) { dbg_log_string("req:%pK found pending list", &req->request); dwc3_gadget_giveback(dep, req, -ECONNRESET); goto out; } } if (r != req) { list_for_each_entry(r, &dep->started_list, list) { if (r == req) break; } if (r == req) { struct dwc3_request *t; dbg_log_string("req:%pK found started list", &req->request); /* wait until it is processed */ dwc3_stop_active_transfer(dep, true, true); Loading @@ -1710,18 +1724,14 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, list_for_each_entry_safe(r, t, &dep->started_list, list) dwc3_gadget_move_cancelled_request(r); goto out0; goto out; } } dev_err(dwc->dev, "request %pK was not queued to %s\n", request, ep->name); ret = -EINVAL; goto out0; } dbg_ep_dequeue(dep->number, req); dwc3_gadget_giveback(dep, req, -ECONNRESET); out0: out: spin_unlock_irqrestore(&dwc->lock, flags); return ret; Loading Loading @@ -2828,14 +2838,7 @@ static int dwc3_gadget_ep_reclaim_trb_linear(struct dwc3_ep *dep, static bool dwc3_gadget_ep_request_completed(struct dwc3_request *req) { /* * For OUT direction, host may send less than the setup * length. Return true for all OUT requests. */ if (!req->direction) return true; return req->request.actual == req->request.length; return req->num_pending_sgs == 0; } static int dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep, Loading Loading @@ -2870,8 +2873,7 @@ static int dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep, req->request.actual = req->request.length - req->remaining; if (!dwc3_gadget_ep_request_completed(req) || req->num_pending_sgs) { if (!dwc3_gadget_ep_request_completed(req)) { __dwc3_gadget_kick_transfer(dep); goto out; } Loading drivers/usb/dwc3/trace.h +7 −2 Original line number Diff line number Diff line Loading @@ -227,6 +227,8 @@ DECLARE_EVENT_CLASS(dwc3_log_trb, __field(u32, size) __field(u32, ctrl) __field(u32, type) __field(u32, enqueue) __field(u32, dequeue) ), TP_fast_assign( __assign_str(name, dep->name); Loading @@ -236,9 +238,12 @@ DECLARE_EVENT_CLASS(dwc3_log_trb, __entry->size = trb->size; __entry->ctrl = trb->ctrl; __entry->type = usb_endpoint_type(dep->endpoint.desc); __entry->enqueue = dep->trb_enqueue; __entry->dequeue = dep->trb_dequeue; ), TP_printk("%s: trb %p buf %08x%08x size %s%d ctrl %08x (%c%c%c%c:%c%c:%s)", __get_str(name), __entry->trb, __entry->bph, __entry->bpl, TP_printk("%s: trb %p (E%d:D%d) buf %08x%08x size %s%d ctrl %08x (%c%c%c%c:%c%c:%s)", __get_str(name), __entry->trb, __entry->enqueue, __entry->dequeue, __entry->bph, __entry->bpl, ({char *s; int pcm = ((__entry->size >> 24) & 3) + 1; switch (__entry->type) { Loading Loading
drivers/usb/dwc3/gadget.c +38 −36 Original line number Diff line number Diff line Loading @@ -1339,6 +1339,8 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep) } } static void dwc3_gadget_ep_cleanup_cancelled_requests(struct dwc3_ep *dep); static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep) { struct dwc3_gadget_ep_cmd_params params; Loading Loading @@ -1380,14 +1382,20 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep) ret = dwc3_send_gadget_ep_cmd(dep, cmd, ¶ms); if (ret < 0) { /* * FIXME we need to iterate over the list of requests * here and stop, unmap, free and del each of the linked * requests instead of what we do now. */ if (req->trb) memset(req->trb, 0, sizeof(struct dwc3_trb)); dwc3_gadget_del_and_unmap_request(dep, req, ret); struct dwc3_request *tmp; if (ret == -EAGAIN) return ret; dwc3_stop_active_transfer(dep, true, true); list_for_each_entry_safe(req, tmp, &dep->started_list, list) dwc3_gadget_move_cancelled_request(req); /* If ep isn't started, then there's no end transfer pending */ if (!(dep->flags & DWC3_EP_END_TRANSFER_PENDING)) dwc3_gadget_ep_cleanup_cancelled_requests(dep); return ret; } Loading Loading @@ -1679,27 +1687,33 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, } trace_dwc3_ep_dequeue(req); dbg_ep_dequeue(dep->number, req); spin_lock_irqsave(&dwc->lock, flags); list_for_each_entry(r, &dep->cancelled_list, list) { if (r == req) goto out0; if (r == req) { dbg_log_string("req:%pK found cancelled list", &req->request); goto out; } } list_for_each_entry(r, &dep->pending_list, list) { if (r == req) break; if (r == req) { dbg_log_string("req:%pK found pending list", &req->request); dwc3_gadget_giveback(dep, req, -ECONNRESET); goto out; } } if (r != req) { list_for_each_entry(r, &dep->started_list, list) { if (r == req) break; } if (r == req) { struct dwc3_request *t; dbg_log_string("req:%pK found started list", &req->request); /* wait until it is processed */ dwc3_stop_active_transfer(dep, true, true); Loading @@ -1710,18 +1724,14 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, list_for_each_entry_safe(r, t, &dep->started_list, list) dwc3_gadget_move_cancelled_request(r); goto out0; goto out; } } dev_err(dwc->dev, "request %pK was not queued to %s\n", request, ep->name); ret = -EINVAL; goto out0; } dbg_ep_dequeue(dep->number, req); dwc3_gadget_giveback(dep, req, -ECONNRESET); out0: out: spin_unlock_irqrestore(&dwc->lock, flags); return ret; Loading Loading @@ -2828,14 +2838,7 @@ static int dwc3_gadget_ep_reclaim_trb_linear(struct dwc3_ep *dep, static bool dwc3_gadget_ep_request_completed(struct dwc3_request *req) { /* * For OUT direction, host may send less than the setup * length. Return true for all OUT requests. */ if (!req->direction) return true; return req->request.actual == req->request.length; return req->num_pending_sgs == 0; } static int dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep, Loading Loading @@ -2870,8 +2873,7 @@ static int dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep, req->request.actual = req->request.length - req->remaining; if (!dwc3_gadget_ep_request_completed(req) || req->num_pending_sgs) { if (!dwc3_gadget_ep_request_completed(req)) { __dwc3_gadget_kick_transfer(dep); goto out; } Loading
drivers/usb/dwc3/trace.h +7 −2 Original line number Diff line number Diff line Loading @@ -227,6 +227,8 @@ DECLARE_EVENT_CLASS(dwc3_log_trb, __field(u32, size) __field(u32, ctrl) __field(u32, type) __field(u32, enqueue) __field(u32, dequeue) ), TP_fast_assign( __assign_str(name, dep->name); Loading @@ -236,9 +238,12 @@ DECLARE_EVENT_CLASS(dwc3_log_trb, __entry->size = trb->size; __entry->ctrl = trb->ctrl; __entry->type = usb_endpoint_type(dep->endpoint.desc); __entry->enqueue = dep->trb_enqueue; __entry->dequeue = dep->trb_dequeue; ), TP_printk("%s: trb %p buf %08x%08x size %s%d ctrl %08x (%c%c%c%c:%c%c:%s)", __get_str(name), __entry->trb, __entry->bph, __entry->bpl, TP_printk("%s: trb %p (E%d:D%d) buf %08x%08x size %s%d ctrl %08x (%c%c%c%c:%c%c:%s)", __get_str(name), __entry->trb, __entry->enqueue, __entry->dequeue, __entry->bph, __entry->bpl, ({char *s; int pcm = ((__entry->size >> 24) & 3) + 1; switch (__entry->type) { Loading