When an isochronous transfer of n frames is scheduled, the last frame
i.e. frame number (n - 1) is set to generate an interrupt.

To figure out which transfer generated the interrupt, the interrupt
handler iterates over all outstanding transfers and checks if the last
TD of the transfer is active. If it's not active, then the transter is
done and the completion call-back is invoked.

Except that for isochronous transfers the interrupt handler checks the
n-th TD insted of the last one. In turn, the transfer appears as
active and the completion call-back is not called (yet). It will be
called on the interrupt of the next transfer (if any).


Index: uhci.c
RCS file: /cvs/src/sys/dev/usb/uhci.c,v
retrieving revision 1.144
diff -u -p -u -p -r1.144 uhci.c
--- uhci.c      16 Nov 2018 11:57:29 -0000      1.144
+++ uhci.c      7 Feb 2019 05:21:29 -0000
@@ -2188,7 +2188,7 @@ uhci_device_isoc_start(struct usbd_xfer 
        /* Find the last TD */
-       i = ux->curframe + xfer->nframes;
+       i = ux->curframe + (xfer->nframes - 1);
        if (i >= UHCI_VFRAMELIST_COUNT)
                i -= UHCI_VFRAMELIST_COUNT;
        end = upipe->u.iso.stds[i];

Reply via email to