Here's those two patch files.  Boy, don't I feel silly.

James
--- sierra.c	2007-05-02 13:11:47.000000000 -0500
+++ sierra_107.c	2007-04-30 19:17:43.000000000 -0500
@@ -15,7 +15,7 @@
 
 */
 
-#define DRIVER_VERSION "v.1.0.6"
+#define DRIVER_VERSION "v.1.0.7"
 #define DRIVER_AUTHOR "Kevin Lloyd <[EMAIL PROTECTED]>"
 #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems"
 
@@ -69,6 +69,9 @@
 	{ }
 };
 
+static int sierra_resume(struct usb_serial *serial);
+static int sierra_suspend(struct usb_serial *serial, pm_message_t message);
+
 static struct usb_driver sierra_driver = {
 	.name       = "sierra",
 	.probe      = usb_serial_probe,
@@ -456,15 +459,45 @@
 	return (0);
 }
 
-static inline void stop_urb(struct urb *urb)
+/* Stop reading/writing urbs */
+static inline void unlink_urbs(struct sierra_port_private *portdata)
+{		
+	int i;
+	for (i = 0; i < N_IN_URB; i++)
+		usb_unlink_urb(portdata->in_urbs[i]);
+	for (i = 0; i < N_OUT_URB; i++)
+		usb_unlink_urb(portdata->out_urbs[i]);
+}
+
+static void unlink_all_ports_urbs(struct usb_serial *serial)
+{
+	int i;
+	struct usb_serial_port *port;
+	struct sierra_port_private *portdata;
+
+	/* Stop reading/writing urbs */
+	for (i = 0; i < serial->num_ports; ++i) {
+		port = serial->port[i];
+		if (!port)
+			continue;
+		portdata = usb_get_serial_port_data(port);
+		if (!portdata)
+			continue;
+
+		unlink_urbs(portdata);
+	}
+}
+
+static int sierra_suspend(struct usb_serial *serial, pm_message_t message)
 {
-	if (urb && urb->status == -EINPROGRESS)
-		usb_kill_urb(urb);
+	dbg("%s", __FUNCTION__);
+	if (serial)
+		unlink_all_ports_urbs(serial);
+	return 0;
 }
 
 static void sierra_close(struct usb_serial_port *port, struct file *filp)
 {
-	int i;
 	struct usb_serial *serial = port->serial;
 	struct sierra_port_private *portdata;
 
@@ -476,12 +509,7 @@
 
 	if (serial->dev) {
 		sierra_send_setup(port);
-
-		/* Stop reading/writing urbs */
-		for (i = 0; i < N_IN_URB; i++)
-			stop_urb(portdata->in_urbs[i]);
-		for (i = 0; i < N_OUT_URB; i++)
-			stop_urb(portdata->out_urbs[i]);
+		unlink_urbs(portdata);
 	}
 	port->tty = NULL;
 }
@@ -523,7 +551,7 @@
 		port = serial->port[i];
 		portdata = usb_get_serial_port_data(port);
 
-	/* Do indat endpoints first */
+		/* Do indat endpoints first */
 		for (j = 0; j < N_IN_URB; ++j) {
 			portdata->in_urbs[j] = sierra_setup_urb (serial,
                   	port->bulk_in_endpointAddress, USB_DIR_IN, port,
@@ -539,6 +567,14 @@
 	}
 }
 
+static int sierra_resume(struct usb_serial *serial)
+{
+	dbg("%s", __FUNCTION__);
+	if (serial)
+		sierra_setup_urbs(serial);
+	return 0;
+}
+
 static int sierra_startup(struct usb_serial *serial)
 {
 	int i, err;
@@ -580,20 +616,16 @@
 
 	dbg("%s", __FUNCTION__);
 
-	/* Stop reading/writing urbs */
-	for (i = 0; i < serial->num_ports; ++i) {
-		port = serial->port[i];
-		portdata = usb_get_serial_port_data(port);
-		for (j = 0; j < N_IN_URB; j++)
-			stop_urb(portdata->in_urbs[j]);
-		for (j = 0; j < N_OUT_URB; j++)
-			stop_urb(portdata->out_urbs[j]);
-	}
+	unlink_all_ports_urbs(serial);
 
 	/* Now free them */
 	for (i = 0; i < serial->num_ports; ++i) {
 		port = serial->port[i];
+		if (!port)
+			continue;
 		portdata = usb_get_serial_port_data(port);
+		if (!portdata)
+			continue;
 
 		for (j = 0; j < N_IN_URB; j++) {
 			if (portdata->in_urbs[j]) {
@@ -612,6 +644,8 @@
 	/* Now free per port private data */
 	for (i = 0; i < serial->num_ports; i++) {
 		port = serial->port[i];
+		if (!port)
+			continue;
 		kfree(usb_get_serial_port_data(port));
 	}
 }
@@ -643,6 +677,8 @@
 	.attach            = sierra_startup,
 	.shutdown          = sierra_shutdown,
 	.read_int_callback = sierra_instat_callback,
+	.suspend           = sierra_suspend,
+	.resume            = sierra_resume,
 };
 
 static struct usb_serial_driver sierra_3port_device = {
@@ -672,6 +708,8 @@
 	.attach            = sierra_startup,
 	.shutdown          = sierra_shutdown,
 	.read_int_callback = sierra_instat_callback,
+	.suspend           = sierra_suspend,
+	.resume            = sierra_resume,
 };
 
 /* Functions used by new usb-serial code. */
--- 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