Hi,

this implements generic support for suspend/resume for usb serial.

        Regards
                Oliver
Signed-off-by: Oliver Neukum <[EMAIL PROTECTED]>
-- 

--- linux-2.6.21-rc7/include/linux/usb/serial.h 2007-04-25 17:02:20.000000000 
+0200
+++ linux-2.6.21-rc7-auto/include/linux/usb/serial.h    2007-04-26 
14:48:17.000000000 +0200
@@ -221,6 +221,9 @@ struct usb_serial_driver {
        int (*port_probe) (struct usb_serial_port *port);
        int (*port_remove) (struct usb_serial_port *port);
 
+       int (*suspend) (struct usb_serial *serial, pm_message_t message);
+       int (*resume) (struct usb_serial *serial);
+
        /* serial function calls */
        int  (*open)            (struct usb_serial_port *port, struct file * 
filp);
        void (*close)           (struct usb_serial_port *port, struct file * 
filp);
@@ -249,6 +252,9 @@ extern void usb_serial_port_softint(stru
 extern int usb_serial_probe(struct usb_interface *iface, const struct 
usb_device_id *id);
 extern void usb_serial_disconnect(struct usb_interface *iface);
 
+extern int usb_serial_suspend(struct usb_interface *intf, pm_message_t 
message);
+extern int usb_serial_resume(struct usb_interface *intf);
+
 extern int ezusb_writememory (struct usb_serial *serial, int address, unsigned 
char *data, int length, __u8 bRequest);
 extern int ezusb_set_reset (struct usb_serial *serial, unsigned char 
reset_bit);
 
@@ -269,6 +275,7 @@ extern void usb_serial_put(struct usb_se
 extern int usb_serial_generic_open (struct usb_serial_port *port, struct file 
*filp);
 extern int usb_serial_generic_write (struct usb_serial_port *port, const 
unsigned char *buf, int count);
 extern void usb_serial_generic_close (struct usb_serial_port *port, struct 
file *filp);
+extern int usb_serial_generic_resume (struct usb_serial *serial);
 extern int usb_serial_generic_write_room (struct usb_serial_port *port);
 extern int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port);
 extern void usb_serial_generic_read_bulk_callback (struct urb *urb);
--- linux-2.6.21-rc7/drivers/usb/serial/generic.c       2007-04-25 
17:02:10.000000000 +0200
+++ linux-2.6.21-rc7-auto/drivers/usb/serial/generic.c  2007-04-26 
14:09:27.000000000 +0200
@@ -169,6 +169,23 @@ static void generic_cleanup (struct usb_
        }
 }
 
+int usb_serial_generic_resume(struct usb_serial *serial)
+{
+       struct usb_serial_port *port;
+       int i, c = 0, r;
+
+       for (i = 0; i < serial->num_ports; i++) {
+               port = serial->port[i];
+               if (port->open_count && port->read_urb) {
+                       r = usb_submit_urb(port->read_urb, GFP_NOIO);
+                       if (r < 0)
+                               c++;
+               }
+       }
+
+       return c ? -EIO : 0;
+}
+
 void usb_serial_generic_close (struct usb_serial_port *port, struct file * 
filp)
 {
        dbg("%s - port %d", __FUNCTION__, port->number);
--- linux-2.6.21-rc7/drivers/usb/serial/usb-serial.c    2007-04-25 
17:02:11.000000000 +0200
+++ linux-2.6.21-rc7-auto/drivers/usb/serial/usb-serial.c       2007-04-26 
15:28:23.000000000 +0200
@@ -47,6 +47,8 @@ static struct usb_driver usb_serial_driv
        .name =         "usbserial",
        .probe =        usb_serial_probe,
        .disconnect =   usb_serial_disconnect,
+       .suspend =      usb_serial_suspend,
+       .resume =       usb_serial_resume,
        .no_dynamic_id =        1,
 };
 
@@ -1070,6 +1072,37 @@ void usb_serial_disconnect(struct usb_in
        dev_info(dev, "device disconnected\n");
 }
 
+int usb_serial_suspend(struct usb_interface *intf, pm_message_t message)
+{
+       struct usb_serial *serial = usb_get_intfdata(intf);
+       struct usb_serial_port *port;
+       int i, r = 0;
+
+       if (serial) {
+               for (i = 0; i < serial->num_ports; ++i) {
+                       port = serial->port[i];
+                       if (port)
+                               kill_traffic(port);
+               }
+       }
+
+       if (serial->type->suspend)
+               serial->type->suspend(serial, message);
+
+       return r;
+}
+
+EXPORT_SYMBOL(usb_serial_suspend);
+
+int usb_serial_resume(struct usb_interface *intf)
+{
+       struct usb_serial *serial = usb_get_intfdata(intf);
+
+       return serial->type->resume(serial);
+}
+
+EXPORT_SYMBOL(usb_serial_resume);
+
 static const struct tty_operations serial_ops = {
        .open =                 serial_open,
        .close =                serial_close,
@@ -1195,6 +1228,7 @@ static void fixup_generic(struct usb_ser
        set_to_generic_if_null(device, read_bulk_callback);
        set_to_generic_if_null(device, write_bulk_callback);
        set_to_generic_if_null(device, shutdown);
+       set_to_generic_if_null(device, resume);
 }
 
 int usb_serial_register(struct usb_serial_driver *driver) /* must be called 
with BKL held */


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to