Commit d1f114d1 authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman

USB: EHCI: fix remote-wakeup regression

This patch (as1097) fixes a bug in the remote-wakeup handling in
ehci-hcd.  The driver currently does not keep track of whether the
change-suspend feature is enabled for each port; the feature is
automatically reset the first time it is read.  But recent changes to
the hub driver require that the feature be read at least twice in
order to work properly.

A bit-vector is added for storing the change-suspend feature values.
Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Acked-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 3a31155c
...@@ -609,7 +609,7 @@ static int ehci_hub_control ( ...@@ -609,7 +609,7 @@ static int ehci_hub_control (
} }
break; break;
case USB_PORT_FEAT_C_SUSPEND: case USB_PORT_FEAT_C_SUSPEND:
/* we auto-clear this feature */ clear_bit(wIndex, &ehci->port_c_suspend);
break; break;
case USB_PORT_FEAT_POWER: case USB_PORT_FEAT_POWER:
if (HCS_PPC (ehci->hcs_params)) if (HCS_PPC (ehci->hcs_params))
...@@ -688,7 +688,7 @@ static int ehci_hub_control ( ...@@ -688,7 +688,7 @@ static int ehci_hub_control (
/* resume completed? */ /* resume completed? */
else if (time_after_eq(jiffies, else if (time_after_eq(jiffies,
ehci->reset_done[wIndex])) { ehci->reset_done[wIndex])) {
status |= 1 << USB_PORT_FEAT_C_SUSPEND; set_bit(wIndex, &ehci->port_c_suspend);
ehci->reset_done[wIndex] = 0; ehci->reset_done[wIndex] = 0;
/* stop resume signaling */ /* stop resume signaling */
...@@ -765,6 +765,8 @@ static int ehci_hub_control ( ...@@ -765,6 +765,8 @@ static int ehci_hub_control (
status |= 1 << USB_PORT_FEAT_RESET; status |= 1 << USB_PORT_FEAT_RESET;
if (temp & PORT_POWER) if (temp & PORT_POWER)
status |= 1 << USB_PORT_FEAT_POWER; status |= 1 << USB_PORT_FEAT_POWER;
if (test_bit(wIndex, &ehci->port_c_suspend))
status |= 1 << USB_PORT_FEAT_C_SUSPEND;
#ifndef VERBOSE_DEBUG #ifndef VERBOSE_DEBUG
if (status & ~0xffff) /* only if wPortChange is interesting */ if (status & ~0xffff) /* only if wPortChange is interesting */
......
...@@ -97,6 +97,8 @@ struct ehci_hcd { /* one per controller */ ...@@ -97,6 +97,8 @@ struct ehci_hcd { /* one per controller */
dedicated to the companion controller */ dedicated to the companion controller */
unsigned long owned_ports; /* which ports are unsigned long owned_ports; /* which ports are
owned by the companion during a bus suspend */ owned by the companion during a bus suspend */
unsigned long port_c_suspend; /* which ports have
the change-suspend feature turned on */
/* per-HC memory pools (could be per-bus, but ...) */ /* per-HC memory pools (could be per-bus, but ...) */
struct dma_pool *qh_pool; /* qh per active urb */ struct dma_pool *qh_pool; /* qh per active urb */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment