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