This patch fixes another toggle bug and reverts the previous bogus
patch which caused compile warnings.

It also adds a quick comment explaining the criteria.

JE

--- linux-2.4.18-pre9.orig/drivers/usb/uhci.c   Tue Feb 19 21:57:46 2002
+++ linux-2.4.18-pre9/drivers/usb/uhci.c        Tue Feb 19 22:04:54 2002
@@ -1669,6 +1669,7 @@
 {
        struct list_head *head, *tmp;
        struct urb_priv *urbp = urb->hcpriv;
+       int prevactive = 1;
 
        /* We can get called when urbp allocation fails, so check */
        if (!urbp)
@@ -1676,6 +1677,19 @@
 
        uhci_dec_fsbr(uhci, urb);       /* Safe since it checks */
 
+       /*
+        * Now we need to find out what the last successful toggle was
+        * so we can update the local data toggle for the next transfer
+        *
+        * There's 3 way's the last successful completed TD is found:
+        *
+        * 1) The TD is NOT active and the actual length < expected length
+        * 2) The TD is NOT active and it's the last TD in the chain
+        * 3) The TD is active and the previous TD is NOT active
+        *
+        * Control and Isochronous ignore the toggle, so this is safe
+        * for all types
+        */
        head = &urbp->td_list;
        tmp = head->next;
        while (tmp != head) {
@@ -1683,15 +1697,18 @@
 
                tmp = tmp->next;
 
-               /* Control and Isochronous ignore the toggle, so this */
-               /* is safe for all types */
-               if ((!(td->status & TD_CTRL_ACTIVE) &&
-                   (uhci_actual_length(td->status) < uhci_expected_length(td->info)) 
||
-                   tmp == head)) {
+               if (!(td->status & TD_CTRL_ACTIVE) &&
+                   (uhci_actual_length(td->status) < uhci_expected_length(td->info) ||
+                   tmp == head))
                        usb_settoggle(urb->dev, uhci_endpoint(td->info),
                                uhci_packetout(td->info),
                                uhci_toggle(td->info) ^ 1);
-               }
+               else if ((td->status & TD_CTRL_ACTIVE) && !prevactive)
+                       usb_settoggle(urb->dev, uhci_endpoint(td->info),
+                               uhci_packetout(td->info),
+                               uhci_toggle(td->info));
+
+               prevactive = td->status & TD_CTRL_ACTIVE;
        }
 
        uhci_delete_queued_urb(uhci, urb);

_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to