ChangeSet 1.1305.7.5, 2003/06/16 12:01:45-07:00, [EMAIL PROTECTED]

[PATCH] USB: ehci, fix qh re-activation problem

This resolves a problem that appears when relinking
a bulk or control QH that has a partially completed
multi-packet qTD.  Some I/O could be repeated.

Such cases can happen when an empty QH starts to unlink,
but gets re-activated (by queueing the multi-packet qTD)
before the HC saw the unlink.  It's rarely an issue with
control traffic (transfers are so small) or when bulk
queues are active (the QH won't empty).


 drivers/usb/host/ehci-hcd.c |    2 +-
 drivers/usb/host/ehci-q.c   |   16 +++++++++++-----
 2 files changed, 12 insertions(+), 6 deletions(-)


diff -Nru a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
--- a/drivers/usb/host/ehci-hcd.c       Wed Jun 18 11:15:55 2003
+++ b/drivers/usb/host/ehci-hcd.c       Wed Jun 18 11:15:55 2003
@@ -91,7 +91,7 @@
  * 2001-June   Works with usb-storage and NEC EHCI on 2.4
  */
 
-#define DRIVER_VERSION "2003-Jun-12"
+#define DRIVER_VERSION "2003-Jun-13"
 #define DRIVER_AUTHOR "David Brownell"
 #define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver"
 
diff -Nru a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
--- a/drivers/usb/host/ehci-q.c Wed Jun 18 11:15:55 2003
+++ b/drivers/usb/host/ehci-q.c Wed Jun 18 11:15:55 2003
@@ -360,11 +360,17 @@
        if (unlikely (stopped != 0)
                        /* some EHCI 0.95 impls will overlay dummy qtds */ 
                        || qh->hw_qtd_next == EHCI_LIST_END) {
-               qh_update (ehci, qh,
-                       list_empty (&qh->qtd_list)
-                               ? qh->dummy
-                               : list_entry (qh->qtd_list.next,
-                                       struct ehci_qtd, qtd_list));
+               if (list_empty (&qh->qtd_list))
+                       end = qh->dummy;
+               else {
+                       end = list_entry (qh->qtd_list.next,
+                                       struct ehci_qtd, qtd_list);
+                       /* first qtd may already be partially processed */
+                       if (cpu_to_le32 (end->qtd_dma) == qh->hw_current)
+                               end = 0;
+               }
+               if (end)
+                       qh_update (ehci, qh, end);
        }
 
        return count;



-------------------------------------------------------
This SF.Net email is sponsored by: INetU
Attention Web Developers & Consultants: Become An INetU Hosting Partner.
Refer Dedicated Servers. We Manage Them. You Get 10% Monthly Commission!
INetU Dedicated Managed Hosting http://www.inetu.net/partner/index.php
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to