Following is the patch that we received from our h/w vendor. It seems
to correct the issue where we are seeing the ethernet interface
accumulate RX errors while USB device is not actually used.

We have been testing this for a while and it seems to work. Comments
appreciated.

Patch is against 2.6.16

Thanks.

--- ohci-q.c.old        2007-05-31 09:18:26.569155000 -0700
+++ ohci-q.c    2007-06-19 11:08:44.678144000 -0700
@@ -872,7 +872,11 @@ static struct td *dl_reverse_done_list (
        struct td       *td_rev = NULL;
        struct td       *td = NULL;

-       td_dma = hc32_to_cpup (ohci, &ohci->hcca->done_head);
+       urb_priv_t *urbpriv;
+       int count;
+       struct urb *urb;
+
+       td_dma = hc32_to_cpup(ohci, &ohci->hcca->done_head);
        ohci->hcca->done_head = 0;
        wmb();

@@ -891,18 +895,38 @@ static struct td *dl_reverse_done_list (
                td->hwINFO |= cpu_to_hc32 (ohci, TD_DONE);
                cc = TD_CC_GET (hc32_to_cpup (ohci, &td->hwINFO));

-               /* Non-iso endpoints can halt on error; un-halt,
-                * and dequeue any other TDs from this urb.
-                * No other TD could have caused the halt.
-                */
-               if (cc != TD_CC_NOERROR
-                               && (td->ed->hwHeadP & cpu_to_hc32 (ohci, ED_H)))
-                       td_rev = ed_halted (ohci, td, cc, td_rev);
-
-               td->next_dl_td = td_rev;
-               td_rev = td;
-               td_dma = hc32_to_cpup (ohci, &td->hwNextTD);
-       }
+
+               if (cc == TD_PIDCHECKFAIL || cc == TD_DEVNOTRESP) {
+                       urbpriv = td->urb->hcpriv;
+
+                       td->ed->hwHeadP &= ~cpu_to_hc32(ohci, ED_H);
+                       td->hwINFO &= ~cpu_to_hc32(ohci, TD_CC);
+                       td->hwINFO &= ~cpu_to_hc32(ohci, TD_EC);
+                       urb = td->urb;
+                       for (count = 0; count < urbpriv->length; count++) {
+                               td = urbpriv->td[count];
+                               if (td) {
+                                       list_del(&td->td_list);
+                                       td_dma =
+                                           hc32_to_cpup(ohci, &td->hwNextTD);
+                               }
+                       }
+                       list_del(&urbpriv->pending);
+                       td_submit_urb(ohci, urb);
+               } else {
+                       /* Non-iso endpoints can halt on error; un-halt,
+                        * and dequeue any other TDs from this urb.
+                        * No other TD could have caused the halt.
+                        */
+                       if (cc != TD_CC_NOERROR &&
+                           (td->ed->hwHeadP & cpu_to_hc32(ohci, ED_H)))
+                               td_rev = ed_halted(ohci, td, cc, td_rev);
+
+                       td->next_dl_td = td_rev;
+                       td_rev = td;
+                       td_dma = hc32_to_cpup(ohci, &td->hwNextTD);
+               }
+       }
        return td_rev;
 }

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to