84 lines
2.6 KiB
Diff
84 lines
2.6 KiB
Diff
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
|
|
index 7b6eb0ad513b..96b6935dc0d7 100644
|
|
--- a/drivers/usb/dwc2/hcd.c
|
|
+++ b/drivers/usb/dwc2/hcd.c
|
|
@@ -2748,6 +2748,8 @@ static int dwc2_assign_and_init_hc(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
|
|
chan->xfer_len = urb->length - urb->actual_length;
|
|
chan->xfer_count = 0;
|
|
|
|
+ chan->csplit_nak = 0;
|
|
+
|
|
/* Set the split attributes if required */
|
|
if (qh->do_split)
|
|
dwc2_hc_init_split(hsotg, chan, qtd, urb);
|
|
diff --git a/drivers/usb/dwc2/hcd.h b/drivers/usb/dwc2/hcd.h
|
|
index 78e9e01051b5..e54f1351225b 100644
|
|
--- a/drivers/usb/dwc2/hcd.h
|
|
+++ b/drivers/usb/dwc2/hcd.h
|
|
@@ -143,6 +143,7 @@ struct dwc2_host_chan {
|
|
u8 halt_pending;
|
|
u8 do_split;
|
|
u8 complete_split;
|
|
+ u8 csplit_nak;
|
|
u8 hub_addr;
|
|
u8 hub_port;
|
|
u8 xact_pos;
|
|
diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c
|
|
index 916d991b96b8..551cfacd2252 100644
|
|
--- a/drivers/usb/dwc2/hcd_intr.c
|
|
+++ b/drivers/usb/dwc2/hcd_intr.c
|
|
@@ -691,6 +691,7 @@ static void dwc2_release_channel(struct dwc2_hsotg *hsotg,
|
|
enum dwc2_transaction_type tr_type;
|
|
u32 haintmsk;
|
|
int free_qtd = 0;
|
|
+ int continue_trans = 1;
|
|
|
|
if (dbg_hc(chan))
|
|
dev_vdbg(hsotg->dev, " %s: channel %d, halt_status %d\n",
|
|
@@ -719,6 +720,7 @@ static void dwc2_release_channel(struct dwc2_hsotg *hsotg,
|
|
* deactivated. Don't want to do anything except release the
|
|
* host channel and try to queue more transfers.
|
|
*/
|
|
+ continue_trans = 0;
|
|
goto cleanup;
|
|
case DWC2_HC_XFER_PERIODIC_INCOMPLETE:
|
|
dev_vdbg(hsotg->dev, " Complete URB with I/O error\n");
|
|
@@ -730,6 +732,11 @@ static void dwc2_release_channel(struct dwc2_hsotg *hsotg,
|
|
break;
|
|
}
|
|
|
|
+ if (chan->csplit_nak) {
|
|
+ continue_trans = 0;
|
|
+ chan->csplit_nak = 0;
|
|
+ }
|
|
+
|
|
dwc2_deactivate_qh(hsotg, chan->qh, free_qtd);
|
|
|
|
cleanup:
|
|
@@ -767,9 +774,11 @@ static void dwc2_release_channel(struct dwc2_hsotg *hsotg,
|
|
dwc2_writel(haintmsk, hsotg->regs + HAINTMSK);
|
|
|
|
/* Try to queue more transfers now that there's a free channel */
|
|
- tr_type = dwc2_hcd_select_transactions(hsotg);
|
|
- if (tr_type != DWC2_TRANSACTION_NONE)
|
|
- dwc2_hcd_queue_transactions(hsotg, tr_type);
|
|
+ if (continue_trans) {
|
|
+ tr_type = dwc2_hcd_select_transactions(hsotg);
|
|
+ if (tr_type != DWC2_TRANSACTION_NONE)
|
|
+ dwc2_hcd_queue_transactions(hsotg, tr_type);
|
|
+ }
|
|
}
|
|
|
|
/*
|
|
@@ -1205,6 +1214,7 @@ static void dwc2_hc_nak_intr(struct dwc2_hsotg *hsotg,
|
|
if (chan->do_split) {
|
|
if (chan->complete_split)
|
|
qtd->error_count = 0;
|
|
+ chan->csplit_nak = 1;
|
|
qtd->complete_split = 0;
|
|
dwc2_halt_channel(hsotg, chan, qtd, DWC2_HC_XFER_NAK);
|
|
goto handle_nak_done;
|
|
--
|
|
2.11.0
|
|
|