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>
Šī revīzija ir iekļauta:
Alan Cox
2008-07-22 11:09:07 +01:00
revīziju iesūtīja Linus Torvalds
vecāks 1aa3692da5
revīzija 95da310e66
42 mainīti faili ar 1819 papildinājumiem un 1719 dzēšanām

Parādīt failu

@@ -158,12 +158,13 @@ cleanup:
return -ENOMEM;
}
static void ark3116_set_termios(struct usb_serial_port *port,
static void ark3116_set_termios(struct tty_struct *tty,
struct usb_serial_port *port,
struct ktermios *old_termios)
{
struct usb_serial *serial = port->serial;
struct ark3116_private *priv = usb_get_serial_port_data(port);
struct ktermios *termios = port->tty->termios;
struct ktermios *termios = tty->termios;
unsigned int cflag = termios->c_cflag;
unsigned long flags;
int baud;
@@ -177,8 +178,8 @@ static void ark3116_set_termios(struct usb_serial_port *port,
spin_lock_irqsave(&priv->lock, flags);
if (!priv->termios_initialized) {
*(port->tty->termios) = tty_std_termios;
port->tty->termios->c_cflag = B9600 | CS8
*termios = tty_std_termios;
termios->c_cflag = B9600 | CS8
| CREAD | HUPCL | CLOCAL;
termios->c_ispeed = 9600;
termios->c_ospeed = 9600;
@@ -192,7 +193,7 @@ static void ark3116_set_termios(struct usb_serial_port *port,
buf = kmalloc(1, GFP_KERNEL);
if (!buf) {
dbg("error kmalloc");
*port->tty->termios = *old_termios;
*termios = *old_termios;
return;
}
@@ -243,7 +244,7 @@ static void ark3116_set_termios(struct usb_serial_port *port,
}
/* set baudrate */
baud = tty_get_baud_rate(port->tty);
baud = tty_get_baud_rate(tty);
switch (baud) {
case 75:
@@ -262,11 +263,11 @@ static void ark3116_set_termios(struct usb_serial_port *port,
case 230400:
case 460800:
/* Report the resulting rate back to the caller */
tty_encode_baud_rate(port->tty, baud, baud);
tty_encode_baud_rate(tty, baud, baud);
break;
/* set 9600 as default (if given baudrate is invalid for example) */
default:
tty_encode_baud_rate(port->tty, 9600, 9600);
tty_encode_baud_rate(tty, 9600, 9600);
case 0:
baud = 9600;
}
@@ -317,7 +318,8 @@ static void ark3116_set_termios(struct usb_serial_port *port,
return;
}
static int ark3116_open(struct usb_serial_port *port, struct file *filp)
static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port,
struct file *filp)
{
struct ktermios tmp_termios;
struct usb_serial *serial = port->serial;
@@ -332,7 +334,7 @@ static int ark3116_open(struct usb_serial_port *port, struct file *filp)
return -ENOMEM;
}
result = usb_serial_generic_open(port, filp);
result = usb_serial_generic_open(tty, port, filp);
if (result)
goto err_out;
@@ -362,8 +364,8 @@ static int ark3116_open(struct usb_serial_port *port, struct file *filp)
ARK3116_RCV(serial, 124, 0xFE, 0xC0, 0x0000, 0x0006, 0xFF, buf);
/* initialise termios */
if (port->tty)
ark3116_set_termios(port, &tmp_termios);
if (tty)
ark3116_set_termios(tty, port, &tmp_termios);
err_out:
kfree(buf);
@@ -371,9 +373,10 @@ err_out:
return result;
}
static int ark3116_ioctl(struct usb_serial_port *port, struct file *file,
static int ark3116_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg)
{
struct usb_serial_port *port = tty->driver_data;
struct serial_struct serstruct;
void __user *user_arg = (void __user *)arg;
@@ -403,8 +406,9 @@ static int ark3116_ioctl(struct usb_serial_port *port, struct file *file,
return -ENOIOCTLCMD;
}
static int ark3116_tiocmget(struct usb_serial_port *port, struct file *file)
static int ark3116_tiocmget(struct tty_struct *tty, struct file *file)
{
struct usb_serial_port *port = tty->driver_data;
struct usb_serial *serial = port->serial;
char *buf;
char temp;