diff -Nurb linux-2.6.16.1/drivers/usb/host/ehci.h linux-patched/drivers/usb/host/ehci.h
--- linux-2.6.16.1/drivers/usb/host/ehci.h	2006-03-27 22:49:02.000000000 -0800
+++ linux-patched/drivers/usb/host/ehci.h	2006-04-07 12:07:30.000000000 -0700
@@ -82,6 +82,7 @@
 	struct dma_pool		*sitd_pool;	/* sitd per split iso urb */
 
 	struct timer_list	watchdog;
+	struct timer_list	softirq;
 	unsigned long		actions;
 	unsigned		stamp;
 	unsigned long		next_statechange;
diff -Nurb linux-2.6.16.1/drivers/usb/host/ehci-hcd.c linux-patched/drivers/usb/host/ehci-hcd.c
--- linux-2.6.16.1/drivers/usb/host/ehci-hcd.c	2006-03-27 22:49:02.000000000 -0800
+++ linux-patched/drivers/usb/host/ehci-hcd.c	2006-04-07 13:20:13.000000000 -0700
@@ -116,6 +116,7 @@
 #define EHCI_IO_JIFFIES		(HZ/10)		/* io watchdog > irq_thresh */
 #define EHCI_ASYNC_JIFFIES	(HZ/20)		/* async idle timeout */
 #define EHCI_SHRINK_JIFFIES	(HZ/200)	/* async qh unlink delay */
+#define EHCI_SOFTIRQ		(HZ/400)
 
 /* Initial IRQ latency:  faster than hw default */
 static int log2_irq_thresh = 0;		// 0 to 6
@@ -263,6 +264,16 @@
 #include "ehci-sched.c"
 
 /*-------------------------------------------------------------------------*/
+static irqreturn_t ehci_irq (struct usb_hcd *hcd);
+
+static void ehci_softirq (unsigned long param)
+{
+	struct ehci_hcd         *ehci = (struct ehci_hcd *) param;
+
+	if (ehci_irq(ehci_to_hcd(ehci)) != IRQ_NONE)
+		set_bit(HCD_FLAG_SAW_IRQ, &(ehci_to_hcd(ehci))->flags);
+	mod_timer (&ehci->softirq, jiffies + EHCI_SOFTIRQ);
+}
 
 static void ehci_watchdog (unsigned long param)
 {
@@ -280,6 +291,10 @@
 			COUNT (ehci->stats.lost_iaa);
 			writel (STS_IAA, &ehci->regs->status);
 			ehci->reclaim_ready = 1;
+			if (!timer_pending(&ehci->softirq)) {
+				ehci_info(ehci, "switching to softirq\n");
+				mod_timer (&ehci->softirq, jiffies + EHCI_SOFTIRQ);
+			}
 		}
 	}
 
@@ -371,6 +388,7 @@
 
 	/* no more interrupts ... */
 	del_timer_sync (&ehci->watchdog);
+	del_timer_sync (&ehci->softirq);
 
 	spin_lock_irq(&ehci->lock);
 	if (HC_IS_RUNNING (hcd->state))
@@ -418,6 +436,10 @@
 	ehci->watchdog.function = ehci_watchdog;
 	ehci->watchdog.data = (unsigned long) ehci;
 
+	init_timer(&ehci->softirq);
+	ehci->softirq.function = ehci_softirq;
+	ehci->softirq.data = (unsigned long) ehci;
+
 	/*
 	 * hw default: 1K periodic list heads, one per frame.
 	 * periodic_size can shrink by USBCMD update if hcc_params allows.

