Skip to content

Commit 5a29db2

Browse files
committed
add check for edpt_xfer() with halted, also reset data toggle when clear stall
1 parent 4deea87 commit 5a29db2

File tree

1 file changed

+12
-1
lines changed

1 file changed

+12
-1
lines changed

src/portable/ehci/ehci.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,13 +443,21 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
443443
ehci_qtd_t* qtd;
444444

445445
if (epnum == 0) {
446+
// Control endpoint never be stalled. Skip reset Data Toggle since it is fixed per stage
447+
if (qhd->qtd_overlay.halted) {
448+
qhd->qtd_overlay.halted = false;
449+
}
450+
446451
qtd = qtd_control(dev_addr);
447452
qtd_init(qtd, buffer, buflen);
448453

449454
// first data toggle is always 1 (data & setup stage)
450455
qtd->data_toggle = 1;
451456
qtd->pid = dir ? EHCI_PID_IN : EHCI_PID_OUT;
452457
} else {
458+
// skip if endpoint is halted
459+
TU_VERIFY(!qhd->qtd_overlay.halted);
460+
453461
qtd = qtd_find_free();
454462
TU_ASSERT(qtd);
455463

@@ -506,8 +514,9 @@ bool hcd_edpt_clear_stall(uint8_t daddr, uint8_t ep_addr)
506514
{
507515
ehci_qhd_t *qhd = qhd_get_from_addr(daddr, ep_addr);
508516
qhd->qtd_overlay.halted = 0;
517+
qhd->qtd_overlay.data_toggle = 0;
509518
hcd_dcache_clean_invalidate(qhd, sizeof(ehci_qhd_t));
510-
// TODO reset data toggle ?
519+
511520
return true;
512521
}
513522

@@ -881,8 +890,10 @@ static void qhd_remove_qtd(ehci_qhd_t *qhd) {
881890

882891
qhd->attached_qtd = NULL;
883892
qhd->attached_buffer = 0;
893+
hcd_dcache_clean(qhd, sizeof(ehci_qhd_t));
884894

885895
qtd->used = 0; // free QTD
896+
hcd_dcache_clean(qtd, sizeof(ehci_qtd_t));
886897
}
887898

888899
//--------------------------------------------------------------------+

0 commit comments

Comments
 (0)