|
|
|
RE: Remote wakeup timing | |
| [Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] |
|
>
> > > A better approach might be to have ehci_bus_resume check the port
> > > statuses before turning on CMD_RUN, and re-suspend any enabled port
> > > that isn't already suspended. Then when the controller starts
> sending
> > > SOF packets, the host shouldn't think the device had disconnected.
> > > Would that solve your problem?
>
> What about this patch?
>
Good patch, Alan. Only one thing is that it needs a delay between
re-suspend, and send resume again. (Sorry, I can't find the detail
delay time between suspend and resume signal at usb2.0 spec).
I will test this patch, and give you a response.
> Alan Stern
>
>
>
> drivers/usb/host/ehci-hub.c | 63
> +++++++++++++++++++++++++++++++++++++++++---
> 1 file changed, 59 insertions(+), 4 deletions(-)
>
> Index: usb-3.4/drivers/usb/host/ehci-hub.c
> ===================================================================
> --- usb-3.4.orig/drivers/usb/host/ehci-hub.c
> +++ usb-3.4/drivers/usb/host/ehci-hub.c
> @@ -329,6 +329,59 @@ static int ehci_bus_suspend (struct usb_
> }
>
>
> +static void ehci_resuspend_ports(struct ehci_hcd *ehci)
> +{
> + u32 temp;
> + int i;
> + unsigned long resuspend_needed = 0;
> +
> + /*
> + * If a remote wakeup request was received, the controller will
> + * already have begun resume signalling on that port. Some buggy
> + * controllers (e.g., Synopsys) automatically turn off the resume
> + * signal after 20 ms, leaving the port active and using high-speed
> + * signalling. But since CMD_RUN has been turned off, the device
> + * will not have received any SOF packets, so it will have gone
> + * back into suspend, using full-speed signalling. As a result,
> + * when the controller starts sending SOF packets again, it will
> + * think the device has disconnected.
> + *
> + * To avoid this problem, check to see if any enabled ports are
> + * resumed or resuming, and force them back into suspend before
> + * turning on CMD_RUN.
> + */
> + i = HCS_N_PORTS(ehci->hcs_params);
> + while (i--) {
> + temp = ehci_readl(ehci, &ehci->regs->port_status[i]);
> + temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
> + if ((temp & PORT_PE) && (!(temp & PORT_SUSPEND) ||
> + (temp & PORT_RESUME))) {
> + __set_bit(i, &resuspend_needed);
> + temp &= ~PORT_RESUME;
> + ehci_writel(ehci, temp, &ehci->regs->port_status[i]);
> + }
> + }
> +
> + /* Give the port time to leave suspend, then resuspend it */
> + if (resuspend_needed) {
> + spin_unlock_irq(&ehci->lock);
> + msleep(3);
> + spin_lock_irq(&ehci->lock);
> +
> + i = HCS_N_PORTS(ehci->hcs_params);
> + while (i--) {
> + if (test_bit(i, &resuspend_needed)) {
> + temp = ehci_readl(ehci,
> + &ehci->regs->port_status[i]);
> + temp &= ~PORT_RWC_BITS;
> + temp |= PORT_SUSPEND;
> + ehci_writel(ehci, temp,
> + &ehci->regs->port_status[i]);
> + }
> + }
> + }
> +}
> +
> /* caller has locked the root hub, and should reset/reinit on error */
> static int ehci_bus_resume (struct usb_hcd *hcd)
> {
> @@ -373,10 +426,6 @@ static int ehci_bus_resume (struct usb_h
> ehci_writel(ehci, ehci->periodic_dma, &ehci->regs->frame_list);
> ehci_writel(ehci, (u32) ehci->async->qh_dma, &ehci->regs-
> >async_next);
>
> - /* restore CMD_RUN, framelist size, and irq threshold */
> - ehci_writel(ehci, ehci->command, &ehci->regs->command);
> - ehci->rh_state = EHCI_RH_RUNNING;
> -
> /* Some controller/firmware combinations need a delay during which
> * they set up the port statuses. See Bugzilla #8190. */
> spin_unlock_irq(&ehci->lock);
> @@ -402,6 +451,12 @@ static int ehci_bus_resume (struct usb_h
> spin_lock_irq(&ehci->lock);
> }
>
> + ehci_resuspend_ports(ehci);
> +
> + /* restore CMD_RUN, framelist size, and irq threshold */
> + ehci_writel(ehci, ehci->command, &ehci->regs->command);
> + ehci->rh_state = EHCI_RH_RUNNING;
> +
> /* manually resume the ports we suspended during bus_suspend() */
> i = HCS_N_PORTS (ehci->hcs_params);
> while (i--) {
>
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html

[Linux Media] [Video for Linux] [Linux Input] [Linux Audio Users] [Photo] [Yosemite News] [Yosemite Photos] [Free Online Dating] [Linux Kernel] [Linux SCSI] [Old Linux USB Devel Archive] [More Archives]
![]() |
![]() |