diff --git a/src/host/usbh.c b/src/host/usbh.c index 7cdcbda5ea..5423df6693 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -738,19 +738,27 @@ bool tuh_edpt_abort_xfer(uint8_t daddr, uint8_t ep_addr) { usbh_device_t* dev = get_device(daddr); TU_VERIFY(dev); + TU_LOG_USBH("[%u] Aborted transfer on EP %02X\r\n", daddr, ep_addr); + uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); - // skip if not busy - TU_VERIFY(dev->ep_status[epnum][dir].busy); - - bool const ret = hcd_edpt_abort_xfer(dev->rhport, daddr, ep_addr); - if (ret) { - // mark as ready if transfer is aborted + if ( epnum == 0 ) { + // control transfer: only 1 control at a time, check if we are aborting the current one + TU_VERIFY(daddr == _ctrl_xfer.daddr && _ctrl_xfer.stage != CONTROL_STAGE_IDLE); + TU_VERIFY(hcd_edpt_abort_xfer(dev->rhport, daddr, ep_addr)); + // reset control transfer state to idle + _set_control_xfer_stage(CONTROL_STAGE_IDLE); + } else { + // non-control skip if not busy + TU_VERIFY(dev->ep_status[epnum][dir].busy); + TU_VERIFY(hcd_edpt_abort_xfer(dev->rhport, daddr, ep_addr)); + // mark as ready and release endpoint if transfer is aborted dev->ep_status[epnum][dir].busy = false; + usbh_edpt_release(daddr, ep_addr); } - return ret; + return true; } //--------------------------------------------------------------------+ diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c index 79811985c6..c93c33fc03 100644 --- a/src/portable/ehci/ehci.c +++ b/src/portable/ehci/ehci.c @@ -578,7 +578,9 @@ void qhd_xfer_complete_isr(ehci_qhd_t * qhd) { if ( qtd_overlay->halted ) { if (qtd_overlay->xact_err || qtd_overlay->err_count == 0 || qtd_overlay->buffer_err || qtd_overlay->babble_err) { // Error count = 0 often occurs when device disconnected, or other bus-related error + // clear halted bit if not caused by STALL to allow more transfer xfer_result = XFER_RESULT_FAILED; + qtd_overlay->halted = false; TU_LOG3(" QHD xfer err count: %d\n", qtd_overlay->err_count); // TU_BREAKPOINT(); // TODO skip unplugged device }else {