usb_serial: API all change

USB serial likes to use port->tty back pointers for the real work it does and
to do so without any actual locking. Unfortunately when you consider hangup
events, hangup/parallel reopen or even worse hangup followed by parallel close
events the tty->port and port->tty pointers are not guaranteed to be the same
as port->tty is the active tty while tty->port is the port the tty may or
may not still be attached to.

So rework the entire API to pass the tty struct. For console cases we need
to pass both for now. This shows up multiple drivers that immediately crash
with USB console some of which have been fixed in the process.

Longer term we need a proper tty as console abstraction

Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c
index 0063c11..e59155c 100644
--- a/drivers/usb/serial/ir-usb.c
+++ b/drivers/usb/serial/ir-usb.c
@@ -85,15 +85,17 @@
 /* if overridden by the user, then use the specified number of XBOFs */
 static int xbof = -1;
 
-static int ir_startup(struct usb_serial *serial);
-static int ir_open(struct usb_serial_port *port, struct file *filep);
-static void ir_close(struct usb_serial_port *port, struct file *filep);
-static int ir_write(struct usb_serial_port *port,
-		const unsigned char *buf, int count);
-static void ir_write_bulk_callback(struct urb *urb);
-static void ir_read_bulk_callback(struct urb *urb);
-static void ir_set_termios(struct usb_serial_port *port,
-		struct ktermios *old_termios);
+static int  ir_startup (struct usb_serial *serial);
+static int  ir_open(struct tty_struct *tty, struct usb_serial_port *port,
+					struct file *filep);
+static void ir_close(struct tty_struct *tty, struct usb_serial_port *port,
+					struct file *filep);
+static int  ir_write(struct tty_struct *tty, struct usb_serial_port *port,
+					const unsigned char *buf, int count);
+static void ir_write_bulk_callback (struct urb *urb);
+static void ir_read_bulk_callback (struct urb *urb);
+static void ir_set_termios(struct tty_struct *tty,
+		struct usb_serial_port *port, struct ktermios *old_termios);
 
 /* Not that this lot means you can only have one per system */
 static u8 ir_baud;
@@ -295,7 +297,8 @@
 	return 0;
 }
 
-static int ir_open(struct usb_serial_port *port, struct file *filp)
+static int ir_open(struct tty_struct *tty,
+			struct usb_serial_port *port, struct file *filp)
 {
 	char *buffer;
 	int result = 0;
@@ -343,7 +346,8 @@
 	return result;
 }
 
-static void ir_close(struct usb_serial_port *port, struct file *filp)
+static void ir_close(struct tty_struct *tty,
+			struct usb_serial_port *port, struct file * filp)
 {
 	dbg("%s - port %d", __func__, port->number);
 
@@ -351,8 +355,8 @@
 	usb_kill_urb(port->read_urb);
 }
 
-static int ir_write(struct usb_serial_port *port,
-		const unsigned char *buf, int count)
+static int ir_write(struct tty_struct *tty, struct usb_serial_port *port,
+					const unsigned char *buf, int count)
 {
 	unsigned char *transfer_buffer;
 	int result;
@@ -360,11 +364,6 @@
 
 	dbg("%s - port = %d, count = %d", __func__, port->number, count);
 
-	if (!port->tty) {
-		dev_err(&port->dev, "%s - no tty???\n", __func__);
-		return 0;
-	}
-
 	if (count == 0)
 		return 0;
 
@@ -450,14 +449,13 @@
 
 	dbg("%s - port %d", __func__, port->number);
 
-	if (!port->open_count) {
+	if (!port->port.count) {
 		dbg("%s - port closed.", __func__);
 		return;
 	}
 
 	switch (status) {
 	case 0: /* Successful */
-
 		/*
 		 * The first byte of the packet we get from the device
 		 * contains a busy indicator and baud rate change.
@@ -465,19 +463,11 @@
 		 */
 		if ((*data & 0x0f) > 0)
 			ir_baud = *data & 0x0f;
-
-		usb_serial_debug_data(
-			debug,
-			&port->dev,
-			__func__,
-			urb->actual_length,
-			data);
-
-		tty = port->tty;
-
+		usb_serial_debug_data(debug, &port->dev, __func__,
+						urb->actual_length, data);
+ 		tty = port->port.tty;
 		if (tty_buffer_request_room(tty, urb->actual_length - 1)) {
-			tty_insert_flip_string(tty, data + 1,
-					urb->actual_length - 1);
+			tty_insert_flip_string(tty, data+1, urb->actual_length - 1);
 			tty_flip_buffer_push(tty);
 		}
 
@@ -488,11 +478,10 @@
 		 */
 
 	case -EPROTO: /* taking inspiration from pl2303.c */
-
-		/* Continue trying to always read */
+			/* Continue trying to always read */
 		usb_fill_bulk_urb(
 			port->read_urb,
-			port->serial->dev,
+			port->serial->dev, 
 			usb_rcvbulkpipe(port->serial->dev,
 				port->bulk_in_endpointAddress),
 			port->read_urb->transfer_buffer,
@@ -502,23 +491,19 @@
 
 		result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
 		if (result)
-			dev_err(&port->dev,
-				"%s - failed resubmitting read urb, error %d\n",
+			dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n",
 				__func__, result);
-		break;
-
+			break ;
 	default:
 		dbg("%s - nonzero read bulk status received: %d",
-			__func__,
-			status);
-		break;
+			__func__, status);
+		break ;
 	}
-
 	return;
 }
 
-static void ir_set_termios(struct usb_serial_port *port,
-		struct ktermios *old_termios)
+static void ir_set_termios(struct tty_struct *tty,
+		struct usb_serial_port *port, struct ktermios *old_termios)
 {
 	unsigned char *transfer_buffer;
 	int result;
@@ -527,7 +512,7 @@
 
 	dbg("%s - port %d", __func__, port->number);
 
-	baud = tty_get_baud_rate(port->tty);
+	baud = tty_get_baud_rate(tty);
 
 	/*
 	 * FIXME, we should compare the baud request against the
@@ -600,8 +585,8 @@
 				__func__, result);
 
 	/* Only speed changes are supported */
-	tty_termios_copy_hw(port->tty->termios, old_termios);
-	tty_encode_baud_rate(port->tty, baud, baud);
+	tty_termios_copy_hw(tty->termios, old_termios);
+	tty_encode_baud_rate(tty, baud, baud);
 }
 
 static int __init ir_init(void)