Hi,

I suspect I've found the issue.

Can you try to apply the attached patch by hand?

It appears one of my optimisations have broken something.

--HPS
--- src/sys/dev/usb/controller/ehci.c   2010-04-22 23:36:13.000000000 0000
+++ src/sys/dev/usb/controller/ehci.c   2010-04-22 23:36:13.000000000 0000
@@ -1352,22 +1352,32 @@
                }
        } else if (methods == &ehci_device_isoc_hs_methods) {
                ehci_itd_t *td;
-               uint8_t n = (xfer->nframes & 7);
 
                /* isochronous high speed transfer */
 
                /* check last transfer */
                td = xfer->td_transfer_last;
                usb_pc_cpu_invalidate(td->page_cache);
-               if (n == 0)
-                       status = td->itd_status[7];
-               else
-                       status = td->itd_status[n-1];
+               status = td->itd_status[0];
+               status |= td->itd_status[1];
+               status |= td->itd_status[2];
+               status |= td->itd_status[3];
+               status |= td->itd_status[4];
+               status |= td->itd_status[5];
+               status |= td->itd_status[6];
+               status |= td->itd_status[7];
 
                /* also check first transfer */
                td = xfer->td_transfer_first;
                usb_pc_cpu_invalidate(td->page_cache);
                status |= td->itd_status[0];
+               status |= td->itd_status[1];
+               status |= td->itd_status[2];
+               status |= td->itd_status[3];
+               status |= td->itd_status[4];
+               status |= td->itd_status[5];
+               status |= td->itd_status[6];
+               status |= td->itd_status[7];
 
                /* if no transactions are active we continue */
                if (!(status & htohc32(sc, EHCI_ITD_ACTIVE))) {
@@ -2799,14 +2809,15 @@
        uint8_t x;
        uint8_t td_no;
        uint8_t page_no;
+       uint8_t shift = usbd_xfer_get_fps_shift(xfer);
 
 #ifdef USB_DEBUG
        uint8_t once = 1;
 
 #endif
 
-       DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
-           xfer, xfer->endpoint->isoc_next, xfer->nframes);
+       DPRINTFN(6, "xfer=%p next=%d nframes=%d shift=%d\n",
+           xfer, xfer->endpoint->isoc_next, xfer->nframes, (int)shift);
 
        /* get the current frame index */
 
@@ -2820,7 +2831,7 @@
            (EHCI_VIRTUAL_FRAMELIST_COUNT - 1);
 
        if ((xfer->endpoint->is_synced == 0) ||
-           (buf_offset < ((xfer->nframes + 7) / 8))) {
+           (buf_offset < (((xfer->nframes << shift) + 7) / 8))) {
                /*
                 * If there is data underflow or the pipe queue is empty we
                 * schedule the transfer a few frames ahead of the current
@@ -2844,7 +2855,7 @@
         */
        xfer->isoc_time_complete =
            usb_isoc_time_expand(&sc->sc_bus, nframes) + buf_offset +
-           ((xfer->nframes + 7) / 8);
+           (((xfer->nframes << shift) + 7) / 8);
 
        /* get the real number of frames */
 
--- src/sys/dev/usb/usb_hub.c   2010-05-05 19:58:31.000000000 0000
+++ src/sys/dev/usb/usb_hub.c   2010-05-05 19:58:31.000000000 0000
@@ -1230,6 +1230,11 @@
        if (udev->flags.usb_mode != USB_MODE_HOST)
                return;         /* not supported */
 
+       if (xfer->flags_int.bandwidth_reclaimed != 0)
+               return;         /* bandwidth already allocated */
+
+       xfer->flags_int.bandwidth_reclaimed = 1;
+
        xfer->endpoint->refcount_bw++;
        if (xfer->endpoint->refcount_bw != 1)
                return;         /* already allocated */
@@ -1310,6 +1315,11 @@
        if (udev->flags.usb_mode != USB_MODE_HOST)
                return;         /* not supported */
 
+       if (xfer->flags_int.bandwidth_reclaimed == 0)
+               return;         /* bandwidth already freed */
+
+       xfer->flags_int.bandwidth_reclaimed = 0;
+
        xfer->endpoint->refcount_bw--;
        if (xfer->endpoint->refcount_bw != 0)
                return;         /* still allocated */
_______________________________________________
freebsd-usb@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "freebsd-usb-unsubscr...@freebsd.org"

Reply via email to