Loading drivers/usb/dwc3/gadget.c +43 −0 Original line number Diff line number Diff line Loading @@ -1436,6 +1436,48 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, if (r == req) { /* wait until it is processed */ dwc3_stop_active_transfer(dwc, dep->number, true); /* * If request was already started, this means we had to * stop the transfer. With that we also need to ignore * all TRBs used by the request, however TRBs can only * be modified after completion of END_TRANSFER * command. So what we do here is that we wait for * END_TRANSFER completion and only after that, we jump * over TRBs by clearing HWO and incrementing dequeue * pointer. * * Note that we have 2 possible types of transfers here: * * i) Linear buffer request * ii) SG-list based request * * SG-list based requests will have r->num_pending_sgs * set to a valid number (> 0). Linear requests, * normally use a single TRB. * * All of these cases need to be taken into * consideration so we don't mess up our TRB ring * pointers. */ if (!r->trb) goto out1; if (r->num_pending_sgs) { struct dwc3_trb *trb; int i = 0; for (i = 0; i < r->num_pending_sgs; i++) { trb = r->trb + i; trb->ctrl &= ~DWC3_TRB_CTRL_HWO; dwc3_ep_inc_deq(dep); } } else { struct dwc3_trb *trb = r->trb; trb->ctrl &= ~DWC3_TRB_CTRL_HWO; dwc3_ep_inc_deq(dep); } goto out1; } dev_err(dwc->dev, "request %pK was not queued to %s\n", Loading @@ -1447,6 +1489,7 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, out1: dbg_event(dep->number, "DEQUEUE", 0); /* giveback the request */ dep->queued_requests--; dwc3_gadget_giveback(dep, req, -ECONNRESET); out0: Loading Loading
drivers/usb/dwc3/gadget.c +43 −0 Original line number Diff line number Diff line Loading @@ -1436,6 +1436,48 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, if (r == req) { /* wait until it is processed */ dwc3_stop_active_transfer(dwc, dep->number, true); /* * If request was already started, this means we had to * stop the transfer. With that we also need to ignore * all TRBs used by the request, however TRBs can only * be modified after completion of END_TRANSFER * command. So what we do here is that we wait for * END_TRANSFER completion and only after that, we jump * over TRBs by clearing HWO and incrementing dequeue * pointer. * * Note that we have 2 possible types of transfers here: * * i) Linear buffer request * ii) SG-list based request * * SG-list based requests will have r->num_pending_sgs * set to a valid number (> 0). Linear requests, * normally use a single TRB. * * All of these cases need to be taken into * consideration so we don't mess up our TRB ring * pointers. */ if (!r->trb) goto out1; if (r->num_pending_sgs) { struct dwc3_trb *trb; int i = 0; for (i = 0; i < r->num_pending_sgs; i++) { trb = r->trb + i; trb->ctrl &= ~DWC3_TRB_CTRL_HWO; dwc3_ep_inc_deq(dep); } } else { struct dwc3_trb *trb = r->trb; trb->ctrl &= ~DWC3_TRB_CTRL_HWO; dwc3_ep_inc_deq(dep); } goto out1; } dev_err(dwc->dev, "request %pK was not queued to %s\n", Loading @@ -1447,6 +1489,7 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, out1: dbg_event(dep->number, "DEQUEUE", 0); /* giveback the request */ dep->queued_requests--; dwc3_gadget_giveback(dep, req, -ECONNRESET); out0: Loading