Commit c503b381 authored by Gregory Herrero's avatar Gregory Herrero Committed by Felipe Balbi

usb: dwc2: host: rework isochronous halt path

When a channel is halted because of urb dequeue during transfer
completion, no other qtds must be scheduled until halt is done.
Moreover, all in progress qtds must be given back.
Acked-by: default avatarJohn Youn <johnyoun@synopsys.com>
Signed-off-by: default avatarGregory Herrero <gregory.herrero@intel.com>
Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
parent dde4c1bf
......@@ -1161,6 +1161,21 @@ void dwc2_hcd_complete_xfer_ddma(struct dwc2_hsotg *hsotg,
/* Release the channel if halted or session completed */
if (halt_status != DWC2_HC_XFER_COMPLETE ||
list_empty(&qh->qtd_list)) {
struct dwc2_qtd *qtd, *qtd_tmp;
/*
* Kill all remainings QTDs since channel has been
* halted.
*/
list_for_each_entry_safe(qtd, qtd_tmp,
&qh->qtd_list,
qtd_list_entry) {
dwc2_host_complete(hsotg, qtd,
-ECONNRESET);
dwc2_hcd_qtd_unlink_and_free(hsotg,
qtd, qh);
}
/* Halt the channel if session completed */
if (halt_status == DWC2_HC_XFER_COMPLETE)
dwc2_hc_halt(hsotg, chan, halt_status);
......@@ -1170,7 +1185,12 @@ void dwc2_hcd_complete_xfer_ddma(struct dwc2_hsotg *hsotg,
/* Keep in assigned schedule to continue transfer */
list_move(&qh->qh_list_entry,
&hsotg->periodic_sched_assigned);
continue_isoc_xfer = 1;
/*
* If channel has been halted during giveback of urb
* then prevent any new scheduling.
*/
if (!chan->halt_status)
continue_isoc_xfer = 1;
}
/*
* Todo: Consider the case when period exceeds FrameList size.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment