diff options
author | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-02 03:41:58 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-02 03:41:58 +0300 |
commit | 9641219825a54249d77d7aa1afa7d874a05c7f90 (patch) | |
tree | 94dae67a8804a070e2597b931d1e3335f08389fc /drivers/usb/host | |
parent | 72a73a69f6a79266b8b4b18f796907b73a5c01e3 (diff) | |
parent | 94fcda1f8ab5e0cacc381c5ca1cc9aa6ad523576 (diff) | |
download | linux-9641219825a54249d77d7aa1afa7d874a05c7f90.tar.xz |
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6: (103 commits)
usbcore: remove unused argument in autosuspend
USB: keep count of unsuspended children
USB hub: simplify remote-wakeup handling
USB: struct usb_device: change flag to bitflag
OHCI: make autostop conditional on CONFIG_PM
USB: Add autosuspend support to the hub driver
EHCI: Fix root-hub and port suspend/resume problems
USB: create a new thread for every USB device found during the probe sequence
USB: add driver for the USB debug devices
USB: added dynamic major number for USB endpoints
USB: pegasus error path not resetting task's state
USB: endianness fix for asix.c
USB: build the appledisplay driver
USB serial: replace kmalloc+memset with kzalloc
USB: hid-core: canonical defines for Apple USB device IDs
USB: idmouse cleanup
USB: make drivers/usb/core/driver.c:usb_device_match() static
USB: lh7a40x_udc remove double declaration
USB: pxa2xx_udc recognizes ixp425 rev b0 chip
usbtouchscreen: add support for DMC TSC-10/25 devices
...
Diffstat (limited to 'drivers/usb/host')
-rw-r--r-- | drivers/usb/host/ehci-hcd.c | 16 | ||||
-rw-r--r-- | drivers/usb/host/ehci-hub.c | 104 | ||||
-rw-r--r-- | drivers/usb/host/ehci-pci.c | 40 | ||||
-rw-r--r-- | drivers/usb/host/ehci.h | 1 | ||||
-rw-r--r-- | drivers/usb/host/ohci-hcd.c | 10 | ||||
-rw-r--r-- | drivers/usb/host/ohci-hub.c | 172 | ||||
-rw-r--r-- | drivers/usb/host/u132-hcd.c | 8 |
7 files changed, 205 insertions, 146 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 9030994aba98..025d33313681 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -126,6 +126,11 @@ static unsigned park = 0; module_param (park, uint, S_IRUGO); MODULE_PARM_DESC (park, "park setting; 1-3 back-to-back async packets"); +/* for flakey hardware, ignore overcurrent indicators */ +static int ignore_oc = 0; +module_param (ignore_oc, bool, S_IRUGO); +MODULE_PARM_DESC (ignore_oc, "ignore bogus hardware overcurrent indications"); + #define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT) /*-------------------------------------------------------------------------*/ @@ -541,9 +546,10 @@ static int ehci_run (struct usb_hcd *hcd) temp = HC_VERSION(readl (&ehci->caps->hc_capbase)); ehci_info (ehci, - "USB %x.%x started, EHCI %x.%02x, driver %s\n", + "USB %x.%x started, EHCI %x.%02x, driver %s%s\n", ((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f), - temp >> 8, temp & 0xff, DRIVER_VERSION); + temp >> 8, temp & 0xff, DRIVER_VERSION, + ignore_oc ? ", overcurrent ignored" : ""); writel (INTR_MASK, &ehci->regs->intr_enable); /* Turn On Interrupts */ @@ -613,9 +619,8 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) unsigned i = HCS_N_PORTS (ehci->hcs_params); /* resume root hub? */ - status = readl (&ehci->regs->command); - if (!(status & CMD_RUN)) - writel (status | CMD_RUN, &ehci->regs->command); + if (!(readl(&ehci->regs->command) & CMD_RUN)) + usb_hcd_resume_root_hub(hcd); while (i--) { int pstatus = readl (&ehci->regs->port_status [i]); @@ -632,7 +637,6 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) */ ehci->reset_done [i] = jiffies + msecs_to_jiffies (20); ehci_dbg (ehci, "port %d remote wakeup\n", i + 1); - usb_hcd_resume_root_hub(hcd); } } diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 1b20722c102b..bfe5f307cba6 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -34,6 +34,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci (hcd); int port; + int mask; if (time_before (jiffies, ehci->next_statechange)) msleep(5); @@ -51,14 +52,25 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) ehci->reclaim_ready = 1; ehci_work(ehci); - /* suspend any active/unsuspended ports, maybe allow wakeup */ + /* Unlike other USB host controller types, EHCI doesn't have + * any notion of "global" or bus-wide suspend. The driver has + * to manually suspend all the active unsuspended ports, and + * then manually resume them in the bus_resume() routine. + */ + ehci->bus_suspended = 0; while (port--) { u32 __iomem *reg = &ehci->regs->port_status [port]; u32 t1 = readl (reg) & ~PORT_RWC_BITS; u32 t2 = t1; - if ((t1 & PORT_PE) && !(t1 & PORT_OWNER)) + /* keep track of which ports we suspend */ + if ((t1 & PORT_PE) && !(t1 & PORT_OWNER) && + !(t1 & PORT_SUSPEND)) { t2 |= PORT_SUSPEND; + set_bit(port, &ehci->bus_suspended); + } + + /* enable remote wakeup on all ports */ if (device_may_wakeup(&hcd->self.root_hub->dev)) t2 |= PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E; else @@ -76,6 +88,13 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) ehci_halt (ehci); hcd->state = HC_STATE_SUSPENDED; + /* allow remote wakeup */ + mask = INTR_MASK; + if (!device_may_wakeup(&hcd->self.root_hub->dev)) + mask &= ~STS_PCD; + writel(mask, &ehci->regs->intr_enable); + readl(&ehci->regs->intr_enable); + ehci->next_statechange = jiffies + msecs_to_jiffies(10); spin_unlock_irq (&ehci->lock); return 0; @@ -88,7 +107,6 @@ static int ehci_bus_resume (struct usb_hcd *hcd) struct ehci_hcd *ehci = hcd_to_ehci (hcd); u32 temp; int i; - int intr_enable; if (time_before (jiffies, ehci->next_statechange)) msleep(5); @@ -100,31 +118,30 @@ static int ehci_bus_resume (struct usb_hcd *hcd) * the last user of the controller, not reset/pm hardware keeping * state we gave to it. */ + temp = readl(&ehci->regs->intr_enable); + ehci_dbg(ehci, "resume root hub%s\n", temp ? "" : " after power loss"); - /* re-init operational registers in case we lost power */ - if (readl (&ehci->regs->intr_enable) == 0) { - /* at least some APM implementations will try to deliver - * IRQs right away, so delay them until we're ready. - */ - intr_enable = 1; - writel (0, &ehci->regs->segment); - writel (ehci->periodic_dma, &ehci->regs->frame_list); - writel ((u32)ehci->async->qh_dma, &ehci->regs->async_next); - } else - intr_enable = 0; - ehci_dbg(ehci, "resume root hub%s\n", - intr_enable ? " after power loss" : ""); + /* at least some APM implementations will try to deliver + * IRQs right away, so delay them until we're ready. + */ + writel(0, &ehci->regs->intr_enable); + + /* re-init operational registers */ + writel(0, &ehci->regs->segment); + writel(ehci->periodic_dma, &ehci->regs->frame_list); + writel((u32) ehci->async->qh_dma, &ehci->regs->async_next); /* restore CMD_RUN, framelist size, and irq threshold */ writel (ehci->command, &ehci->regs->command); - /* take ports out of suspend */ + /* manually resume the ports we suspended during bus_suspend() */ i = HCS_N_PORTS (ehci->hcs_params); while (i--) { temp = readl (&ehci->regs->port_status [i]); temp &= ~(PORT_RWC_BITS | PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E); - if (temp & PORT_SUSPEND) { + if (test_bit(i, &ehci->bus_suspended) && + (temp & PORT_SUSPEND)) { ehci->reset_done [i] = jiffies + msecs_to_jiffies (20); temp |= PORT_RESUME; } @@ -134,11 +151,12 @@ static int ehci_bus_resume (struct usb_hcd *hcd) mdelay (20); while (i--) { temp = readl (&ehci->regs->port_status [i]); - if ((temp & PORT_SUSPEND) == 0) - continue; - temp &= ~(PORT_RWC_BITS | PORT_RESUME); - writel (temp, &ehci->regs->port_status [i]); - ehci_vdbg (ehci, "resumed port %d\n", i + 1); + if (test_bit(i, &ehci->bus_suspended) && + (temp & PORT_SUSPEND)) { + temp &= ~(PORT_RWC_BITS | PORT_RESUME); + writel (temp, &ehci->regs->port_status [i]); + ehci_vdbg (ehci, "resumed port %d\n", i + 1); + } } (void) readl (&ehci->regs->command); @@ -157,8 +175,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd) hcd->state = HC_STATE_RUNNING; /* Now we can safely re-enable irqs */ - if (intr_enable) - writel (INTR_MASK, &ehci->regs->intr_enable); + writel(INTR_MASK, &ehci->regs->intr_enable); spin_unlock_irq (&ehci->lock); return 0; @@ -218,6 +235,7 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf) { struct ehci_hcd *ehci = hcd_to_ehci (hcd); u32 temp, status = 0; + u32 mask; int ports, i, retval = 1; unsigned long flags; @@ -233,6 +251,18 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf) retval++; } + /* Some boards (mostly VIA?) report bogus overcurrent indications, + * causing massive log spam unless we completely ignore them. It + * may be relevant that VIA VT8235 controlers, where PORT_POWER is + * always set, seem to clear PORT_OCC and PORT_CSC when writing to + * PORT_POWER; that's surprising, but maybe within-spec. + */ + if (!ignore_oc) + mask = PORT_CSC | PORT_PEC | PORT_OCC; + else + mask = PORT_CSC | PORT_PEC; + // PORT_RESUME from hardware ~= PORT_STAT_C_SUSPEND + /* no hub change reports (bit 0) for now (power, ...) */ /* port N changes (bit N)? */ @@ -250,8 +280,7 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf) } if (!(temp & PORT_CONNECT)) ehci->reset_done [i] = 0; - if ((temp & (PORT_CSC | PORT_PEC | PORT_OCC)) != 0 - // PORT_STAT_C_SUSPEND? + if ((temp & mask) != 0 || ((temp & PORT_RESUME) != 0 && time_after (jiffies, ehci->reset_done [i]))) { @@ -319,6 +348,7 @@ static int ehci_hub_control ( u32 temp, status; unsigned long flags; int retval = 0; + unsigned selector; /* * FIXME: support SetPortFeatures USB_PORT_FEAT_INDICATOR. @@ -417,7 +447,7 @@ static int ehci_hub_control ( status |= 1 << USB_PORT_FEAT_C_CONNECTION; if (temp & PORT_PEC) status |= 1 << USB_PORT_FEAT_C_ENABLE; - if (temp & PORT_OCC) + if ((temp & PORT_OCC) && !ignore_oc) status |= 1 << USB_PORT_FEAT_C_OVER_CURRENT; /* whoever resumes must GetPortStatus to complete it!! */ @@ -506,6 +536,8 @@ static int ehci_hub_control ( } break; case SetPortFeature: + selector = wIndex >> 8; + wIndex &= 0xff; if (!wIndex || wIndex > ports) goto error; wIndex--; @@ -559,6 +591,22 @@ static int ehci_hub_control ( } writel (temp, &ehci->regs->port_status [wIndex]); break; + + /* For downstream facing ports (these): one hub port is put + * into test mode according to USB2 11.24.2.13, then the hub + * must be reset (which for root hub now means rmmod+modprobe, + * or else system reboot). See EHCI 2.3.9 and 4.14 for info + * about the EHCI-specific stuff. + */ + case USB_PORT_FEAT_TEST: + if (!selector || selector > 5) + goto error; + ehci_quiesce(ehci); + ehci_halt(ehci); + temp |= selector << 16; + writel (temp, &ehci->regs->port_status [wIndex]); + break; + default: goto error; } diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index e51c1ed81ac4..4bc7970ba3ef 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -257,9 +257,7 @@ static int ehci_pci_suspend(struct usb_hcd *hcd, pm_message_t message) static int ehci_pci_resume(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); - unsigned port; struct pci_dev *pdev = to_pci_dev(hcd->self.controller); - int retval = -EINVAL; // maybe restore FLADJ @@ -269,27 +267,19 @@ static int ehci_pci_resume(struct usb_hcd *hcd) /* Mark hardware accessible again as we are out of D3 state by now */ set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - /* If CF is clear, we lost PCI Vaux power and need to restart. */ - if (readl(&ehci->regs->configured_flag) != FLAG_CF) - goto restart; - - /* If any port is suspended (or owned by the companion), - * we know we can/must resume the HC (and mustn't reset it). - * We just defer that to the root hub code. + /* If CF is still set, we maintained PCI Vaux power. + * Just undo the effect of ehci_pci_suspend(). */ - for (port = HCS_N_PORTS(ehci->hcs_params); port > 0; ) { - u32 status; - port--; - status = readl(&ehci->regs->port_status [port]); - if (!(status & PORT_POWER)) - continue; - if (status & (PORT_SUSPEND | PORT_RESUME | PORT_OWNER)) { - usb_hcd_resume_root_hub(hcd); - return 0; - } + if (readl(&ehci->regs->configured_flag) == FLAG_CF) { + int mask = INTR_MASK; + + if (!device_may_wakeup(&hcd->self.root_hub->dev)) + mask &= ~STS_PCD; + writel(mask, &ehci->regs->intr_enable); + readl(&ehci->regs->intr_enable); + return 0; } -restart: ehci_dbg(ehci, "lost power, restarting\n"); usb_root_hub_lost_power(hcd->self.root_hub); @@ -307,13 +297,15 @@ restart: ehci_work(ehci); spin_unlock_irq(&ehci->lock); - /* restart; khubd will disconnect devices */ - retval = ehci_run(hcd); - /* here we "know" root ports should always stay powered */ ehci_port_power(ehci, 1); - return retval; + writel(ehci->command, &ehci->regs->command); + writel(FLAG_CF, &ehci->regs->configured_flag); + readl(&ehci->regs->command); /* unblock posted writes */ + + hcd->state = HC_STATE_SUSPENDED; + return 0; } #endif diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index bbc3082a73d7..74dbc6c8228f 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -74,6 +74,7 @@ struct ehci_hcd { /* one per controller */ /* per root hub port */ unsigned long reset_done [EHCI_MAX_ROOT_PORTS]; + unsigned long bus_suspended; /* per-HC memory pools (could be per-bus, but ...) */ struct dma_pool *qh_pool; /* qh per active urb */ diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index ea4714e557e4..a95275a401b1 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -729,6 +729,16 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) ohci->next_statechange = jiffies + STATECHANGE_DELAY; ohci_writel(ohci, OHCI_INTR_RD | OHCI_INTR_RHSC, ®s->intrstatus); + + /* NOTE: Vendors didn't always make the same implementation + * choices for RHSC. Many followed the spec; RHSC triggers + * on an edge, like setting and maybe clearing a port status + * change bit. With others it's level-triggered, active + * until khubd clears all the port status change bits. We'll + * always disable it here and rely on polling until khubd + * re-enables it. + */ + ohci_writel(ohci, OHCI_INTR_RHSC, ®s->intrdisable); usb_hcd_poll_rh_status(hcd); } diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 6995ea36f2e8..2441642cb7b4 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -41,7 +41,11 @@ static void ohci_rhsc_enable (struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci (hcd); - ohci_writel (ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable); + spin_lock_irq(&ohci->lock); + if (!ohci->autostop) + del_timer(&hcd->rh_timer); /* Prevent next poll */ + ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable); + spin_unlock_irq(&ohci->lock); } #define OHCI_SCHED_ENABLES \ @@ -50,6 +54,9 @@ static void ohci_rhsc_enable (struct usb_hcd *hcd) static void dl_done_list (struct ohci_hcd *); static void finish_unlinks (struct ohci_hcd *, u16); +#ifdef CONFIG_PM +static int ohci_restart(struct ohci_hcd *ohci); + static int ohci_rh_suspend (struct ohci_hcd *ohci, int autostop) __releases(ohci->lock) __acquires(ohci->lock) @@ -132,8 +139,6 @@ static inline struct ed *find_head (struct ed *ed) return ed; } -static int ohci_restart (struct ohci_hcd *ohci); - /* caller has locked the root hub */ static int ohci_rh_resume (struct ohci_hcd *ohci) __releases(ohci->lock) @@ -169,7 +174,7 @@ __acquires(ohci->lock) break; case OHCI_USB_RESUME: /* HCFS changes sometime after INTR_RD */ - ohci_info(ohci, "%swakeup\n", + ohci_dbg(ohci, "%swakeup root hub\n", autostopped ? "auto-" : ""); break; case OHCI_USB_OPER: @@ -181,7 +186,6 @@ __acquires(ohci->lock) ohci_dbg (ohci, "lost power\n"); status = -EBUSY; } -#ifdef CONFIG_PM if (status == -EBUSY) { if (!autostopped) { spin_unlock_irq (&ohci->lock); @@ -191,25 +195,12 @@ __acquires(ohci->lock) } return status; } -#endif if (status != -EINPROGRESS) return status; if (autostopped) goto skip_resume; spin_unlock_irq (&ohci->lock); - temp = ohci->num_ports; - while (temp--) { - u32 stat = ohci_readl (ohci, - &ohci->regs->roothub.portstatus [temp]); - - /* force global, not selective, resume */ - if (!(stat & RH_PS_PSS)) - continue; - ohci_writel (ohci, RH_PS_POCI, - &ohci->regs->roothub.portstatus [temp]); - } - /* Some controllers (lucent erratum) need extra-long delays */ msleep (20 /* usb 11.5.1.10 */ + 12 /* 32 msec counter */ + 1); @@ -217,6 +208,7 @@ __acquires(ohci->lock) temp &= OHCI_CTRL_HCFS; if (temp != OHCI_USB_RESUME) { ohci_err (ohci, "controller won't resume\n"); + spin_lock_irq(&ohci->lock); return -EBUSY; } @@ -296,8 +288,6 @@ skip_resume: return 0; } -#ifdef CONFIG_PM - static int ohci_bus_suspend (struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci (hcd); @@ -335,6 +325,83 @@ static int ohci_bus_resume (struct usb_hcd *hcd) return rc; } +/* Carry out polling-, autostop-, and autoresume-related state changes */ +static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed, + int any_connected) +{ + int poll_rh = 1; + + switch (ohci->hc_control & OHCI_CTRL_HCFS) { + + case OHCI_USB_OPER: + /* keep on polling until we know a device is connected + * and RHSC is enabled */ + if (!ohci->autostop) { + if (any_connected || + !device_may_wakeup(&ohci_to_hcd(ohci) + ->self.root_hub->dev)) { + if (ohci_readl(ohci, &ohci->regs->intrenable) & + OHCI_INTR_RHSC) + poll_rh = 0; + } else { + ohci->autostop = 1; + ohci->next_statechange = jiffies + HZ; + } + + /* if no devices have been attached for one second, autostop */ + } else { + if (changed || any_connected) { + ohci->autostop = 0; + ohci->next_statechange = jiffies + + STATECHANGE_DELAY; + } else if (time_after_eq(jiffies, + ohci->next_statechange) + && !ohci->ed_rm_list + && !(ohci->hc_control & + OHCI_SCHED_ENABLES)) { + ohci_rh_suspend(ohci, 1); + } + } + break; + + /* if there is a port change, autostart or ask to be resumed */ + case OHCI_USB_SUSPEND: + case OHCI_USB_RESUME: + if (changed) { + if (ohci->autostop) + ohci_rh_resume(ohci); + else + usb_hcd_resume_root_hub(ohci_to_hcd(ohci)); + } else { + /* everything is idle, no need for polling */ + poll_rh = 0; + } + break; + } + return poll_rh; +} + +#else /* CONFIG_PM */ + +static inline int ohci_rh_resume(struct ohci_hcd *ohci) +{ + return 0; +} + +/* Carry out polling-related state changes. + * autostop isn't used when CONFIG_PM is turned off. + */ +static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed, + int any_connected) +{ + int poll_rh = 1; + + /* keep on polling until RHSC is enabled */ + if (ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC) + poll_rh = 0; + return poll_rh; +} + #endif /* CONFIG_PM */ /*-------------------------------------------------------------------------*/ @@ -346,7 +413,7 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf) { struct ohci_hcd *ohci = hcd_to_ohci (hcd); int i, changed = 0, length = 1; - int any_connected = 0, rhsc_enabled = 1; + int any_connected = 0; unsigned long flags; spin_lock_irqsave (&ohci->lock, flags); @@ -387,67 +454,8 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf) } } - /* NOTE: vendors didn't always make the same implementation - * choices for RHSC. Sometimes it triggers on an edge (like - * setting and maybe clearing a port status change bit); and - * it's level-triggered on other silicon, active until khubd - * clears all active port status change bits. If it's still - * set (level-triggered) we must disable it and rely on - * polling until khubd re-enables it. - */ - if (ohci_readl (ohci, &ohci->regs->intrstatus) & OHCI_INTR_RHSC) { - ohci_writel (ohci, OHCI_INTR_RHSC, &ohci->regs->intrdisable); - (void) ohci_readl (ohci, &ohci->regs->intrdisable); - rhsc_enabled = 0; - } - hcd->poll_rh = 1; - - /* carry out appropriate state changes */ - switch (ohci->hc_control & OHCI_CTRL_HCFS) { - - case OHCI_USB_OPER: - /* keep on polling until we know a device is connected - * and RHSC is enabled */ - if (!ohci->autostop) { - if (any_connected) { - if (rhsc_enabled) - hcd->poll_rh = 0; - } else { - ohci->autostop = 1; - ohci->next_statechange = jiffies + HZ; - } - - /* if no devices have been attached for one second, autostop */ - } else { - if (changed || any_connected) { - ohci->autostop = 0; - ohci->next_statechange = jiffies + - STATECHANGE_DELAY; - } else if (device_may_wakeup(&hcd->self.root_hub->dev) - && time_after_eq(jiffies, - ohci->next_statechange) - && !ohci->ed_rm_list - && !(ohci->hc_control & - OHCI_SCHED_ENABLES)) { - ohci_rh_suspend (ohci, 1); - } - } - break; - - /* if there is a port change, autostart or ask to be resumed */ - case OHCI_USB_SUSPEND: - case OHCI_USB_RESUME: - if (changed) { - if (ohci->autostop) - ohci_rh_resume (ohci); - else - usb_hcd_resume_root_hub (hcd); - } else { - /* everything is idle, no need for polling */ - hcd->poll_rh = 0; - } - break; - } + hcd->poll_rh = ohci_root_hub_state_changes(ohci, changed, + any_connected); done: spin_unlock_irqrestore (&ohci->lock, flags); diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index a00d1595656c..ef54e310bfc4 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c @@ -71,7 +71,7 @@ static int distrust_firmware = 1; module_param(distrust_firmware, bool, 0); MODULE_PARM_DESC(distrust_firmware, "true to distrust firmware power/overcurren" "t setup"); -DECLARE_WAIT_QUEUE_HEAD(u132_hcd_wait); +static DECLARE_WAIT_QUEUE_HEAD(u132_hcd_wait); /* * u132_module_lock exists to protect access to global variables * @@ -205,11 +205,7 @@ struct u132 { struct u132_port port[MAX_U132_PORTS]; struct u132_endp *endp[MAX_U132_ENDPS]; }; -int usb_ftdi_elan_read_reg(struct platform_device *pdev, u32 *data); -int usb_ftdi_elan_read_pcimem(struct platform_device *pdev, u8 addressofs, - u8 width, u32 *data); -int usb_ftdi_elan_write_pcimem(struct platform_device *pdev, u8 addressofs, - u8 width, u32 data); + /* * these cannot be inlines because we need the structure offset!! * Does anyone have a better way????? |