Re: Question: USBserial suspend/resume issue

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Andreas Mohr <andi@...> writes:

> 
> Hi,
> 
> On Mon, Feb 08, 2010 at 04:19:55PM -0600, X Zhang wrote:
> > The issue I have is:
> > If I start a program which open the port of /dev/ttyUSB1 and
> > /dev/ttyUSB2 and then suspend PC (s2ram --force) and resume, I will
> > see
> > /dev/ttyUSB0
> > /dev/ttyUSB3 instead of /dev/ttyUSB1
> > /dev/ttyUSB4 instead of /dev/ttyUSB2
> > 
> > I didn't close /dev/ttyUSB1 and /dev/ttyUSB2 before PC suspend and my
> > goal is NOT to close these ports before suspend and, of course, keep
> > the port communication work after resume.
> 
> .
> .
> .
> 
> > So I think I still need to work on the driver.
> > 
> > I noticed drivers/usb/serial/generic.c doesn't have suspend and resume
> > function. so I added as below.
> > static struct usb_driver generic_driver = {
> >         .name =         "usbserial_generic",
> >         .probe =        generic_probe,
> >         .disconnect =   usb_serial_disconnect,
> >         .id_table =     generic_serial_ids,
> >         .suspend =      usb_serial_suspend,  ==> call usb-serial.c's
> > usb_serial_suspend
> >         .resume =       usb_serial_resume,   ==>  call usb-serial.c's
> > usb_serial_resume
> >         .no_dynamic_id =        1,
> > };
> > 
> > But still no luck. The result is the same.
> 
> Definitely sounds like you want to implement .reset_resume.
> These links should help:
> 
> . http://www.mjmwired.net/kernel/Documentation/usb/power-management.txt
> . reset_resume
http://www.mail-archive.com/linux-usb-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
<at> public.gmane.org/msg55788.html
> .
http://www.opensubscriber.com/message/linux-usb-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
<at> public.gmane.org/7178380.html
> . http://osdir.com/ml/linux.bluez.kernel/2008-09/msg00002.html
> . http://marc.info/?l=linux-usb&m=121483894201937&w=2
> . http://marc.info/?l=linux-usb&m=126020789127192&w=2
> 
> (guess why I had all these links ready for perusal?
> Right, ftdi_sio is waiting for the same thing to happen)
> 
> And indeed, it's annoying as hell. ;)
> 
> > I badly need instruction on this issue! Really appreciate if you could
> > provide any advice!
> 
> HTH,
> 
> Andreas Mohr
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo@...
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> 

Hi,

I did a little fix for this in ftdi driver for 2.6.27 kernel ... perhaps it can
help.
Here is the patch:

Index: ftdi_sio.c
===================================================================
--- ftdi_sio.c	(révision 347)
+++ ftdi_sio.c	(révision 421)
@@ -670,6 +670,9 @@
 	.name =		"ftdi_sio",
 	.probe =	usb_serial_probe,
 	.disconnect =	usb_serial_disconnect,
+	.suspend = usb_serial_suspend,
+	.resume = usb_serial_resume,
+	.reset_resume = usb_serial_resume,
 	.id_table =	id_table_combined,
 	.no_dynamic_id =	1,
 };
@@ -734,6 +737,14 @@
 static __u32 ftdi_232bm_baud_base_to_divisor(int baud, int base);
 static __u32 ftdi_232bm_baud_to_divisor(int baud);
 
+#ifdef CONFIG_PM
+static int ftdi_suspend(struct usb_serial *serial, pm_message_t message);
+static int ftdi_resume(struct usb_serial *serial);
+#else
+#define ftdi_suspend   NULL
+#define ftdi_resume    NULL
+#endif
+
 static struct usb_serial_driver ftdi_sio_device = {
 	.driver = {
 		.owner =	THIS_MODULE,
@@ -761,9 +772,10 @@
 	.set_termios =		ftdi_set_termios,
 	.break_ctl =		ftdi_break_ctl,
 	.shutdown =		ftdi_shutdown,
+	.suspend = ftdi_suspend,
+	.resume = ftdi_resume,
 };
 
-
 #define WDR_TIMEOUT 5000 /* default urb timeout */
 #define WDR_SHORT_TIMEOUT 1000	/* shorter urb timeout */
 
@@ -1414,6 +1426,55 @@
 	return 0;
 }
 
+#ifdef CONFIG_PM
+
+static int ftdi_suspend(struct usb_serial *serial, pm_message_t message)
+{
+	struct usb_serial_port *port;
+	struct ftdi_private *priv; //= usb_get_serial_port_data(port);
+	int i;
+
+	/* Multi-port compatibility (even if generally, there is only one port by
'chip') */
+	for (i = 0; i < serial->num_ports; i++) {
+		port = serial->port[i];
+		priv = usb_get_serial_port_data(port);
+
+		/* TODO: Check for Flow control and disable it if necessary */
+
+		/* cancel any scheduled reading */
+		cancel_delayed_work(&priv->rx_work);
+		flush_scheduled_work();
+
+		/* shutdown our bulk read */
+		usb_kill_urb(port->read_urb);
+	}
+	
+	return 0;
+}
+
+static int ftdi_resume(struct usb_serial *serial)
+{
+	struct usb_serial_port *port;
+	struct ftdi_private *priv;
+	int i;
+
+	/* Multi-port compatibility (even if generally, there is only one port by
'chip') */
+	for (i = 0; i < serial->num_ports; i++) {
+		port = serial->port[i];
+		priv = usb_get_serial_port_data(port);
+
+		/* probe part */
+		ftdi_set_max_packet_size(port);
+
+		/* If port was opened before sleep, re-open it */
+		if(port->port.count) ftdi_open(port->port.tty,port,NULL);
+	}
+	
+	return 0;
+}
+
+#endif /* ifdef CONFIG_PM */
+
 static int ftdi_sio_port_probe(struct usb_serial_port *port)
 {
 	struct ftdi_private *priv;



Best regards,

Martin





--
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

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux