--- sys/dev/usb/xhcivar.h.orig	2025-08-03 06:55:02.895616503 +0000
+++ sys/dev/usb/xhcivar.h	2025-09-27 21:22:57.522766454 +0000
@@ -68,6 +68,8 @@ struct xhci_ring {
 	kmutex_t xr_lock;
 	struct xhci_trb * xr_trb;
 	void **xr_cookies;
+	uint32_t *xr_trbflags;
+#define XHCI_TRBFLAG_LAST	__BIT(0)	/* last TD of transfer */
 	u_int xr_ntrb;			/* number of elements for above */
 	u_int xr_ep;			/* enqueue pointer */
 	u_int xr_cs;			/* cycle state */
--- sys/dev/usb/xhci.c.orig	2025-08-24 09:59:43.231022329 +0000
+++ sys/dev/usb/xhci.c	2025-09-27 06:08:53.806623591 +0000
@@ -2576,6 +2576,20 @@ xhci_event_transfer(struct xhci_softc * 
 			return;
 	}
 
+	/*
+	 * If this event is not from last of zero-length transfer,
+	 * suppress completion of first event.
+	 */
+	if (xfertype == UE_BULK &&
+	    err == USBD_NORMAL_COMPLETION &&
+	    (xfer->ux_flags & USBD_FORCE_SHORT_XFER) &&
+	    (xr->xr_trbflags[idx] & XHCI_TRBFLAG_LAST) == 0) {
+		DPRINTFN(100, "short xfer %#jx: suppress complete status "
+		    "%ju pipe %#jx", (uintptr_t)xfer, xfer->ux_status,
+		    (uintptr_t)xfer->ux_pipe, 0);
+		return;
+	}
+
 	if ((trb_3 & XHCI_TRB_3_ED_BIT) == 0 ||
 	    (trb_0 & 0x3) == 0x0) {
 		/*
@@ -3075,6 +3089,8 @@ xhci_ring_init(struct xhci_softc * const
 	}
 	mutex_init(&xr->xr_lock, MUTEX_DEFAULT, IPL_SOFTUSB);
 	xr->xr_cookies = kmem_zalloc(sizeof(*xr->xr_cookies) * ntrb, KM_SLEEP);
+	xr->xr_trbflags = kmem_zalloc(sizeof(*xr->xr_trbflags) * ntrb,
+	    KM_SLEEP);
 	xr->xr_trb = xhci_ring_trbv(xr, 0);
 	xr->xr_ntrb = ntrb;
 	xr->is_halted = false;
@@ -3092,6 +3108,8 @@ xhci_ring_free(struct xhci_softc * const
 
 	usb_freemem(&(*xr)->xr_dma);
 	mutex_destroy(&(*xr)->xr_lock);
+	kmem_free((*xr)->xr_trbflags,
+	    sizeof(*(*xr)->xr_trbflags) * (*xr)->xr_ntrb);
 	kmem_free((*xr)->xr_cookies,
 	    sizeof(*(*xr)->xr_cookies) * (*xr)->xr_ntrb);
 	kmem_free(*xr, sizeof(struct xhci_ring));
@@ -3115,6 +3133,8 @@ xhci_ring_put(struct xhci_softc * const 
 
 	KASSERTMSG(ntrbs < xr->xr_ntrb, "ntrbs %zu, xr->xr_ntrb %u",
 	    ntrbs, xr->xr_ntrb);
+	if (ntrbs == 0)
+		return;
 	for (i = 0; i < ntrbs; i++) {
 		DPRINTFN(12, "xr %#jx trbs %#jx num %ju", (uintptr_t)xr,
 		    (uintptr_t)trbs, i, 0);
@@ -3148,6 +3168,10 @@ xhci_ring_put(struct xhci_softc * const 
 		u_int oldri = ri;
 		u_int oldcs = cs;
 
+		/* LAST flag is set on only last TRB */
+		xr->xr_trbflags[ri] &= ~XHCI_TRBFLAG_LAST;
+		if (i == ntrbs - 1)
+			xr->xr_trbflags[ri] |= XHCI_TRBFLAG_LAST;
 		if (ri >= (xr->xr_ntrb - 1)) {
 			/* Put Link TD at the end of ring */
 			parameter = xhci_ring_trbp(xr, 0);
