diff options
Diffstat (limited to 'drivers/usb/host')
-rw-r--r-- | drivers/usb/host/ehci-dbg.c | 4 | ||||
-rw-r--r-- | drivers/usb/host/ehci-hcd.c | 88 | ||||
-rw-r--r-- | drivers/usb/host/ehci-hub.c | 4 | ||||
-rw-r--r-- | drivers/usb/host/ehci-pci.c | 4 | ||||
-rw-r--r-- | drivers/usb/host/ehci-q.c | 27 | ||||
-rw-r--r-- | drivers/usb/host/ehci-sched.c | 21 | ||||
-rw-r--r-- | drivers/usb/host/ehci.h | 22 | ||||
-rw-r--r-- | drivers/usb/host/hc_crisv10.c | 12 | ||||
-rw-r--r-- | drivers/usb/host/isp116x-hcd.c | 16 | ||||
-rw-r--r-- | drivers/usb/host/ohci-hcd.c | 14 | ||||
-rw-r--r-- | drivers/usb/host/ohci-hub.c | 8 | ||||
-rw-r--r-- | drivers/usb/host/ohci-pnx4008.c | 9 | ||||
-rw-r--r-- | drivers/usb/host/ohci-q.c | 16 | ||||
-rw-r--r-- | drivers/usb/host/sl811-hcd.c | 21 | ||||
-rw-r--r-- | drivers/usb/host/u132-hcd.c | 9 | ||||
-rw-r--r-- | drivers/usb/host/uhci-hcd.c | 52 | ||||
-rw-r--r-- | drivers/usb/host/uhci-hub.c | 2 | ||||
-rw-r--r-- | drivers/usb/host/uhci-q.c | 15 |
18 files changed, 172 insertions, 172 deletions
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index 23b95b2..34b7a31 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c @@ -754,7 +754,9 @@ show_registers (struct class_device *class_dev, char *buf) } if (ehci->reclaim) { - temp = scnprintf (next, size, "reclaim qh %p\n", ehci->reclaim); + temp = scnprintf (next, size, "reclaim qh %p%s\n", + ehci->reclaim, + ehci->reclaim_ready ? " ready" : ""); size -= temp; next += temp; } diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 5ac9185..9030994 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -111,7 +111,7 @@ static const char hcd_name [] = "ehci_hcd"; #define EHCI_TUNE_MULT_TT 1 #define EHCI_TUNE_FLS 2 /* (small) 256 frame schedule */ -#define EHCI_IAA_MSECS 10 /* arbitrary */ +#define EHCI_IAA_JIFFIES (HZ/100) /* arbitrary; ~10 msec */ #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 */ @@ -254,8 +254,7 @@ static void ehci_quiesce (struct ehci_hcd *ehci) /*-------------------------------------------------------------------------*/ -static void end_unlink_async (struct ehci_hcd *ehci, struct pt_regs *regs); -static void ehci_work(struct ehci_hcd *ehci, struct pt_regs *regs); +static void ehci_work(struct ehci_hcd *ehci); #include "ehci-hub.c" #include "ehci-mem.c" @@ -264,42 +263,30 @@ static void ehci_work(struct ehci_hcd *ehci, struct pt_regs *regs); /*-------------------------------------------------------------------------*/ -static void ehci_iaa_watchdog (unsigned long param) +static void ehci_watchdog (unsigned long param) { struct ehci_hcd *ehci = (struct ehci_hcd *) param; unsigned long flags; - u32 status; spin_lock_irqsave (&ehci->lock, flags); - WARN_ON(!ehci->reclaim); - /* lost IAA irqs wedge things badly; seen first with a vt8235 */ + /* lost IAA irqs wedge things badly; seen with a vt8235 */ if (ehci->reclaim) { - status = readl (&ehci->regs->status); + u32 status = readl (&ehci->regs->status); if (status & STS_IAA) { ehci_vdbg (ehci, "lost IAA\n"); COUNT (ehci->stats.lost_iaa); writel (STS_IAA, &ehci->regs->status); - end_unlink_async (ehci, NULL); + ehci->reclaim_ready = 1; } } - spin_unlock_irqrestore (&ehci->lock, flags); -} - -static void ehci_watchdog (unsigned long param) -{ - struct ehci_hcd *ehci = (struct ehci_hcd *) param; - unsigned long flags; - - spin_lock_irqsave (&ehci->lock, flags); - - /* stop async processing after it's idled a bit */ + /* stop async processing after it's idled a bit */ if (test_bit (TIMER_ASYNC_OFF, &ehci->actions)) start_unlink_async (ehci, ehci->async); /* ehci could run by timer, without IRQs ... */ - ehci_work (ehci, NULL); + ehci_work (ehci); spin_unlock_irqrestore (&ehci->lock, flags); } @@ -342,9 +329,11 @@ static void ehci_port_power (struct ehci_hcd *ehci, int is_on) * ehci_work is called from some interrupts, timers, and so on. * it calls driver completion functions, after dropping ehci->lock. */ -static void ehci_work (struct ehci_hcd *ehci, struct pt_regs *regs) +static void ehci_work (struct ehci_hcd *ehci) { timer_action_done (ehci, TIMER_IO_WATCHDOG); + if (ehci->reclaim_ready) + end_unlink_async (ehci); /* another CPU may drop ehci->lock during a schedule scan while * it reports urb completions. this flag guards against bogus @@ -353,9 +342,9 @@ static void ehci_work (struct ehci_hcd *ehci, struct pt_regs *regs) if (ehci->scanning) return; ehci->scanning = 1; - scan_async (ehci, regs); + scan_async (ehci); if (ehci->next_uframe != -1) - scan_periodic (ehci, regs); + scan_periodic (ehci); ehci->scanning = 0; /* the IO watchdog guards against hardware or driver bugs that @@ -379,7 +368,6 @@ static void ehci_stop (struct usb_hcd *hcd) /* no more interrupts ... */ del_timer_sync (&ehci->watchdog); - del_timer_sync (&ehci->iaa_watchdog); spin_lock_irq(&ehci->lock); if (HC_IS_RUNNING (hcd->state)) @@ -397,7 +385,7 @@ static void ehci_stop (struct usb_hcd *hcd) /* root hub is shut down separately (first, when possible) */ spin_lock_irq (&ehci->lock); if (ehci->async) - ehci_work (ehci, NULL); + ehci_work (ehci); spin_unlock_irq (&ehci->lock); ehci_mem_cleanup (ehci); @@ -426,10 +414,6 @@ static int ehci_init(struct usb_hcd *hcd) ehci->watchdog.function = ehci_watchdog; ehci->watchdog.data = (unsigned long) ehci; - init_timer(&ehci->iaa_watchdog); - ehci->iaa_watchdog.function = ehci_iaa_watchdog; - ehci->iaa_watchdog.data = (unsigned long) ehci; - /* * hw default: 1K periodic list heads, one per frame. * periodic_size can shrink by USBCMD update if hcc_params allows. @@ -446,6 +430,7 @@ static int ehci_init(struct usb_hcd *hcd) ehci->i_thresh = 2 + HCC_ISOC_THRES(hcc_params); ehci->reclaim = NULL; + ehci->reclaim_ready = 0; ehci->next_uframe = -1; /* @@ -573,7 +558,7 @@ static int ehci_run (struct usb_hcd *hcd) /*-------------------------------------------------------------------------*/ -static irqreturn_t ehci_irq (struct usb_hcd *hcd, struct pt_regs *regs) +static irqreturn_t ehci_irq (struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci (hcd); u32 status; @@ -619,7 +604,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd, struct pt_regs *regs) /* complete the unlinking of some qh [4.15.2.3] */ if (status & STS_IAA) { COUNT (ehci->stats.reclaim); - end_unlink_async (ehci, regs); + ehci->reclaim_ready = 1; bh = 1; } @@ -670,7 +655,7 @@ dead: } if (bh) - ehci_work (ehci, regs); + ehci_work (ehci); spin_unlock (&ehci->lock); return IRQ_HANDLED; } @@ -723,14 +708,10 @@ static int ehci_urb_enqueue ( static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) { - // BUG_ON(qh->qh_state != QH_STATE_LINKED); - - /* failfast */ - if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) - end_unlink_async (ehci, NULL); - - /* defer till later if busy */ - else if (ehci->reclaim) { + /* if we need to use IAA and it's busy, defer */ + if (qh->qh_state == QH_STATE_LINKED + && ehci->reclaim + && HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) { struct ehci_qh *last; for (last = ehci->reclaim; @@ -740,8 +721,12 @@ static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) qh->qh_state = QH_STATE_UNLINK_WAIT; last->reclaim = qh; - /* start IAA cycle */ - } else + /* bypass IAA if the hc can't care */ + } else if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state) && ehci->reclaim) + end_unlink_async (ehci); + + /* something else might have unlinked the qh by now */ + if (qh->qh_state == QH_STATE_LINKED) start_unlink_async (ehci, qh); } @@ -763,19 +748,7 @@ static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) qh = (struct ehci_qh *) urb->hcpriv; if (!qh) break; - switch (qh->qh_state) { - case QH_STATE_LINKED: - case QH_STATE_COMPLETING: - unlink_async (ehci, qh); - break; - case QH_STATE_UNLINK: - case QH_STATE_UNLINK_WAIT: - /* already started */ - break; - case QH_STATE_IDLE: - WARN_ON(1); - break; - } + unlink_async (ehci, qh); break; case PIPE_INTERRUPT: @@ -787,7 +760,7 @@ static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) intr_deschedule (ehci, qh); /* FALL THROUGH */ case QH_STATE_IDLE: - qh_completions (ehci, qh, NULL); + qh_completions (ehci, qh); break; default: ehci_dbg (ehci, "bogus qh %p state %d\n", @@ -867,7 +840,6 @@ rescan: unlink_async (ehci, qh); /* FALL THROUGH */ case QH_STATE_UNLINK: /* wait for hw to finish? */ - case QH_STATE_UNLINK_WAIT: idle_timeout: spin_unlock_irqrestore (&ehci->lock, flags); schedule_timeout_uninterruptible(1); diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index b2ee13c..1b20722 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -48,8 +48,8 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) } ehci->command = readl (&ehci->regs->command); if (ehci->reclaim) - end_unlink_async (ehci, NULL); - ehci_work(ehci, NULL); + ehci->reclaim_ready = 1; + ehci_work(ehci); /* suspend any active/unsuspended ports, maybe allow wakeup */ while (port--) { diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 08d0472..e51c1ed8 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -303,8 +303,8 @@ restart: /* emptying the schedule aborts any urbs */ spin_lock_irq(&ehci->lock); if (ehci->reclaim) - end_unlink_async (ehci, NULL); - ehci_work(ehci, NULL); + ehci->reclaim_ready = 1; + ehci_work(ehci); spin_unlock_irq(&ehci->lock); /* restart; khubd will disconnect devices */ diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 7fc25b6..62e46dc 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -214,7 +214,7 @@ static void qtd_copy_status ( } static void -ehci_urb_done (struct ehci_hcd *ehci, struct urb *urb, struct pt_regs *regs) +ehci_urb_done (struct ehci_hcd *ehci, struct urb *urb) __releases(ehci->lock) __acquires(ehci->lock) { @@ -262,7 +262,7 @@ __acquires(ehci->lock) /* complete() can reenter this HCD */ spin_unlock (&ehci->lock); - usb_hcd_giveback_urb (ehci_to_hcd(ehci), urb, regs); + usb_hcd_giveback_urb (ehci_to_hcd(ehci), urb); spin_lock (&ehci->lock); } @@ -279,7 +279,7 @@ static int qh_schedule (struct ehci_hcd *ehci, struct ehci_qh *qh); */ #define HALT_BIT __constant_cpu_to_le32(QTD_STS_HALT) static unsigned -qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs) +qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) { struct ehci_qtd *last = NULL, *end = qh->dummy; struct list_head *entry, *tmp; @@ -317,7 +317,7 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs) /* clean up any state from previous QTD ...*/ if (last) { if (likely (last->urb != urb)) { - ehci_urb_done (ehci, last->urb, regs); + ehci_urb_done (ehci, last->urb); count++; } ehci_qtd_free (ehci, last); @@ -407,7 +407,7 @@ halt: /* last urb's completion might still need calling */ if (likely (last != NULL)) { - ehci_urb_done (ehci, last->urb, regs); + ehci_urb_done (ehci, last->urb); count++; ehci_qtd_free (ehci, last); } @@ -962,12 +962,12 @@ submit_async ( /* the async qh for the qtds being reclaimed are now unlinked from the HC */ -static void end_unlink_async (struct ehci_hcd *ehci, struct pt_regs *regs) +static void end_unlink_async (struct ehci_hcd *ehci) { struct ehci_qh *qh = ehci->reclaim; struct ehci_qh *next; - iaa_watchdog_done (ehci); + timer_action_done (ehci, TIMER_IAA_WATCHDOG); // qh->hw_next = cpu_to_le32 (qh->qh_dma); qh->qh_state = QH_STATE_IDLE; @@ -977,9 +977,10 @@ static void end_unlink_async (struct ehci_hcd *ehci, struct pt_regs *regs) /* other unlink(s) may be pending (in QH_STATE_UNLINK_WAIT) */ next = qh->reclaim; ehci->reclaim = next; + ehci->reclaim_ready = 0; qh->reclaim = NULL; - qh_completions (ehci, qh, regs); + qh_completions (ehci, qh); if (!list_empty (&qh->qtd_list) && HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) @@ -1047,20 +1048,20 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) /* if (unlikely (qh->reclaim != 0)) * this will recurse, probably not much */ - end_unlink_async (ehci, NULL); + end_unlink_async (ehci); return; } + ehci->reclaim_ready = 0; cmd |= CMD_IAAD; writel (cmd, &ehci->regs->command); (void) readl (&ehci->regs->command); - iaa_watchdog_start (ehci); + timer_action (ehci, TIMER_IAA_WATCHDOG); } /*-------------------------------------------------------------------------*/ -static void -scan_async (struct ehci_hcd *ehci, struct pt_regs *regs) +static void scan_async (struct ehci_hcd *ehci) { struct ehci_qh *qh; enum ehci_timer_action action = TIMER_IO_WATCHDOG; @@ -1084,7 +1085,7 @@ rescan: */ qh = qh_get (qh); qh->stamp = ehci->stamp; - temp = qh_completions (ehci, qh, regs); + temp = qh_completions (ehci, qh); qh_put (qh); if (temp != 0) { goto rescan; diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index e5e9c65..65c402a 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1553,8 +1553,7 @@ itd_link_urb ( static unsigned itd_complete ( struct ehci_hcd *ehci, - struct ehci_itd *itd, - struct pt_regs *regs + struct ehci_itd *itd ) { struct urb *urb = itd->urb; struct usb_iso_packet_descriptor *desc; @@ -1613,7 +1612,7 @@ itd_complete ( /* give urb back to the driver ... can be out-of-order */ dev = urb->dev; - ehci_urb_done (ehci, urb, regs); + ehci_urb_done (ehci, urb); urb = NULL; /* defer stopping schedule; completion can submit */ @@ -1930,8 +1929,7 @@ sitd_link_urb ( static unsigned sitd_complete ( struct ehci_hcd *ehci, - struct ehci_sitd *sitd, - struct pt_regs *regs + struct ehci_sitd *sitd ) { struct urb *urb = sitd->urb; struct usb_iso_packet_descriptor *desc; @@ -1978,7 +1976,7 @@ sitd_complete ( /* give urb back to the driver */ dev = urb->dev; - ehci_urb_done (ehci, urb, regs); + ehci_urb_done (ehci, urb); urb = NULL; /* defer stopping schedule; completion can submit */ @@ -2065,8 +2063,7 @@ sitd_submit (struct ehci_hcd *ehci, struct urb *urb, gfp_t mem_flags) static inline unsigned sitd_complete ( struct ehci_hcd *ehci, - struct ehci_sitd *sitd, - struct pt_regs *regs + struct ehci_sitd *sitd ) { ehci_err (ehci, "sitd_complete %p?\n", sitd); return 0; @@ -2077,7 +2074,7 @@ sitd_complete ( /*-------------------------------------------------------------------------*/ static void -scan_periodic (struct ehci_hcd *ehci, struct pt_regs *regs) +scan_periodic (struct ehci_hcd *ehci) { unsigned frame, clock, now_uframe, mod; unsigned modified; @@ -2131,7 +2128,7 @@ restart: temp.qh = qh_get (q.qh); type = Q_NEXT_TYPE (q.qh->hw_next); q = q.qh->qh_next; - modified = qh_completions (ehci, temp.qh, regs); + modified = qh_completions (ehci, temp.qh); if (unlikely (list_empty (&temp.qh->qtd_list))) intr_deschedule (ehci, temp.qh); qh_put (temp.qh); @@ -2169,7 +2166,7 @@ restart: *hw_p = q.itd->hw_next; type = Q_NEXT_TYPE (q.itd->hw_next); wmb(); - modified = itd_complete (ehci, q.itd, regs); + modified = itd_complete (ehci, q.itd); q = *q_p; break; case Q_TYPE_SITD: @@ -2185,7 +2182,7 @@ restart: *hw_p = q.sitd->hw_next; type = Q_NEXT_TYPE (q.sitd->hw_next); wmb(); - modified = sitd_complete (ehci, q.sitd, regs); + modified = sitd_complete (ehci, q.sitd); q = *q_p; break; default: diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 6aac39f..bbc3082 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -58,6 +58,7 @@ struct ehci_hcd { /* one per controller */ /* async schedule support */ struct ehci_qh *async; struct ehci_qh *reclaim; + unsigned reclaim_ready : 1; unsigned scanning : 1; /* periodic schedule support */ @@ -80,7 +81,6 @@ struct ehci_hcd { /* one per controller */ struct dma_pool *itd_pool; /* itd per iso urb */ struct dma_pool *sitd_pool; /* sitd per split iso urb */ - struct timer_list iaa_watchdog; struct timer_list watchdog; unsigned long actions; unsigned stamp; @@ -114,21 +114,9 @@ static inline struct usb_hcd *ehci_to_hcd (struct ehci_hcd *ehci) } -static inline void -iaa_watchdog_start (struct ehci_hcd *ehci) -{ - WARN_ON(timer_pending(&ehci->iaa_watchdog)); - mod_timer (&ehci->iaa_watchdog, - jiffies + msecs_to_jiffies(EHCI_IAA_MSECS)); -} - -static inline void iaa_watchdog_done (struct ehci_hcd *ehci) -{ - del_timer (&ehci->iaa_watchdog); -} - enum ehci_timer_action { TIMER_IO_WATCHDOG, + TIMER_IAA_WATCHDOG, TIMER_ASYNC_SHRINK, TIMER_ASYNC_OFF, }; @@ -146,6 +134,9 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action) unsigned long t; switch (action) { + case TIMER_IAA_WATCHDOG: + t = EHCI_IAA_JIFFIES; + break; case TIMER_IO_WATCHDOG: t = EHCI_IO_JIFFIES; break; @@ -162,7 +153,8 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action) // async queue SHRINK often precedes IAA. while it's ready // to go OFF neither can matter, and afterwards the IO // watchdog stops unless there's still periodic traffic. - if (time_before_eq(t, ehci->watchdog.expires) + if (action != TIMER_IAA_WATCHDOG + && t > ehci->watchdog.expires && timer_pending (&ehci->watchdog)) return; mod_timer (&ehci->watchdog, t); diff --git a/drivers/usb/host/hc_crisv10.c b/drivers/usb/host/hc_crisv10.c index 61e5717..87eca6a 100644 --- a/drivers/usb/host/hc_crisv10.c +++ b/drivers/usb/host/hc_crisv10.c @@ -478,9 +478,9 @@ static int etrax_usb_submit_urb(struct urb *urb, unsigned mem_flags); static int etrax_usb_unlink_urb(struct urb *urb, int status); static int etrax_usb_get_frame_number(struct usb_device *usb_dev); -static irqreturn_t etrax_usb_tx_interrupt(int irq, void *vhc, struct pt_regs *regs); -static irqreturn_t etrax_usb_rx_interrupt(int irq, void *vhc, struct pt_regs *regs); -static irqreturn_t etrax_usb_hc_interrupt_top_half(int irq, void *vhc, struct pt_regs *regs); +static irqreturn_t etrax_usb_tx_interrupt(int irq, void *vhc); +static irqreturn_t etrax_usb_rx_interrupt(int irq, void *vhc); +static irqreturn_t etrax_usb_hc_interrupt_top_half(int irq, void *vhc); static void etrax_usb_hc_interrupt_bottom_half(void *data); static void etrax_usb_isoc_descr_interrupt_bottom_half(void *data); @@ -1573,7 +1573,7 @@ static int etrax_usb_get_frame_number(struct usb_device *usb_dev) return (*R_USB_FM_NUMBER & 0x7ff); } -static irqreturn_t etrax_usb_tx_interrupt(int irq, void *vhc, struct pt_regs *regs) +static irqreturn_t etrax_usb_tx_interrupt(int irq, void *vhc) { DBFENTER; @@ -1839,7 +1839,7 @@ static void etrax_usb_isoc_descr_interrupt_bottom_half(void *data) -static irqreturn_t etrax_usb_rx_interrupt(int irq, void *vhc, struct pt_regs *regs) +static irqreturn_t etrax_usb_rx_interrupt(int irq, void *vhc) { struct urb *urb; etrax_urb_priv_t *urb_priv; @@ -3280,7 +3280,7 @@ static void etrax_usb_complete_urb(struct urb *urb, int status) -static irqreturn_t etrax_usb_hc_interrupt_top_half(int irq, void *vhc, struct pt_regs *regs) +static irqreturn_t etrax_usb_hc_interrupt_top_half(int irq, void *vhc) { usb_interrupt_registers_t *reg; unsigned long flags; diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index a72e041..2718b5d 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c @@ -418,7 +418,7 @@ static void postproc_atl_queue(struct isp116x *isp116x) processed urbs. */ static void finish_request(struct isp116x *isp116x, struct isp116x_ep *ep, - struct urb *urb, struct pt_regs *regs) + struct urb *urb) __releases(isp116x->lock) __acquires(isp116x->lock) { unsigned i; @@ -432,7 +432,7 @@ __releases(isp116x->lock) __acquires(isp116x->lock) urb_dbg(urb, "Finish"); spin_unlock(&isp116x->lock); - usb_hcd_giveback_urb(isp116x_to_hcd(isp116x), urb, regs); + usb_hcd_giveback_urb(isp116x_to_hcd(isp116x), urb); spin_lock(&isp116x->lock); /* take idle endpoints out of the schedule */ @@ -568,7 +568,7 @@ static void start_atl_transfers(struct isp116x *isp116x) /* Finish the processed transfers */ -static void finish_atl_transfers(struct isp116x *isp116x, struct pt_regs *regs) +static void finish_atl_transfers(struct isp116x *isp116x) { struct isp116x_ep *ep; struct urb *urb; @@ -590,12 +590,12 @@ static void finish_atl_transfers(struct isp116x *isp116x, struct pt_regs *regs) occured, while URB_SHORT_NOT_OK was set */ if (urb && urb->status != -EINPROGRESS && ep->nextpid != USB_PID_ACK) - finish_request(isp116x, ep, urb, regs); + finish_request(isp116x, ep, urb); } atomic_dec(&isp116x->atl_finishing); } -static irqreturn_t isp116x_irq(struct usb_hcd *hcd, struct pt_regs *regs) +static irqreturn_t isp116x_irq(struct usb_hcd *hcd) { struct isp116x *isp116x = hcd_to_isp116x(hcd); u16 irqstat; @@ -608,7 +608,7 @@ static irqreturn_t isp116x_irq(struct usb_hcd *hcd, struct pt_regs *regs) if (irqstat & (HCuPINT_ATL | HCuPINT_SOF)) { ret = IRQ_HANDLED; - finish_atl_transfers(isp116x, regs); + finish_atl_transfers(isp116x); } if (irqstat & HCuPINT_OPR) { @@ -824,7 +824,7 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd, spin_lock(&urb->lock); if (urb->status != -EINPROGRESS) { spin_unlock(&urb->lock); - finish_request(isp116x, ep, urb, NULL); + finish_request(isp116x, ep, urb); ret = 0; goto fail; } @@ -870,7 +870,7 @@ static int isp116x_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) } if (urb) - finish_request(isp116x, ep, urb, NULL); + finish_request(isp116x, ep, urb); spin_unlock_irqrestore(&isp116x->lock, flags); return 0; diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index d1d68c4..9be6b30 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -261,7 +261,7 @@ static int ohci_urb_enqueue ( if (urb->status != -EINPROGRESS) { spin_unlock (&urb->lock); urb->hcpriv = urb_priv; - finish_urb (ohci, urb, NULL); + finish_urb (ohci, urb); retval = 0; goto fail; } @@ -337,7 +337,7 @@ static int ohci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) * any more ... just clean up every urb's memory. */ if (urb->hcpriv) - finish_urb (ohci, urb, NULL); + finish_urb (ohci, urb); } spin_unlock_irqrestore (&ohci->lock, flags); return 0; @@ -369,7 +369,7 @@ rescan: if (!HC_IS_RUNNING (hcd->state)) { sanitize: ed->state = ED_IDLE; - finish_unlinks (ohci, 0, NULL); + finish_unlinks (ohci, 0); } switch (ed->state) { @@ -691,7 +691,7 @@ retry: /* an interrupt happens */ -static irqreturn_t ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs) +static irqreturn_t ohci_irq (struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci (hcd); struct ohci_regs __iomem *regs = ohci->regs; @@ -747,7 +747,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs) if (HC_IS_RUNNING(hcd->state)) ohci_writel (ohci, OHCI_INTR_WDH, ®s->intrdisable); spin_lock (&ohci->lock); - dl_done_list (ohci, ptregs); + dl_done_list (ohci); spin_unlock (&ohci->lock); if (HC_IS_RUNNING(hcd->state)) ohci_writel (ohci, OHCI_INTR_WDH, ®s->intrenable); @@ -760,7 +760,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs) */ spin_lock (&ohci->lock); if (ohci->ed_rm_list) - finish_unlinks (ohci, ohci_frame_no(ohci), ptregs); + finish_unlinks (ohci, ohci_frame_no(ohci)); if ((ints & OHCI_INTR_SF) != 0 && !ohci->ed_rm_list && HC_IS_RUNNING(hcd->state)) ohci_writel (ohci, OHCI_INTR_SF, ®s->intrdisable); @@ -852,7 +852,7 @@ static int ohci_restart (struct ohci_hcd *ohci) urb->status = -ESHUTDOWN; spin_unlock (&urb->lock); } - finish_unlinks (ohci, 0, NULL); + finish_unlinks (ohci, 0); spin_unlock_irq(&ohci->lock); /* paranoia, in case that didn't work: */ diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index ec75774..6f11359 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -47,8 +47,8 @@ static void ohci_rhsc_enable (struct usb_hcd *hcd) #define OHCI_SCHED_ENABLES \ (OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_PLE|OHCI_CTRL_IE) -static void dl_done_list (struct ohci_hcd *, struct pt_regs *); -static void finish_unlinks (struct ohci_hcd *, u16 , struct pt_regs *); +static void dl_done_list (struct ohci_hcd *); +static void finish_unlinks (struct ohci_hcd *, u16); static int ohci_rh_suspend (struct ohci_hcd *ohci, int autostop) __releases(ohci->lock) @@ -94,8 +94,8 @@ __acquires(ohci->lock) msleep (8); spin_lock_irq (&ohci->lock); } - dl_done_list (ohci, NULL); - finish_unlinks (ohci, ohci_frame_no(ohci), NULL); + dl_done_list (ohci); + finish_unlinks (ohci, ohci_frame_no(ohci)); /* maybe resume can wake root hub */ if (device_may_wakeup(&ohci_to_hcd(ohci)->self.root_hub->dev) || diff --git a/drivers/usb/host/ohci-pnx4008.c b/drivers/usb/host/ohci-pnx4008.c index 82cb22f..2dbb774 100644 --- a/drivers/usb/host/ohci-pnx4008.c +++ b/drivers/usb/host/ohci-pnx4008.c @@ -262,6 +262,7 @@ static const struct hc_driver ohci_pnx4008_hc_driver = { */ .start = ohci_pnx4008_start, .stop = ohci_stop, + .shutdown = ohci_shutdown, /* * managing i/o requests and associated device resources @@ -280,7 +281,11 @@ static const struct hc_driver ohci_pnx4008_hc_driver = { */ .hub_status_data = ohci_hub_status_data, .hub_control = ohci_hub_control, - + .hub_irq_enable = ohci_rhsc_enable, +#ifdef CONFIG_PM + .bus_suspend = ohci_bus_suspend, + .bus_resume = ohci_bus_resume, +#endif .start_port_reset = ohci_start_port_reset, }; @@ -410,8 +415,6 @@ static int __devinit usb_hcd_pnx4008_probe(struct platform_device *pdev) goto out4; } - hcd->self.hcpriv = (void *)hcd; - pnx4008_start_hc(); platform_set_drvdata(pdev, hcd); ohci = hcd_to_ohci(hcd); diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index e372306..fe1fe2f 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c @@ -7,6 +7,8 @@ * This file is licenced under the GPL. */ +#include <linux/irq.h> + static void urb_free_priv (struct ohci_hcd *hc, urb_priv_t *urb_priv) { int last = urb_priv->length - 1; @@ -34,7 +36,7 @@ static void urb_free_priv (struct ohci_hcd *hc, urb_priv_t *urb_priv) * PRECONDITION: ohci lock held, irqs blocked. */ static void -finish_urb (struct ohci_hcd *ohci, struct urb *urb, struct pt_regs *regs) +finish_urb (struct ohci_hcd *ohci, struct urb *urb) __releases(ohci->lock) __acquires(ohci->lock) { @@ -73,7 +75,7 @@ __acquires(ohci->lock) /* urb->complete() can reenter this HCD */ spin_unlock (&ohci->lock); - usb_hcd_giveback_urb (ohci_to_hcd(ohci), urb, regs); + usb_hcd_giveback_urb (ohci_to_hcd(ohci), urb); spin_lock (&ohci->lock); /* stop periodic dma if it's not needed */ @@ -910,7 +912,7 @@ static struct td *dl_reverse_done_list (struct ohci_hcd *ohci) /* there are some urbs/eds to unlink; called in_irq(), with HCD locked */ static void -finish_unlinks (struct ohci_hcd *ohci, u16 tick, struct pt_regs *regs) +finish_unlinks (struct ohci_hcd *ohci, u16 tick) { struct ed *ed, **last; @@ -923,7 +925,7 @@ rescan_all: /* only take off EDs that the HC isn't using, accounting for * frame counter wraps and EDs with partially retired TDs */ - if (likely (regs && HC_IS_RUNNING(ohci_to_hcd(ohci)->state))) { + if (likely (HC_IS_RUNNING(ohci_to_hcd(ohci)->state))) { if (tick_before (tick, ed->tick)) { skip_ed: last = &ed->ed_next; @@ -990,7 +992,7 @@ rescan_this: /* if URB is done, clean up */ if (urb_priv->td_cnt == urb_priv->length) { modified = completed = 1; - finish_urb (ohci, urb, regs); + finish_urb (ohci, urb); } } if (completed && !list_empty (&ed->td_list)) @@ -1068,7 +1070,7 @@ rescan_this: * scanning the (re-reversed) donelist as this does. */ static void -dl_done_list (struct ohci_hcd *ohci, struct pt_regs *regs) +dl_done_list (struct ohci_hcd *ohci) { struct td *td = dl_reverse_done_list (ohci); @@ -1084,7 +1086,7 @@ dl_done_list (struct ohci_hcd *ohci, struct pt_regs *regs) /* If all this urb's TDs are done, call complete() */ if (urb_priv->td_cnt == urb_priv->length) - finish_urb (ohci, urb, regs); + finish_urb (ohci, urb); /* clean schedule: unlink EDs that are no longer busy */ if (list_empty (&ed->td_list)) { diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index 3a586aa..5fa5647 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c @@ -428,7 +428,6 @@ static void finish_request( struct sl811 *sl811, struct sl811h_ep *ep, struct urb *urb, - struct pt_regs *regs, int status ) __releases(sl811->lock) __acquires(sl811->lock) { @@ -444,7 +443,7 @@ static void finish_request( spin_unlock(&urb->lock); spin_unlock(&sl811->lock); - usb_hcd_giveback_urb(sl811_to_hcd(sl811), urb, regs); + usb_hcd_giveback_urb(sl811_to_hcd(sl811), urb); spin_lock(&sl811->lock); /* leave active endpoints in the schedule */ @@ -484,7 +483,7 @@ static void finish_request( } static void -done(struct sl811 *sl811, struct sl811h_ep *ep, u8 bank, struct pt_regs *regs) +done(struct sl811 *sl811, struct sl811h_ep *ep, u8 bank) { u8 status; struct urb *urb; @@ -608,7 +607,7 @@ done(struct sl811 *sl811, struct sl811h_ep *ep, u8 bank, struct pt_regs *regs) } if (urb && (urbstat != -EINPROGRESS || urb->status != -EINPROGRESS)) - finish_request(sl811, ep, urb, regs, urbstat); + finish_request(sl811, ep, urb, urbstat); } static inline u8 checkdone(struct sl811 *sl811) @@ -641,7 +640,7 @@ static inline u8 checkdone(struct sl811 *sl811) return irqstat; } -static irqreturn_t sl811h_irq(struct usb_hcd *hcd, struct pt_regs *regs) +static irqreturn_t sl811h_irq(struct usb_hcd *hcd) { struct sl811 *sl811 = hcd_to_sl811(hcd); u8 irqstat; @@ -670,13 +669,13 @@ retry: * issued ... that's fine if they're different endpoints. */ if (irqstat & SL11H_INTMASK_DONE_A) { - done(sl811, sl811->active_a, SL811_EP_A(SL811_HOST_BUF), regs); + done(sl811, sl811->active_a, SL811_EP_A(SL811_HOST_BUF)); sl811->active_a = NULL; sl811->stat_a++; } #ifdef USE_B if (irqstat & SL11H_INTMASK_DONE_B) { - done(sl811, sl811->active_b, SL811_EP_B(SL811_HOST_BUF), regs); + done(sl811, sl811->active_b, SL811_EP_B(SL811_HOST_BUF)); sl811->active_b = NULL; sl811->stat_b++; } @@ -723,7 +722,7 @@ retry: container_of(sl811->active_a ->hep->urb_list.next, struct urb, urb_list), - NULL, -ESHUTDOWN); + -ESHUTDOWN); sl811->active_a = NULL; } #ifdef USE_B @@ -957,7 +956,7 @@ static int sl811h_urb_enqueue( spin_lock(&urb->lock); if (urb->status != -EINPROGRESS) { spin_unlock(&urb->lock); - finish_request(sl811, ep, urb, NULL, 0); + finish_request(sl811, ep, urb, 0); retval = 0; goto fail; } @@ -1026,7 +1025,7 @@ static int sl811h_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) } if (urb) - finish_request(sl811, ep, urb, NULL, 0); + finish_request(sl811, ep, urb, 0); else VDBG("dequeue, urb %p active %s; wait4irq\n", urb, (sl811->active_a == ep) ? "A" : "B"); @@ -1083,7 +1082,7 @@ sl811h_hub_status_data(struct usb_hcd *hcd, char *buf) */ local_irq_save(flags); if (!timer_pending(&sl811->timer)) { - if (sl811h_irq( /* ~0, */ hcd, NULL) != IRQ_NONE) + if (sl811h_irq( /* ~0, */ hcd) != IRQ_NONE) sl811->stat_lost++; } local_irq_restore(flags); diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index cb2e2a6..32c635e 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c @@ -35,7 +35,6 @@ * via an ELAN U132 adapter. * */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/moduleparam.h> @@ -558,7 +557,7 @@ static void u132_hcd_giveback_urb(struct u132 *u132, struct u132_endp *endp, u132_ring_queue_work(u132, ring, 0); up(&u132->scheduler_lock); u132_endp_put_kref(u132, endp); - usb_hcd_giveback_urb(hcd, urb, NULL); + usb_hcd_giveback_urb(hcd, urb); return; } @@ -591,7 +590,7 @@ static void u132_hcd_abandon_urb(struct u132 *u132, struct u132_endp *endp, endp->active = 0; spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); kfree(urbq); - } usb_hcd_giveback_urb(hcd, urb, NULL); + } usb_hcd_giveback_urb(hcd, urb); return; } @@ -2435,7 +2434,7 @@ static int dequeue_from_overflow_chain(struct u132 *u132, endp->queue_size -= 1; urb->error_count = 0; urb->hcpriv = NULL; - usb_hcd_giveback_urb(hcd, urb, NULL); + usb_hcd_giveback_urb(hcd, urb); return 0; } else continue; @@ -2513,7 +2512,7 @@ static int u132_endp_urb_dequeue(struct u132 *u132, struct u132_endp *endp, kfree(urbq); } urb->error_count = 0; urb->hcpriv = NULL; - usb_hcd_giveback_urb(hcd, urb, NULL); + usb_hcd_giveback_urb(hcd, urb); return 0; } else if (list_empty(&endp->urb_more)) { dev_err(&u132->platform_dev->dev, "urb=%p not found in " diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index eb4eab9..226bf3d 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -40,6 +40,7 @@ #include <linux/dma-mapping.h> #include <linux/usb.h> #include <linux/bitops.h> +#include <linux/dmi.h> #include <asm/uaccess.h> #include <asm/io.h> @@ -196,12 +197,42 @@ static int resume_detect_interrupts_are_broken(struct uhci_hcd *uhci) return 0; } +static int remote_wakeup_is_broken(struct uhci_hcd *uhci) +{ + static struct dmi_system_id broken_wakeup_table[] = { + { + .ident = "Asus A7V8X", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK"), + DMI_MATCH(DMI_BOARD_NAME, "A7V8X"), + DMI_MATCH(DMI_BOARD_VERSION, "REV 1.xx"), + } + }, + { } + }; + int port; + + /* One of Asus's motherboards has a bug which causes it to + * wake up immediately from suspend-to-RAM if any of the ports + * are connected. In such cases we will not set EGSM. + */ + if (dmi_check_system(broken_wakeup_table)) { + for (port = 0; port < uhci->rh_numports; ++port) { + if (inw(uhci->io_addr + USBPORTSC1 + port * 2) & + USBPORTSC_CCS) + return 1; + } + } + + return 0; +} + static void suspend_rh(struct uhci_hcd *uhci, enum uhci_rh_state new_state) __releases(uhci->lock) __acquires(uhci->lock) { int auto_stop; - int int_enable; + int int_enable, egsm_enable; auto_stop = (new_state == UHCI_RH_AUTO_STOPPED); dev_dbg(&uhci_to_hcd(uhci)->self.root_hub->dev, @@ -217,15 +248,18 @@ __acquires(uhci->lock) } /* Enable resume-detect interrupts if they work. - * Then enter Global Suspend mode, still configured. + * Then enter Global Suspend mode if _it_ works, still configured. */ + egsm_enable = USBCMD_EGSM; uhci->working_RD = 1; int_enable = USBINTR_RESUME; - if (resume_detect_interrupts_are_broken(uhci)) { + if (remote_wakeup_is_broken(uhci)) + egsm_enable = 0; + if (resume_detect_interrupts_are_broken(uhci) || !egsm_enable) uhci->working_RD = int_enable = 0; - } + outw(int_enable, uhci->io_addr + USBINTR); - outw(USBCMD_EGSM | USBCMD_CF, uhci->io_addr + USBCMD); + outw(egsm_enable | USBCMD_CF, uhci->io_addr + USBCMD); mb(); udelay(5); @@ -252,7 +286,7 @@ __acquires(uhci->lock) uhci->is_stopped = UHCI_IS_STOPPED; uhci_to_hcd(uhci)->poll_rh = !int_enable; - uhci_scan_schedule(uhci, NULL); + uhci_scan_schedule(uhci); uhci_fsbr_off(uhci); } @@ -309,7 +343,7 @@ __acquires(uhci->lock) mod_timer(&uhci_to_hcd(uhci)->rh_timer, jiffies); } -static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs) +static irqreturn_t uhci_irq(struct usb_hcd *hcd) { struct uhci_hcd *uhci = hcd_to_uhci(hcd); unsigned short status; @@ -358,7 +392,7 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs) usb_hcd_poll_rh_status(hcd); else { spin_lock_irqsave(&uhci->lock, flags); - uhci_scan_schedule(uhci, regs); + uhci_scan_schedule(uhci); spin_unlock_irqrestore(&uhci->lock, flags); } @@ -671,7 +705,7 @@ static void uhci_stop(struct usb_hcd *hcd) spin_lock_irq(&uhci->lock); if (test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) && !uhci->dead) uhci_hc_died(uhci); - uhci_scan_schedule(uhci, NULL); + uhci_scan_schedule(uhci); spin_unlock_irq(&uhci->lock); del_timer_sync(&uhci->fsbr_timer); diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c index 16fb72e..f8347f1 100644 --- a/drivers/usb/host/uhci-hub.c +++ b/drivers/usb/host/uhci-hub.c @@ -176,7 +176,7 @@ static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf) spin_lock_irqsave(&uhci->lock, flags); - uhci_scan_schedule(uhci, NULL); + uhci_scan_schedule(uhci); if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags) || uhci->dead) goto done; uhci_check_ports(uhci); diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index 431e8f3..06115f2 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c @@ -1244,7 +1244,7 @@ done: * Finish unlinking an URB and give it back */ static void uhci_giveback_urb(struct uhci_hcd *uhci, struct uhci_qh *qh, - struct urb *urb, struct pt_regs *regs) + struct urb *urb) __releases(uhci->lock) __acquires(uhci->lock) { @@ -1293,7 +1293,7 @@ __acquires(uhci->lock) } spin_unlock(&uhci->lock); - usb_hcd_giveback_urb(uhci_to_hcd(uhci), urb, regs); + usb_hcd_giveback_urb(uhci_to_hcd(uhci), urb); spin_lock(&uhci->lock); /* If the queue is now empty, we can unlink the QH and give up its @@ -1313,8 +1313,7 @@ __acquires(uhci->lock) (qh->state == QH_STATE_UNLINKING && \ uhci->frame_number + uhci->is_stopped != qh->unlink_frame) -static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh, - struct pt_regs *regs) +static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) { struct urb_priv *urbp; struct urb *urb; @@ -1347,7 +1346,7 @@ static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh, return; } - uhci_giveback_urb(uhci, qh, urb, regs); + uhci_giveback_urb(uhci, qh, urb); if (status < 0 && qh->type != USB_ENDPOINT_XFER_ISOC) break; } @@ -1372,7 +1371,7 @@ restart: qh->is_stopped = 0; return; } - uhci_giveback_urb(uhci, qh, urb, regs); + uhci_giveback_urb(uhci, qh, urb); goto restart; } } @@ -1487,7 +1486,7 @@ done: /* * Process events in the schedule, but only in one thread at a time */ -static void uhci_scan_schedule(struct uhci_hcd *uhci, struct pt_regs *regs) +static void uhci_scan_schedule(struct uhci_hcd *uhci) { int i; struct uhci_qh *qh; @@ -1515,7 +1514,7 @@ rescan: struct uhci_qh, node); if (uhci_advance_check(uhci, qh)) { - uhci_scan_qh(uhci, qh, regs); + uhci_scan_qh(uhci, qh); if (qh->state == QH_STATE_ACTIVE) { uhci_urbp_wants_fsbr(uhci, list_entry(qh->queue.next, struct urb_priv, node)); |