/* to make sure it doesn't hog all of the bandwidth */
 #define DEPTH_INTERVAL 5
 
-static inline void restart_timer(struct uhci_hcd *uhci)
-{
-       mod_timer(&uhci->stall_timer, jiffies + msecs_to_jiffies(100));
-}
-
-#include "uhci-hub.c"
 #include "uhci-debug.c"
 #include "uhci-q.c"
+#include "uhci-hub.c"
 
 /*
  * Make sure the controller is completely inactive, unable to
 {
        reset_hc(uhci);
        uhci->hc_inaccessible = 1;
-       del_timer(&uhci->stall_timer);
 }
 
 /*
        /* Enable resume-detect interrupts if they work.
         * Then enter Global Suspend mode, still configured.
         */
-       int_enable = (resume_detect_interrupts_are_broken(uhci) ?
-                       0 : USBINTR_RESUME);
+       uhci->working_RD = 1;
+       int_enable = USBINTR_RESUME;
+       if (resume_detect_interrupts_are_broken(uhci)) {
+               uhci->working_RD = int_enable = 0;
+       }
        outw(int_enable, uhci->io_addr + USBINTR);
        outw(USBCMD_EGSM | USBCMD_CF, uhci->io_addr + USBCMD);
        mb();
 
        uhci->rh_state = new_state;
        uhci->is_stopped = UHCI_IS_STOPPED;
-       del_timer(&uhci->stall_timer);
        uhci_to_hcd(uhci)->poll_rh = !int_enable;
 
        uhci_scan_schedule(uhci, NULL);
        mb();
        uhci->rh_state = UHCI_RH_RUNNING;
        uhci_to_hcd(uhci)->poll_rh = 1;
-       restart_timer(uhci);
 }
 
 static void wakeup_rh(struct uhci_hcd *uhci)
        mod_timer(&uhci_to_hcd(uhci)->rh_timer, jiffies);
 }
 
-static void stall_callback(unsigned long _uhci)
-{
-       struct uhci_hcd *uhci = (struct uhci_hcd *) _uhci;
-       unsigned long flags;
-
-       spin_lock_irqsave(&uhci->lock, flags);
-       uhci_scan_schedule(uhci, NULL);
-       check_fsbr(uhci);
-
-       if (!uhci->is_stopped)
-               restart_timer(uhci);
-       spin_unlock_irqrestore(&uhci->lock, flags);
-}
-
 static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
 {
        struct uhci_hcd *uhci = hcd_to_uhci(hcd);
                                        "host controller halted, "
                                        "very bad!\n");
                                hc_died(uhci);
-                               spin_unlock_irqrestore(&uhci->lock, flags);
-                               return IRQ_HANDLED;
+
+                               /* Force a callback in case there are
+                                * pending unlinks */
+                               mod_timer(&hcd->rh_timer, jiffies);
                        }
                        spin_unlock_irqrestore(&uhci->lock, flags);
                }
 
        if (status & USBSTS_RD)
                usb_hcd_poll_rh_status(hcd);
-
-       spin_lock_irqsave(&uhci->lock, flags);
-       uhci_scan_schedule(uhci, regs);
-       spin_unlock_irqrestore(&uhci->lock, flags);
+       else {
+               spin_lock_irqsave(&uhci->lock, flags);
+               uhci_scan_schedule(uhci, regs);
+               spin_unlock_irqrestore(&uhci->lock, flags);
+       }
 
        return IRQ_HANDLED;
 }
 
        init_waitqueue_head(&uhci->waitqh);
 
-       init_timer(&uhci->stall_timer);
-       uhci->stall_timer.function = stall_callback;
-       uhci->stall_timer.data = (unsigned long) uhci;
-
        uhci->fl = dma_alloc_coherent(uhci_dev(uhci), sizeof(*uhci->fl),
                        &dma_handle, 0);
        if (!uhci->fl) {
        struct uhci_hcd *uhci = hcd_to_uhci(hcd);
 
        spin_lock_irq(&uhci->lock);
-       reset_hc(uhci);
+       if (!uhci->hc_inaccessible)
+               reset_hc(uhci);
        uhci_scan_schedule(uhci, NULL);
        spin_unlock_irq(&uhci->lock);
 
-       del_timer_sync(&uhci->stall_timer);
        release_uhci(uhci);
 }
 
         */
        pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, 0);
        uhci->hc_inaccessible = 1;
+       hcd->poll_rh = 0;
 
        /* FIXME: Enable non-PME# remote wakeup? */
 
 done:
        spin_unlock_irq(&uhci->lock);
-       if (rc == 0)
-               del_timer_sync(&hcd->rh_timer);
        return rc;
 }
 
 
        spin_unlock_irq(&uhci->lock);
 
-       if (hcd->poll_rh)
+       if (!uhci->working_RD) {
+               /* Suspended root hub needs to be polled */
+               hcd->poll_rh = 1;
                usb_hcd_poll_rh_status(hcd);
+       }
        return 0;
 }
 #endif
 
 
 /*
  * This describes the full uhci information.
- *
- * Note how the "proper" USB information is just
- * a subset of what the full implementation needs.
  */
 struct uhci_hcd {
 
        struct dma_pool *qh_pool;
        struct dma_pool *td_pool;
 
-       struct usb_bus *bus;
-
        struct uhci_td *term_td;        /* Terminating TD, see UHCI bug */
        struct uhci_qh *skelqh[UHCI_NUM_SKELQH];        /* Skeleton QH's */
 
        unsigned int scan_in_progress:1;        /* Schedule scan is running */
        unsigned int need_rescan:1;             /* Redo the schedule scan */
        unsigned int hc_inaccessible:1;         /* HC is suspended or dead */
+       unsigned int working_RD:1;              /* Suspended root hub doesn't
+                                                  need to be polled */
 
        /* Support for port suspend/resume/reset */
        unsigned long port_c_suspend;           /* Bit-arrays of ports */
        /* List of URB's awaiting completion callback */
        struct list_head complete_list;         /* P: uhci->lock */
 
-       int rh_numports;
-
-       struct timer_list stall_timer;
+       int rh_numports;                        /* Number of root-hub ports */
 
        wait_queue_head_t waitqh;               /* endpoint_disable waiters */
 };