]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
USB: EHCI: fix remote-wakeup regression
authorAlan Stern <stern@rowland.harvard.edu>
Tue, 20 May 2008 20:58:58 +0000 (16:58 -0400)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 6 Aug 2008 17:11:05 +0000 (10:11 -0700)
commit d1f114d12bb4db3147e1b1342ae31083c5a79c84 upstream

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: Alan Stern <stern@rowland.harvard.edu>
Acked-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/host/ehci-hub.c
drivers/usb/host/ehci.h

index 4e065e556e4b802c8c83a507973fb31a56931460..fe930d5be965db0727d5e9056e7643f19adb63a6 100644 (file)
@@ -621,7 +621,7 @@ static int ehci_hub_control (
                        }
                        break;
                case USB_PORT_FEAT_C_SUSPEND:
-                       /* we auto-clear this feature */
+                       clear_bit(wIndex, &ehci->port_c_suspend);
                        break;
                case USB_PORT_FEAT_POWER:
                        if (HCS_PPC (ehci->hcs_params))
@@ -700,7 +700,7 @@ static int ehci_hub_control (
                        /* resume completed? */
                        else if (time_after_eq(jiffies,
                                        ehci->reset_done[wIndex])) {
-                               status |= 1 << USB_PORT_FEAT_C_SUSPEND;
+                               set_bit(wIndex, &ehci->port_c_suspend);
                                ehci->reset_done[wIndex] = 0;
 
                                /* stop resume signaling */
@@ -777,6 +777,8 @@ static int ehci_hub_control (
                        status |= 1 << USB_PORT_FEAT_RESET;
                if (temp & PORT_POWER)
                        status |= 1 << USB_PORT_FEAT_POWER;
+               if (test_bit(wIndex, &ehci->port_c_suspend))
+                       status |= 1 << USB_PORT_FEAT_C_SUSPEND;
 
 #ifndef        EHCI_VERBOSE_DEBUG
        if (status & ~0xffff)   /* only if wPortChange is interesting */
index 888e81e607c84b7a1a4b77f33c04ae5a588c4da6..4769ba26654075860b2dac54cf0f754109771c19 100644 (file)
@@ -97,6 +97,8 @@ struct ehci_hcd {                     /* one per controller */
                        dedicated to the companion controller */
        unsigned long           owned_ports;            /* which ports are
                        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 ...) */
        struct dma_pool         *qh_pool;       /* qh per active urb */