On 06/12/2014 08:11 PM, Alan Stern wrote: > On Wed, 11 Jun 2014, Oliver Neukum wrote: > >> Alan, >> >> I don't like this, but it might be enough to simply >> revert 0aa2832dd0d9d8609fd8f15139bc7572541a1215. >> I am afraid we have to deal with real hardware, not specs. > > Toralf and Adam: > > Does this patch (for 3.14 or 3.15) fix the problems you observed? > At my system (32 bit stable Gentoo at a ThinkkPad T420) it is not fixed - tested against 3.14.7 and 3.15.0. > Alan Stern > > > > Index: usb-3.15/drivers/usb/core/hub.c > =================================================================== > --- usb-3.15.orig/drivers/usb/core/hub.c > +++ usb-3.15/drivers/usb/core/hub.c > @@ -2922,15 +2922,6 @@ static int usb_disable_remote_wakeup(str > USB_CTRL_SET_TIMEOUT); > } > > -/* Count of wakeup-enabled devices at or below udev */ > -static unsigned wakeup_enabled_descendants(struct usb_device *udev) > -{ > - struct usb_hub *hub = usb_hub_to_struct_hub(udev); > - > - return udev->do_remote_wakeup + > - (hub ? hub->wakeup_enabled_descendants : 0); > -} > - > /* > * usb_port_suspend - suspend a usb device's upstream port > * @udev: device that's no longer in active use, not a root hub > @@ -2971,12 +2962,6 @@ static unsigned wakeup_enabled_descendan > * Linux (2.6) currently has NO mechanisms to initiate that: no khubd > * timer, no SRP, no requests through sysfs. > * > - * If Runtime PM isn't enabled or used, non-SuperSpeed devices may not get > - * suspended until their bus goes into global suspend (i.e., the root > - * hub is suspended). Nevertheless, we change @udev->state to > - * USB_STATE_SUSPENDED as this is the device's "logical" state. The actual > - * upstream port setting is stored in @udev->port_is_suspended. > - * > * Returns 0 on success, else negative errno. > */ > int usb_port_suspend(struct usb_device *udev, pm_message_t msg) > @@ -2985,7 +2970,6 @@ int usb_port_suspend(struct usb_device * > struct usb_port *port_dev = hub->ports[udev->portnum - 1]; > int port1 = udev->portnum; > int status; > - bool really_suspend = true; > > /* enable remote wakeup when appropriate; this lets the device > * wake up the upstream hub (including maybe the root hub). > @@ -3024,25 +3008,9 @@ int usb_port_suspend(struct usb_device * > /* see 7.1.7.6 */ > if (hub_is_superspeed(hub->hdev)) > status = hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_U3); > - > - /* > - * For system suspend, we do not need to enable the suspend feature > - * on individual USB-2 ports. The devices will automatically go > - * into suspend a few ms after the root hub stops sending packets. > - * The USB 2.0 spec calls this "global suspend". > - * > - * However, many USB hubs have a bug: They don't relay wakeup requests > - * from a downstream port if the port's suspend feature isn't on. > - * Therefore we will turn on the suspend feature if udev or any of its > - * descendants is enabled for remote wakeup. > - */ > - else if (PMSG_IS_AUTO(msg) || wakeup_enabled_descendants(udev) > 0) > + else > status = set_port_feature(hub->hdev, port1, > - USB_PORT_FEAT_SUSPEND); > - else { > - really_suspend = false; > - status = 0; > - } > + USB_PORT_FEAT_SUSPEND); > if (status) { > dev_dbg(hub->intfdev, "can't suspend port %d, status %d\n", > port1, status); > @@ -3067,12 +3035,10 @@ int usb_port_suspend(struct usb_device * > dev_dbg(&udev->dev, "usb %ssuspend, wakeup %d\n", > (PMSG_IS_AUTO(msg) ? "auto-" : ""), > udev->do_remote_wakeup); > - if (really_suspend) { > - udev->port_is_suspended = 1; > + udev->port_is_suspended = 1; > > - /* device has up to 10 msec to fully suspend */ > - msleep(10); > - } > + /* device has up to 10 msec to fully suspend */ > + msleep(10); > usb_set_device_state(udev, USB_STATE_SUSPENDED); > } > > @@ -3343,11 +3309,7 @@ static int hub_suspend(struct usb_interf > unsigned port1; > int status; > > - /* > - * Warn if children aren't already suspended. > - * Also, add up the number of wakeup-enabled descendants. > - */ > - hub->wakeup_enabled_descendants = 0; > + /* Warn if children aren't already suspended */ > for (port1 = 1; port1 <= hdev->maxchild; port1++) { > struct usb_device *udev; > > @@ -3358,9 +3320,6 @@ static int hub_suspend(struct usb_interf > if (PMSG_IS_AUTO(msg)) > return -EBUSY; > } > - if (udev) > - hub->wakeup_enabled_descendants += > - wakeup_enabled_descendants(udev); > } > > if (hdev->do_remote_wakeup && hub->quirk_check_port_auto_suspend) { > Index: usb-3.15/drivers/usb/core/hub.h > =================================================================== > --- usb-3.15.orig/drivers/usb/core/hub.h > +++ usb-3.15/drivers/usb/core/hub.h > @@ -59,9 +59,6 @@ struct usb_hub { > struct usb_tt tt; /* Transaction Translator */ > > unsigned mA_per_port; /* current for each child */ > -#ifdef CONFIG_PM > - unsigned wakeup_enabled_descendants; > -#endif > > unsigned limited_power:1; > unsigned quiescing:1; > > -- Toralf -- 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