On Wed, 25 Feb 2004, Stephen Hemminger wrote:

> The idea is good, but something is bad about this. It works for normal i/o
> to a USB device, but when I do lsusb, it ends up oops'ing.

I think I found the problem.  In usb_control_retrigger_status you were 
freeing a TD without removing it from its list.  This patch is nearly the 
same as yours.  Please try it and see how well it works for you.

Alan Stern


===== uhci-hcd.c 1.94 vs edited =====
--- 1.94/drivers/usb/host/uhci-hcd.c    Thu Feb 26 15:03:16 2004
+++ edited/drivers/usb/host/uhci-hcd.c  Thu Feb 26 15:24:51 2004
@@ -157,7 +157,6 @@
        td->dev = dev;
 
        INIT_LIST_HEAD(&td->list);
-       INIT_LIST_HEAD(&td->remove_list);
        INIT_LIST_HEAD(&td->fl_list);
 
        usb_get_dev(dev);
@@ -288,8 +287,6 @@
 {
        if (!list_empty(&td->list))
                dev_warn(uhci_dev(uhci), "td %p still in list!\n", td);
-       if (!list_empty(&td->remove_list))
-               dev_warn(uhci_dev(uhci), "td %p still in remove_list!\n", td);
        if (!list_empty(&td->fl_list))
                dev_warn(uhci_dev(uhci), "td %p still in fl_list!\n", td);
 
@@ -694,19 +691,6 @@
 /*
  * MUST be called with urb->lock acquired
  */
-static void uhci_remove_td_from_urb(struct uhci_td *td)
-{
-       if (list_empty(&td->list))
-               return;
-
-       list_del_init(&td->list);
-
-       td->urb = NULL;
-}
-
-/*
- * MUST be called with urb->lock acquired
- */
 static void uhci_destroy_urb_priv(struct uhci_hcd *uhci, struct urb *urb)
 {
        struct list_head *head, *tmp;
@@ -735,9 +719,9 @@
 
                tmp = tmp->next;
 
-               uhci_remove_td_from_urb(td);
+               td->urb = NULL;
                uhci_remove_td(uhci, td);
-               list_add(&td->remove_list, &uhci->td_remove_list);
+               list_move_tail(&td->list, &uhci->td_remove_list);
        }
 
        spin_unlock_irqrestore(&uhci->td_remove_list_lock, flags);
@@ -948,9 +932,9 @@
 
                tmp = tmp->next;
 
-               uhci_remove_td_from_urb(td);
+               td->urb = NULL;
                uhci_remove_td(uhci, td);
-               uhci_free_td(uhci, td);
+               list_move_tail(&td->list, &uhci->td_remove_list);
        }
 
        urbp->qh = uhci_alloc_qh(uhci, urb->dev);
@@ -1804,12 +1788,11 @@
        head = &uhci->td_remove_list;
        tmp = head->next;
        while (tmp != head) {
-               struct uhci_td *td = list_entry(tmp, struct uhci_td, remove_list);
+               struct uhci_td *td = list_entry(tmp, struct uhci_td, list);
 
                tmp = tmp->next;
 
-               list_del_init(&td->remove_list);
-
+               list_del_init(&td->list);
                uhci_free_td(uhci, td);
        }
        spin_unlock(&uhci->td_remove_list_lock);
===== uhci-hcd.h 1.24 vs edited =====
--- 1.24/drivers/usb/host/uhci-hcd.h    Mon Feb 23 12:15:56 2004
+++ edited/drivers/usb/host/uhci-hcd.h  Thu Feb 26 15:09:00 2004
@@ -197,7 +197,6 @@
        struct urb *urb;
 
        struct list_head list;          /* P: urb->lock */
-       struct list_head remove_list;   /* P: uhci->td_remove_list_lock */
 
        int frame;                      /* for iso: what frame? */
        struct list_head fl_list;       /* P: uhci->frame_list_lock */



-------------------------------------------------------
SF.Net is sponsored by: Speed Start Your Linux Apps Now.
Build and deploy apps & Web services for Linux with
a free DVD software kit from IBM. Click Now!
http://ads.osdn.com/?ad_id=1356&alloc_id=3438&op=click
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to