Skip to content

Commit cfe2329

Browse files
Bin Yangscorpiochang
authored andcommitted
USB: fix handle NAK for IN/OUT SSPLIT/CSPLIT transfers
IN SSPLIT/CSPLIT transfers, NAK packet will cause DWC_OTG ctrl to generate lots of SSPLIT/CSPLIT transfer interrupts, and seriously affect the performance of the system. So need to stop queue transactions after receive SSPLIT/CSPLIT NAK. Change-Id: Ie1b1e9e6971c6546a4239a10b06fba7360978ce0 Signed-off-by: Wu Liang feng <wulf@rock-chips.com> Reviewed-on: https://tp-biosrd-v02/gerrit/80149 Reviewed-by: Scorpio Chang(張志賢) <Scorpio_Chang@asus.com> Tested-by: Scorpio Chang(張志賢) <Scorpio_Chang@asus.com>
1 parent d245442 commit cfe2329

File tree

3 files changed

+17
-5
lines changed

3 files changed

+17
-5
lines changed

drivers/usb/dwc2/hcd.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2700,6 +2700,8 @@ static int dwc2_assign_and_init_hc(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
27002700
chan->xfer_len = urb->length - urb->actual_length;
27012701
chan->xfer_count = 0;
27022702

2703+
chan->csplit_nak = 0;
2704+
27032705
/* Set the split attributes if required */
27042706
if (qh->do_split)
27052707
dwc2_hc_init_split(hsotg, chan, qtd, urb);

drivers/usb/dwc2/hcd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ struct dwc2_host_chan {
142142
u8 halt_pending;
143143
u8 do_split;
144144
u8 complete_split;
145+
u8 csplit_nak;
145146
u8 hub_addr;
146147
u8 hub_port;
147148
u8 xact_pos;

drivers/usb/dwc2/hcd_intr.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,7 @@ static void dwc2_release_channel(struct dwc2_hsotg *hsotg,
691691
enum dwc2_transaction_type tr_type;
692692
u32 haintmsk;
693693
int free_qtd = 0;
694+
int continue_trans = 1;
694695

695696
if (dbg_hc(chan))
696697
dev_vdbg(hsotg->dev, " %s: channel %d, halt_status %d\n",
@@ -719,6 +720,7 @@ static void dwc2_release_channel(struct dwc2_hsotg *hsotg,
719720
* deactivated. Don't want to do anything except release the
720721
* host channel and try to queue more transfers.
721722
*/
723+
continue_trans = 0;
722724
goto cleanup;
723725
case DWC2_HC_XFER_PERIODIC_INCOMPLETE:
724726
dev_vdbg(hsotg->dev, " Complete URB with I/O error\n");
@@ -730,6 +732,10 @@ static void dwc2_release_channel(struct dwc2_hsotg *hsotg,
730732
break;
731733
}
732734

735+
if (chan->csplit_nak) {
736+
continue_trans = 0;
737+
chan->csplit_nak = 0;
738+
}
733739
dwc2_deactivate_qh(hsotg, chan->qh, free_qtd);
734740

735741
cleanup:
@@ -767,11 +773,13 @@ static void dwc2_release_channel(struct dwc2_hsotg *hsotg,
767773
dwc2_writel(haintmsk, hsotg->regs + HAINTMSK);
768774

769775
/* Try to queue more transfers now that there's a free channel */
770-
tr_type = dwc2_hcd_select_transactions(hsotg);
771-
if (tr_type != DWC2_TRANSACTION_NONE)
772-
dwc2_hcd_queue_transactions(hsotg, tr_type);
773-
}
774-
776+
if (continue_trans) {
777+
tr_type = dwc2_hcd_select_transactions(hsotg);
778+
if (tr_type != DWC2_TRANSACTION_NONE)
779+
dwc2_hcd_queue_transactions(hsotg, tr_type);
780+
}
781+
}
782+
775783
/*
776784
* Halts a host channel. If the channel cannot be halted immediately because
777785
* the request queue is full, this function ensures that the FIFO empty
@@ -1199,6 +1207,7 @@ static void dwc2_hc_nak_intr(struct dwc2_hsotg *hsotg,
11991207
if (chan->do_split) {
12001208
if (chan->complete_split)
12011209
qtd->error_count = 0;
1210+
chan->csplit_nak = 1;
12021211
qtd->complete_split = 0;
12031212
dwc2_halt_channel(hsotg, chan, qtd, DWC2_HC_XFER_NAK);
12041213
goto handle_nak_done;

0 commit comments

Comments
 (0)