From 014e73c99aa408f3766afe8d11a1caa3a708b736 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Sat, 9 Apr 2005 17:24:42 -0400 Subject: [PATCH] [PATCH] USB UHCI: subroutine reordering This patch moves a few subroutines around in the uhci-hcd source file. Nothing else is changed. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/uhci-hcd.c | 287 ++++++++++++++++++++++---------------------- 1 file changed, 143 insertions(+), 144 deletions(-) diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 49bd83e..8b6c87e 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -90,7 +90,6 @@ static char *errbuf; static kmem_cache_t *uhci_up_cachep; /* urb_priv */ static void uhci_get_current_frame_number(struct uhci_hcd *uhci); -static void hc_state_transitions(struct uhci_hcd *uhci); /* If a transfer is still active after this much time, turn off FSBR */ #define IDLE_TIMEOUT msecs_to_jiffies(50) @@ -105,96 +104,43 @@ static void hc_state_transitions(struct uhci_hcd *uhci); #include "uhci-debug.c" #include "uhci-q.c" -static int init_stall_timer(struct usb_hcd *hcd); - -static void stall_callback(unsigned long ptr) -{ - struct usb_hcd *hcd = (struct usb_hcd *)ptr; - struct uhci_hcd *uhci = hcd_to_uhci(hcd); - struct urb_priv *up; - unsigned long flags; - - spin_lock_irqsave(&uhci->lock, flags); - uhci_scan_schedule(uhci, NULL); - - list_for_each_entry(up, &uhci->urb_list, urb_list) { - struct urb *u = up->urb; - - spin_lock(&u->lock); - - /* Check if the FSBR timed out */ - if (up->fsbr && !up->fsbr_timeout && time_after_eq(jiffies, up->fsbrtime + IDLE_TIMEOUT)) - uhci_fsbr_timeout(uhci, u); - - spin_unlock(&u->lock); - } - - /* Really disable FSBR */ - if (!uhci->fsbr && uhci->fsbrtimeout && time_after_eq(jiffies, uhci->fsbrtimeout)) { - uhci->fsbrtimeout = 0; - uhci->skel_term_qh->link = UHCI_PTR_TERM; - } - - /* Poll for and perform state transitions */ - hc_state_transitions(uhci); - if (unlikely(uhci->suspended_ports && uhci->state != UHCI_SUSPENDED)) - uhci_check_ports(uhci); - - init_stall_timer(hcd); - spin_unlock_irqrestore(&uhci->lock, flags); -} - -static int init_stall_timer(struct usb_hcd *hcd) +static int ports_active(struct uhci_hcd *uhci) { - struct uhci_hcd *uhci = hcd_to_uhci(hcd); + unsigned long io_addr = uhci->io_addr; + int connection = 0; + int i; - init_timer(&uhci->stall_timer); - uhci->stall_timer.function = stall_callback; - uhci->stall_timer.data = (unsigned long)hcd; - uhci->stall_timer.expires = jiffies + msecs_to_jiffies(100); - add_timer(&uhci->stall_timer); + for (i = 0; i < uhci->rh_numports; i++) + connection |= (inw(io_addr + USBPORTSC1 + i * 2) & USBPORTSC_CCS); - return 0; + return connection; } -static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs) +static int suspend_allowed(struct uhci_hcd *uhci) { - struct uhci_hcd *uhci = hcd_to_uhci(hcd); unsigned long io_addr = uhci->io_addr; - unsigned short status; + int i; - /* - * Read the interrupt status, and write it back to clear the - * interrupt cause. Contrary to the UHCI specification, the - * "HC Halted" status bit is persistent: it is RO, not R/WC. + if (to_pci_dev(uhci_dev(uhci))->vendor != PCI_VENDOR_ID_INTEL) + return 1; + + /* Some of Intel's USB controllers have a bug that causes false + * resume indications if any port has an over current condition. + * To prevent problems, we will not allow a global suspend if + * any ports are OC. + * + * Some motherboards using Intel's chipsets (but not using all + * the USB ports) appear to hardwire the over current inputs active + * to disable the USB ports. */ - status = inw(io_addr + USBSTS); - if (!(status & ~USBSTS_HCH)) /* shared interrupt, not mine */ - return IRQ_NONE; - outw(status, io_addr + USBSTS); /* Clear it */ - if (status & ~(USBSTS_USBINT | USBSTS_ERROR | USBSTS_RD)) { - if (status & USBSTS_HSE) - dev_err(uhci_dev(uhci), "host system error, " - "PCI problems?\n"); - if (status & USBSTS_HCPE) - dev_err(uhci_dev(uhci), "host controller process " - "error, something bad happened!\n"); - if ((status & USBSTS_HCH) && uhci->state > 0) { - dev_err(uhci_dev(uhci), "host controller halted, " - "very bad!\n"); - /* FIXME: Reset the controller, fix the offending TD */ - } + /* check for over current condition on any port */ + for (i = 0; i < uhci->rh_numports; i++) { + if (inw(io_addr + USBPORTSC1 + i * 2) & USBPORTSC_OC) + return 0; } - if (status & USBSTS_RD) - uhci->resume_detect = 1; - - spin_lock(&uhci->lock); - uhci_scan_schedule(uhci, regs); - spin_unlock(&uhci->lock); - - return IRQ_HANDLED; + return 1; } static void reset_hc(struct uhci_hcd *uhci) @@ -276,43 +222,46 @@ static void wakeup_hc(struct uhci_hcd *uhci) } } -static int ports_active(struct uhci_hcd *uhci) +static int start_hc(struct uhci_hcd *uhci) { unsigned long io_addr = uhci->io_addr; - int connection = 0; - int i; - - for (i = 0; i < uhci->rh_numports; i++) - connection |= (inw(io_addr + USBPORTSC1 + i * 2) & USBPORTSC_CCS); + int timeout = 10; - return connection; -} + /* + * Reset the HC - this will force us to get a + * new notification of any already connected + * ports due to the virtual disconnect that it + * implies. + */ + outw(USBCMD_HCRESET, io_addr + USBCMD); + while (inw(io_addr + USBCMD) & USBCMD_HCRESET) { + if (--timeout < 0) { + dev_err(uhci_dev(uhci), "USBCMD_HCRESET timed out!\n"); + return -ETIMEDOUT; + } + msleep(1); + } -static int suspend_allowed(struct uhci_hcd *uhci) -{ - unsigned long io_addr = uhci->io_addr; - int i; + /* Mark controller as running before we enable interrupts */ + uhci_to_hcd(uhci)->state = HC_STATE_RUNNING; - if (to_pci_dev(uhci_dev(uhci))->vendor != PCI_VENDOR_ID_INTEL) - return 1; + /* Turn on PIRQ and all interrupts */ + pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, + USBLEGSUP_DEFAULT); + outw(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP, + io_addr + USBINTR); - /* Some of Intel's USB controllers have a bug that causes false - * resume indications if any port has an over current condition. - * To prevent problems, we will not allow a global suspend if - * any ports are OC. - * - * Some motherboards using Intel's chipsets (but not using all - * the USB ports) appear to hardwire the over current inputs active - * to disable the USB ports. - */ + /* Start at frame 0 */ + outw(0, io_addr + USBFRNUM); + outl(uhci->fl->dma_handle, io_addr + USBFLBASEADD); - /* check for over current condition on any port */ - for (i = 0; i < uhci->rh_numports; i++) { - if (inw(io_addr + USBPORTSC1 + i * 2) & USBPORTSC_OC) - return 0; - } + /* Run and mark it configured with a 64-byte max packet */ + uhci->state = UHCI_RUNNING_GRACE; + uhci->state_end = jiffies + HZ; + outw(USBCMD_RS | USBCMD_CF | USBCMD_MAXP, io_addr + USBCMD); + uhci->is_stopped = 0; - return 1; + return 0; } static void hc_state_transitions(struct uhci_hcd *uhci) @@ -353,56 +302,106 @@ static void hc_state_transitions(struct uhci_hcd *uhci) } } -/* - * Store the current frame number in uhci->frame_number if the controller - * is runnning - */ -static void uhci_get_current_frame_number(struct uhci_hcd *uhci) +static int init_stall_timer(struct usb_hcd *hcd); + +static void stall_callback(unsigned long ptr) { - if (!uhci->is_stopped) - uhci->frame_number = inw(uhci->io_addr + USBFRNUM); + struct usb_hcd *hcd = (struct usb_hcd *)ptr; + struct uhci_hcd *uhci = hcd_to_uhci(hcd); + struct urb_priv *up; + unsigned long flags; + + spin_lock_irqsave(&uhci->lock, flags); + uhci_scan_schedule(uhci, NULL); + + list_for_each_entry(up, &uhci->urb_list, urb_list) { + struct urb *u = up->urb; + + spin_lock(&u->lock); + + /* Check if the FSBR timed out */ + if (up->fsbr && !up->fsbr_timeout && time_after_eq(jiffies, up->fsbrtime + IDLE_TIMEOUT)) + uhci_fsbr_timeout(uhci, u); + + spin_unlock(&u->lock); + } + + /* Really disable FSBR */ + if (!uhci->fsbr && uhci->fsbrtimeout && time_after_eq(jiffies, uhci->fsbrtimeout)) { + uhci->fsbrtimeout = 0; + uhci->skel_term_qh->link = UHCI_PTR_TERM; + } + + /* Poll for and perform state transitions */ + hc_state_transitions(uhci); + if (unlikely(uhci->suspended_ports && uhci->state != UHCI_SUSPENDED)) + uhci_check_ports(uhci); + + init_stall_timer(hcd); + spin_unlock_irqrestore(&uhci->lock, flags); } -static int start_hc(struct uhci_hcd *uhci) +static int init_stall_timer(struct usb_hcd *hcd) { + struct uhci_hcd *uhci = hcd_to_uhci(hcd); + + init_timer(&uhci->stall_timer); + uhci->stall_timer.function = stall_callback; + uhci->stall_timer.data = (unsigned long)hcd; + uhci->stall_timer.expires = jiffies + msecs_to_jiffies(100); + add_timer(&uhci->stall_timer); + + return 0; +} + +static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs) +{ + struct uhci_hcd *uhci = hcd_to_uhci(hcd); unsigned long io_addr = uhci->io_addr; - int timeout = 10; + unsigned short status; /* - * Reset the HC - this will force us to get a - * new notification of any already connected - * ports due to the virtual disconnect that it - * implies. + * Read the interrupt status, and write it back to clear the + * interrupt cause. Contrary to the UHCI specification, the + * "HC Halted" status bit is persistent: it is RO, not R/WC. */ - outw(USBCMD_HCRESET, io_addr + USBCMD); - while (inw(io_addr + USBCMD) & USBCMD_HCRESET) { - if (--timeout < 0) { - dev_err(uhci_dev(uhci), "USBCMD_HCRESET timed out!\n"); - return -ETIMEDOUT; + status = inw(io_addr + USBSTS); + if (!(status & ~USBSTS_HCH)) /* shared interrupt, not mine */ + return IRQ_NONE; + outw(status, io_addr + USBSTS); /* Clear it */ + + if (status & ~(USBSTS_USBINT | USBSTS_ERROR | USBSTS_RD)) { + if (status & USBSTS_HSE) + dev_err(uhci_dev(uhci), "host system error, " + "PCI problems?\n"); + if (status & USBSTS_HCPE) + dev_err(uhci_dev(uhci), "host controller process " + "error, something bad happened!\n"); + if ((status & USBSTS_HCH) && uhci->state > 0) { + dev_err(uhci_dev(uhci), "host controller halted, " + "very bad!\n"); + /* FIXME: Reset the controller, fix the offending TD */ } - msleep(1); } - /* Mark controller as running before we enable interrupts */ - uhci_to_hcd(uhci)->state = HC_STATE_RUNNING; - - /* Turn on PIRQ and all interrupts */ - pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, - USBLEGSUP_DEFAULT); - outw(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP, - io_addr + USBINTR); + if (status & USBSTS_RD) + uhci->resume_detect = 1; - /* Start at frame 0 */ - outw(0, io_addr + USBFRNUM); - outl(uhci->fl->dma_handle, io_addr + USBFLBASEADD); + spin_lock(&uhci->lock); + uhci_scan_schedule(uhci, regs); + spin_unlock(&uhci->lock); - /* Run and mark it configured with a 64-byte max packet */ - uhci->state = UHCI_RUNNING_GRACE; - uhci->state_end = jiffies + HZ; - outw(USBCMD_RS | USBCMD_CF | USBCMD_MAXP, io_addr + USBCMD); - uhci->is_stopped = 0; + return IRQ_HANDLED; +} - return 0; +/* + * Store the current frame number in uhci->frame_number if the controller + * is runnning + */ +static void uhci_get_current_frame_number(struct uhci_hcd *uhci) +{ + if (!uhci->is_stopped) + uhci->frame_number = inw(uhci->io_addr + USBFRNUM); } /* -- 2.7.4