hi,

great work that fast bug hunting :)

... mmmh, but i cant find any *remove_qh function in 2.4.26 usb-uhci,

so thats not targeting "my" problem(?)

anyway bt nap is running mostly of time, i'll investigate further after i read the kernel hacking docs completely ;)

thx
y
tom

Alan Stern wrote:
Greg and others:

A major bug in the UHCI driver turned up recently.  Thanks to a lot of
help from Simone Gotti it was identified and fixed late last week.  It
turned out to be entirely my fault -- a previous patch had introduced two
(!) errors.  (A combination of carelessness and a nasty thinko, and
somehow it passed the regression tests...)

Anyway, it's entirely possible that many of the problems people have been
seeing are caused by that bug.  This patch is the solution.

Greg, please apply this and send it up for inclusion in the next -rc and -mm kernels ASAP.

Alan Stern


===== drivers/usb/host/uhci-hcd.c 1.101 vs edited =====
--- 1.101/drivers/usb/host/uhci-hcd.c Fri Mar 26 10:19:10 2004
+++ edited/drivers/usb/host/uhci-hcd.c Fri Apr 16 13:43:12 2004
@@ -382,6 +382,7 @@
static void uhci_remove_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
{
struct uhci_qh *pqh;
+ __u32 newlink;
if (!qh)
return;
@@ -390,8 +391,24 @@
* Only go through the hoops if it's actually linked in
*/
if (!list_empty(&qh->list)) {
- pqh = list_entry(qh->list.prev, struct uhci_qh, list);
+ /* If our queue is nonempty, make the next URB the head */
+ if (!list_empty(&qh->urbp->queue_list)) {
+ struct urb_priv *nurbp;
+
+ nurbp = list_entry(qh->urbp->queue_list.next,
+ struct urb_priv, queue_list);
+ nurbp->queued = 0;
+ list_add(&nurbp->qh->list, &qh->list);
+ newlink = cpu_to_le32(nurbp->qh->dma_handle) | UHCI_PTR_QH;
+ } else
+ newlink = qh->link;
+
+ /* Fix up the previous QH's queue to link to either
+ * the new head of this queue or the start of the
+ * next endpoint's queue. */
+ pqh = list_entry(qh->list.prev, struct uhci_qh, list);
+ pqh->link = newlink;
if (pqh->urbp) {
struct list_head *head, *tmp;
@@ -403,28 +420,19 @@
tmp = tmp->next;
- turbp->qh->link = qh->link;
+ turbp->qh->link = newlink;
}
}
-
- pqh->link = qh->link;
mb();
+
/* Leave qh->link in case the HC is on the QH now, it will */
/* continue the rest of the schedule */
qh->element = UHCI_PTR_TERM;
- /* If our queue is nonempty, make the next URB the head */
- if (!list_empty(&qh->urbp->queue_list)) {
- struct urb_priv *nurbp;
-
- nurbp = list_entry(qh->urbp->queue_list.next,
- struct urb_priv, queue_list);
- nurbp->queued = 0;
- list_add_tail(&nurbp->qh->list, &qh->list);
- }
list_del_init(&qh->list);
}
+ list_del_init(&qh->urbp->queue_list);
qh->urbp = NULL;
/* Check to see if the remove list is empty. Set the IOC bit */
@@ -579,7 +587,7 @@
pltd->link = UHCI_PTR_TERM;
}
- list_del_init(&urbp->queue_list);
+ /* urbp->queue_list is handled in uhci_remove_qh() */
}
static struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci, struct urb *urb)




-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&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