[PATCH] USB: add ability for usb-serial drivers to determine if their write urb is currently being used.

This removes a lot of racy and buggy code by trying to check the status of the urb.

Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 99214aa..ddde5fb 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -174,10 +174,14 @@
 
 	/* only do something if we have a bulk out endpoint */
 	if (serial->num_bulk_out) {
-		if (port->write_urb->status == -EINPROGRESS) {
+		spin_lock(&port->lock);
+		if (port->write_urb_busy) {
+			spin_unlock(&port->lock);
 			dbg("%s - already writing", __FUNCTION__);
-			return (0);
+			return 0;
 		}
+		port->write_urb_busy = 1;
+		spin_unlock(&port->lock);
 
 		count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
 
@@ -195,17 +199,20 @@
 				     usb_serial_generic_write_bulk_callback), port);
 
 		/* send the data out the bulk port */
+		port->write_urb_busy = 1;
 		result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
-		if (result)
+		if (result) {
 			dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result);
-		else
+			/* don't have to grab the lock here, as we will retry if != 0 */
+			port->write_urb_busy = 0;
+		} else
 			result = count;
 
 		return result;
 	}
 
 	/* no bulk out, so return 0 bytes written */
-	return (0);
+	return 0;
 }
 
 int usb_serial_generic_write_room (struct usb_serial_port *port)
@@ -214,9 +221,9 @@
 	int room = 0;
 
 	dbg("%s - port %d", __FUNCTION__, port->number);
-	
+
 	if (serial->num_bulk_out) {
-		if (port->write_urb->status != -EINPROGRESS)
+		if (port->write_urb_busy)
 			room = port->bulk_out_size;
 	}
 
@@ -232,7 +239,7 @@
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
 	if (serial->num_bulk_out) {
-		if (port->write_urb->status == -EINPROGRESS)
+		if (port->write_urb_busy)
 			chars = port->write_urb->transfer_buffer_length;
 	}
 
@@ -291,6 +298,7 @@
 
 	dbg("%s - port %d", __FUNCTION__, port->number);
 
+	port->write_urb_busy = 0;
 	if (urb->status) {
 		dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
 		return;