[PATCH] USB UHCI: remove the FSBR kernel timer
This patch (as558) removes from the UHCI driver a kernel timer used for checking Full Speed Bandwidth Reclamation (FSBR). The checking can be done during normal root-hub polling; it doesn't need a separate timer. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
f1a15606d5
commit
1f09df8bfe
|
@ -97,14 +97,9 @@ static void uhci_get_current_frame_number(struct uhci_hcd *uhci);
|
|||
/* 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
|
||||
|
@ -160,7 +155,6 @@ static void hc_died(struct uhci_hcd *uhci)
|
|||
{
|
||||
reset_hc(uhci);
|
||||
uhci->hc_inaccessible = 1;
|
||||
del_timer(&uhci->stall_timer);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -287,8 +281,11 @@ __acquires(uhci->lock)
|
|||
/* 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();
|
||||
|
@ -315,7 +312,6 @@ __acquires(uhci->lock)
|
|||
|
||||
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);
|
||||
|
@ -335,7 +331,6 @@ static void start_rh(struct uhci_hcd *uhci)
|
|||
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)
|
||||
|
@ -374,20 +369,6 @@ __acquires(uhci->lock)
|
|||
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);
|
||||
|
@ -418,8 +399,10 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
|
|||
"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);
|
||||
}
|
||||
|
@ -427,10 +410,11 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
|
|||
|
||||
if (status & USBSTS_RD)
|
||||
usb_hcd_poll_rh_status(hcd);
|
||||
|
||||
else {
|
||||
spin_lock_irqsave(&uhci->lock, flags);
|
||||
uhci_scan_schedule(uhci, regs);
|
||||
spin_unlock_irqrestore(&uhci->lock, flags);
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
@ -595,10 +579,6 @@ static int uhci_start(struct usb_hcd *hcd)
|
|||
|
||||
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) {
|
||||
|
@ -745,11 +725,11 @@ static void uhci_stop(struct usb_hcd *hcd)
|
|||
struct uhci_hcd *uhci = hcd_to_uhci(hcd);
|
||||
|
||||
spin_lock_irq(&uhci->lock);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -811,13 +791,12 @@ static int uhci_suspend(struct usb_hcd *hcd, pm_message_t message)
|
|||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -850,8 +829,11 @@ static int uhci_resume(struct usb_hcd *hcd)
|
|||
|
||||
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
|
||||
|
|
|
@ -345,9 +345,6 @@ enum uhci_rh_state {
|
|||
|
||||
/*
|
||||
* 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 {
|
||||
|
||||
|
@ -360,8 +357,6 @@ 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 */
|
||||
|
||||
|
@ -380,6 +375,8 @@ struct uhci_hcd {
|
|||
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 */
|
||||
|
@ -405,9 +402,7 @@ struct uhci_hcd {
|
|||
/* 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 */
|
||||
};
|
||||
|
|
|
@ -145,15 +145,16 @@ static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf)
|
|||
{
|
||||
struct uhci_hcd *uhci = hcd_to_uhci(hcd);
|
||||
unsigned long flags;
|
||||
int status;
|
||||
int status = 0;
|
||||
|
||||
spin_lock_irqsave(&uhci->lock, flags);
|
||||
if (uhci->hc_inaccessible) {
|
||||
status = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
uhci_scan_schedule(uhci, NULL);
|
||||
if (uhci->hc_inaccessible)
|
||||
goto done;
|
||||
check_fsbr(uhci);
|
||||
uhci_check_ports(uhci);
|
||||
|
||||
status = get_hub_status_data(uhci, buf);
|
||||
|
||||
switch (uhci->rh_state) {
|
||||
|
|
|
@ -33,7 +33,7 @@ static void uhci_free_pending_tds(struct uhci_hcd *uhci);
|
|||
static inline void uhci_set_next_interrupt(struct uhci_hcd *uhci)
|
||||
{
|
||||
if (uhci->is_stopped)
|
||||
mod_timer(&uhci->stall_timer, jiffies);
|
||||
mod_timer(&uhci_to_hcd(uhci)->rh_timer, jiffies);
|
||||
uhci->term_td->status |= cpu_to_le32(TD_CTRL_IOC);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue