On Monday 26 November 2012 13:29:09 Daniele Palmas wrote: > Ok. Do you have any hint for adding the code in the proper place?
First we need to define a new quirk. > >> According to the USB 2.0 specs it seems to me that this feature should > >> be always requested when suspending a device, so probably the driver > >> behavior is not correct. > > > > Hm. Which part of the spec do you base this on? > > > > The doc is "Universal Serial Bus Specification" revision 2.0 paragraph > 10.5.4.5, if I am not misunderstanding the topic. > > Here > > http://msdn.microsoft.com/en-us/library/windows/hardware/ff537628%28v=vs.85%29.aspx > > there is an interpretation coming from Microsoft > > "In USB terminology, a USB device is enabled for remote wakeup when > its DEVICE_REMOTE_WAKEUP feature is set. The USB specification > specifies that host software must set the remote wakeup feature on a > device "only just prior" to putting the device to sleep." Well, that tells us when to set DEVICE_REMOTE_WAKEUP, if we want remote wakeup, not whether we want it at all. > Modem is registered to the network. Host suspended, I want my device > to wake up the host when it receives, for example, a call or an sms. If you want a device to wake up the system, you need to declare it a wakeup source in sysfs. > This doesn't happen if the driver doesn't send the > DEVICE_REMOTE_WAKEUP request. Moreover without this request the modem > is bricked. That is not good. > I understand that probably there are problems in the firmware of the > modem (because it should not brick), but I'm trying to find a > workaround to have things working. I am attaching a patch to introduce a new quirk type. You need to add your device to the list of quirky devices in drivers/usb/core/quirks.c with the new quirk type. You cannot solve this in the cdc-acm driver because there is an unsolvable race if your system is suspended after the device is enumerated but before the driver is loaded. Would you test this? Regards Oliver
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 6056db7..094c3c9 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -1097,7 +1097,10 @@ static int usb_suspend_device(struct usb_device *udev, pm_message_t msg) if (udev->dev.driver) udriver = to_usb_device_driver(udev->dev.driver); else { - udev->do_remote_wakeup = 0; + if (udev->quirks & USB_QUIRK_NEEDS_REMOTE_WAKEUP) + udev->do_remote_wakeup = 1; + else + udev->do_remote_wakeup = 0; udriver = &usb_generic_driver; } status = udriver->suspend(udev, msg); diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h index 52f944d..a5d1995 100644 --- a/include/linux/usb/quirks.h +++ b/include/linux/usb/quirks.h @@ -30,4 +30,7 @@ descriptor */ #define USB_QUIRK_DELAY_INIT 0x00000040 +/* device requires remote wakeup to survive suspend/resume */ +#define USB_QUIRK_NEEDS_REMOTE_WAKEUP 0x00000080 + #endif /* __LINUX_USB_QUIRKS_H */