On Mon, Jun 08, 2009 at 07:47:06PM -0400, Alan Stern wrote: > It should not make any difference. Can you provide dmesg output with > CONFIG_USB_DEBUG enabled, together with a usbmon trace? You might also > want to #define VERBOSE_DEBUG at the start of drivers.c (before the > #include lines). With autosuspend enabled I get the following: usb usb1: usb auto-resume ehci_hcd 0000:00:1a.7: resume root hub usb usb1: usb_resume_device: status 0 hub 1-0:1.0: hub_resume hub 1-0:1.0: port 2: status 0507 change 0000 hub 1-0:1.0: port 5: status 0507 change 0000 hub 1-0:1.0: usb_resume_interface: status 0 usb usb1: usb_resume_both: status 0 usb usb1: usb_autoresume_device: status 0 cnt 1 usb 1-2: usb auto-resume hub 1-0:1.0: state 7 ports 6 chg 0000 evt 0000 hub 1-0:1.0: usb_autopm_get_interface: status 0 cnt 2 usb usb1: usb_suspend_both: status -16 hub 1-0:1.0: usb_autopm_set_interface: status -16 cnt 0 ehci_hcd 0000:00:1a.7: GetStatus port 2 status 001005 POWER sig=se0 PE CONNECT usb 1-2: finish resume usb 1-2: usb_resume_device: status 0 usb 1-2:1.0: usb_resume_interface: status 0 usb 1-2:1.1: usb_resume_interface: status 0 qcserial 1-2:1.2: usb_resume_interface: status 0 usb 1-2:1.3: usb_resume_interface: status 0 usb 1-2: usb_resume_both: status 0 qcserial 1-2:1.2: usb_autopm_get_interface: status 0 cnt 1 qcserial ttyUSB0: usb_serial_generic_open - failed resubmitting read urb, error -22 usb 1-2: usb_suspend_both: status -11 qcserial 1-2:1.2: usb_autopm_put_interface: status -11 cnt 0 usb 1-2:1.0: usb_suspend_interface: status 0 usb 1-2:1.1: usb_suspend_interface: status 0 qcserial 1-2:1.2: usb_suspend_interface: status 0 usb 1-2:1.3: usb_suspend_interface: status 0 usb 1-2: usb auto-suspend usb 1-2: usb_suspend_device: status 0 usb usb1: usb_suspend_both: status -11 usb usb1: usb_autosuspend_device: cnt 0 usb 1-2: usb_suspend_both: status 0 hub 1-0:1.0: hub_suspend hub 1-0:1.0: usb_suspend_interface: status 0 usb usb1: bus auto-suspend ehci_hcd 0000:00:1a.7: suspend root hub usb usb1: usb_suspend_device: status 0 usb usb1: usb_suspend_both: status 0 If I then do echo on >/sys/bus/usb/devices/1-2/power/level I get usb usb1: usb auto-resume ehci_hcd 0000:00:1a.7: resume root hub usb usb1: usb_resume_device: status 0 hub 1-0:1.0: hub_resume hub 1-0:1.0: port 2: status 0507 change 0000 hub 1-0:1.0: port 5: status 0507 change 0000 hub 1-0:1.0: usb_resume_interface: status 0 usb usb1: usb_resume_both: status 0 usb usb1: usb_autoresume_device: status 0 cnt 1 usb 1-2: usb resume hub 1-0:1.0: state 7 ports 6 chg 0000 evt 0000 hub 1-0:1.0: usb_autopm_get_interface: status 0 cnt 2 usb usb1: usb_suspend_both: status -16 hub 1-0:1.0: usb_autopm_set_interface: status -16 cnt 0 ehci_hcd 0000:00:1a.7: GetStatus port 2 status 001005 POWER sig=se0 PE CONNECT usb 1-2: finish resume usb 1-2: usb_resume_device: status 0 usb 1-2:1.0: usb_resume_interface: status 0 usb 1-2:1.1: usb_resume_interface: status 0 qcserial 1-2:1.2: usb_resume_interface: status 0 usb 1-2:1.3: usb_resume_interface: status 0 usb 1-2: usb_resume_both: status 0 usb 1-2: usb_suspend_both: status -1 usb 1-2: usb_try_autosuspend_device: cnt 0 qcserial 1-2:1.2: usb_autopm_get_interface: status 0 cnt 1 and the device can be opened correctly. As far as I can tell these are substantively identical, which leaves me confused. Could it just be a timing thing? The following patch makes it work, but seems suboptimal, especially given the empty reset_resume... diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index 7528b8d..2f60bfa 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c @@ -15,6 +15,7 @@ #include <linux/tty_flip.h> #include <linux/usb.h> #include <linux/usb/serial.h> +#include <linux/usb/quirks.h> #define DRIVER_AUTHOR "Qualcomm Inc" #define DRIVER_DESC "Qualcomm USB Serial driver" @@ -51,16 +52,6 @@ static struct usb_device_id id_table[] = { }; MODULE_DEVICE_TABLE(usb, id_table); -static struct usb_driver qcdriver = { - .name = "qcserial", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = id_table, - .suspend = usb_serial_suspend, - .resume = usb_serial_resume, - .supports_autosuspend = true, -}; - static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) { int retval = -ENODEV; @@ -74,6 +65,8 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber; dbg("This Interface = %d", ifnum); + serial->dev->quirks |= USB_QUIRK_RESET_RESUME; + switch (nintf) { case 1: /* QDL mode */ @@ -122,6 +115,24 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) return retval; } +static int qc_reset_resume(struct usb_interface *intf) +{ + return 0; +} + +static struct usb_driver qcdriver = { + .name = "qcserial", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = id_table, + .suspend = usb_serial_suspend, + .resume = usb_serial_resume, + .reset_resume = qc_reset_resume, + .supports_autosuspend = true, +}; + static struct usb_serial_driver qcdevice = { .driver = { .owner = THIS_MODULE, -- Matthew Garrett | mjg59@xxxxxxxxxxxxx -- 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