--- /dev/null
+diff -Nur linux-2.4.32/drivers/usb/host/ehci-hcd.c linux-2.4.33-pre1/drivers/usb/host/ehci-hcd.c
+--- linux-2.4.32/drivers/usb/host/ehci-hcd.c 2004-11-17 09:54:21.000000000 -0200
++++ linux-2.4.33-pre1/drivers/usb/host/ehci-hcd.c 2005-12-28 18:15:56.000000000 -0200
+@@ -796,6 +796,30 @@
+ }
+ }
+
++static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
++{
++ /* if we need to use IAA and it's busy, defer */
++ if (qh->qh_state == QH_STATE_LINKED
++ && ehci->reclaim
++ && HCD_IS_RUNNING (ehci->hcd.state)) {
++ struct ehci_qh *last;
++
++ for (last = ehci->reclaim;
++ last->reclaim;
++ last = last->reclaim)
++ continue;
++ qh->qh_state = QH_STATE_UNLINK_WAIT;
++ last->reclaim = qh;
++
++ /* bypass IAA if the hc can't care */
++ } else if (!HCD_IS_RUNNING (ehci->hcd.state) && ehci->reclaim)
++ end_unlink_async (ehci, NULL);
++
++ /* something else might have unlinked the qh by now */
++ if (qh->qh_state == QH_STATE_LINKED)
++ start_unlink_async (ehci, qh);
++}
++
+ /* remove from hardware lists
+ * completions normally happen asynchronously
+ */
+@@ -814,28 +838,7 @@
+ qh = (struct ehci_qh *) urb->hcpriv;
+ if (!qh)
+ break;
+-
+- /* if we need to use IAA and it's busy, defer */
+- if (qh->qh_state == QH_STATE_LINKED
+- && ehci->reclaim
+- && HCD_IS_RUNNING (ehci->hcd.state)
+- ) {
+- struct ehci_qh *last;
+-
+- for (last = ehci->reclaim;
+- last->reclaim;
+- last = last->reclaim)
+- continue;
+- qh->qh_state = QH_STATE_UNLINK_WAIT;
+- last->reclaim = qh;
+-
+- /* bypass IAA if the hc can't care */
+- } else if (!HCD_IS_RUNNING (ehci->hcd.state) && ehci->reclaim)
+- end_unlink_async (ehci, NULL);
+-
+- /* something else might have unlinked the qh by now */
+- if (qh->qh_state == QH_STATE_LINKED)
+- start_unlink_async (ehci, qh);
++ unlink_async (ehci, qh);
+ break;
+
+ case PIPE_INTERRUPT:
+diff -Nur linux-2.4.32/drivers/usb/host/ehci-q.c linux-2.4.33-pre1/drivers/usb/host/ehci-q.c
+--- linux-2.4.32/drivers/usb/host/ehci-q.c 2005-01-19 12:10:07.000000000 -0200
++++ linux-2.4.33-pre1/drivers/usb/host/ehci-q.c 2005-12-28 18:15:56.000000000 -0200
+@@ -199,8 +199,6 @@
+ #ifdef INTR_AUTOMAGIC
+ struct urb *resubmit = 0;
+ struct usb_device *dev = 0;
+-
+- static int ehci_urb_enqueue (struct usb_hcd *, struct urb *, int);
+ #endif
+
+ if (likely (urb->hcpriv != 0)) {
+@@ -280,6 +278,7 @@
+ }
+
+ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh);
++static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh);
+
+ /*
+ * Process and free completed qtds for a qh, returning URBs to drivers.
+@@ -430,7 +429,7 @@
+ qh_refresh(ehci, qh);
+ break;
+ case QH_STATE_LINKED:
+- start_unlink_async (ehci, qh);
++ unlink_async (ehci, qh);
+ break;
+ /* otherwise, unlink already started */
+ }