From 6c9536afbad975f141e164a680ba15842b48b905 Mon Sep 17 00:00:00 2001 From: Tormod Volden Date: Sat, 15 Nov 2025 19:34:08 +0100 Subject: [PATCH] uhci: Split large bulk out transfers Signed-off-by: Tormod Volden --- system/uhci.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/system/uhci.c b/system/uhci.c index 3b5c8e9..c3e3f46 100644 --- a/system/uhci.c +++ b/system/uhci.c @@ -387,11 +387,14 @@ static bool out_data_request(const usb_hcd_t *hcd, const usb_ep_t *ep, const usb build_uhci_td(&ws->td[pkt_num], ep, UHCI_TD_PID_OUT, UHCI_TD_DT(pkt_num & 1), UHCI_TD_IOC_N, buffer, length); pkt_num++; build_uhci_td(&ws->td[pkt_num], ep, UHCI_TD_PID_IN, UHCI_TD_DT(1), UHCI_TD_IOC_Y, 0, 0); } else { - // toggle must be preserved across transactions or not? - // IOC or not? - // TODO split long packets as for control out? + // FIXME store toggle per endpoint static int bulk_pkt_num; - build_uhci_td(&ws->td[pkt_num], ep, UHCI_TD_PID_OUT, UHCI_TD_DT(bulk_pkt_num++ & 1), UHCI_TD_IOC_Y, buffer, length); pkt_num++; + while (length > packet_size) { + build_uhci_td(&ws->td[pkt_num], ep, UHCI_TD_PID_OUT, UHCI_TD_DT(bulk_pkt_num++ & 1), UHCI_TD_IOC_N, buffer, packet_size); pkt_num++; + buffer = (uint8_t *)buffer + packet_size; + length -= packet_size; + } + build_uhci_td(&ws->td[pkt_num], ep, UHCI_TD_PID_OUT, UHCI_TD_DT(bulk_pkt_num++ & 1), UHCI_TD_IOC_Y, buffer, length); } write32(&ws->qh[0].qe_link_ptr, (uintptr_t)(&ws->td[0]) | UHCI_LP_TYPE_TD); return wait_for_uhci_done(ws);