Merge branch 'tty-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6

* 'tty-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6:
  serial: mfd: adjust the baud rate setting
  TTY: open/hangup race fixup
  TTY: don't allow reopen when ldisc is changing
  NET: wan/x25, fix ldisc->open retval
  TTY: ldisc, fix open flag handling
  serial8250: Mark console as CON_ANYTIME
This commit is contained in:
Linus Torvalds 2010-12-02 12:58:16 -08:00
commit eed5ee1a3a
6 changed files with 24 additions and 20 deletions

View File

@ -577,7 +577,7 @@ static int x25_asy_open_tty(struct tty_struct *tty)
if (err) if (err)
return err; return err;
/* Done. We have linked the TTY line to a channel. */ /* Done. We have linked the TTY line to a channel. */
return sl->dev->base_addr; return 0;
} }

View File

@ -2872,7 +2872,7 @@ static struct console serial8250_console = {
.device = uart_console_device, .device = uart_console_device,
.setup = serial8250_console_setup, .setup = serial8250_console_setup,
.early_setup = serial8250_console_early_setup, .early_setup = serial8250_console_early_setup,
.flags = CON_PRINTBUFFER, .flags = CON_PRINTBUFFER | CON_ANYTIME,
.index = -1, .index = -1,
.data = &serial8250_reg, .data = &serial8250_reg,
}; };

View File

@ -900,8 +900,7 @@ serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios,
unsigned char cval, fcr = 0; unsigned char cval, fcr = 0;
unsigned long flags; unsigned long flags;
unsigned int baud, quot; unsigned int baud, quot;
u32 mul = 0x3600; u32 ps, mul;
u32 ps = 0x10;
switch (termios->c_cflag & CSIZE) { switch (termios->c_cflag & CSIZE) {
case CS5: case CS5:
@ -943,31 +942,24 @@ serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios,
baud = uart_get_baud_rate(port, termios, old, 0, 4000000); baud = uart_get_baud_rate(port, termios, old, 0, 4000000);
quot = 1; quot = 1;
ps = 0x10;
mul = 0x3600;
switch (baud) { switch (baud) {
case 3500000: case 3500000:
mul = 0x3345; mul = 0x3345;
ps = 0xC; ps = 0xC;
break; break;
case 3000000:
mul = 0x2EE0;
break;
case 2500000:
mul = 0x2710;
break;
case 2000000:
mul = 0x1F40;
break;
case 1843200: case 1843200:
mul = 0x2400; mul = 0x2400;
break; break;
case 3000000:
case 2500000:
case 2000000:
case 1500000: case 1500000:
mul = 0x1770;
break;
case 1000000: case 1000000:
mul = 0xFA0;
break;
case 500000: case 500000:
mul = 0x7D0; /* mul/ps/quot = 0x9C4/0x10/0x1 will make a 500000 bps */
mul = baud / 500000 * 0x9C4;
break; break;
default: default:
/* Use uart_get_divisor to get quot for other baud rates */ /* Use uart_get_divisor to get quot for other baud rates */

View File

@ -559,6 +559,9 @@ void __tty_hangup(struct tty_struct *tty)
tty_lock(); tty_lock();
/* some functions below drop BTM, so we need this bit */
set_bit(TTY_HUPPING, &tty->flags);
/* inuse_filps is protected by the single tty lock, /* inuse_filps is protected by the single tty lock,
this really needs to change if we want to flush the this really needs to change if we want to flush the
workqueue with the lock held */ workqueue with the lock held */
@ -578,6 +581,10 @@ void __tty_hangup(struct tty_struct *tty)
} }
spin_unlock(&tty_files_lock); spin_unlock(&tty_files_lock);
/*
* it drops BTM and thus races with reopen
* we protect the race by TTY_HUPPING
*/
tty_ldisc_hangup(tty); tty_ldisc_hangup(tty);
read_lock(&tasklist_lock); read_lock(&tasklist_lock);
@ -615,7 +622,6 @@ void __tty_hangup(struct tty_struct *tty)
tty->session = NULL; tty->session = NULL;
tty->pgrp = NULL; tty->pgrp = NULL;
tty->ctrl_status = 0; tty->ctrl_status = 0;
set_bit(TTY_HUPPED, &tty->flags);
spin_unlock_irqrestore(&tty->ctrl_lock, flags); spin_unlock_irqrestore(&tty->ctrl_lock, flags);
/* Account for the p->signal references we killed */ /* Account for the p->signal references we killed */
@ -641,6 +647,7 @@ void __tty_hangup(struct tty_struct *tty)
* can't yet guarantee all that. * can't yet guarantee all that.
*/ */
set_bit(TTY_HUPPED, &tty->flags); set_bit(TTY_HUPPED, &tty->flags);
clear_bit(TTY_HUPPING, &tty->flags);
tty_ldisc_enable(tty); tty_ldisc_enable(tty);
tty_unlock(); tty_unlock();
@ -1310,7 +1317,9 @@ static int tty_reopen(struct tty_struct *tty)
{ {
struct tty_driver *driver = tty->driver; struct tty_driver *driver = tty->driver;
if (test_bit(TTY_CLOSING, &tty->flags)) if (test_bit(TTY_CLOSING, &tty->flags) ||
test_bit(TTY_HUPPING, &tty->flags) ||
test_bit(TTY_LDISC_CHANGING, &tty->flags))
return -EIO; return -EIO;
if (driver->type == TTY_DRIVER_TYPE_PTY && if (driver->type == TTY_DRIVER_TYPE_PTY &&

View File

@ -454,6 +454,8 @@ static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld)
/* BTM here locks versus a hangup event */ /* BTM here locks versus a hangup event */
WARN_ON(!tty_locked()); WARN_ON(!tty_locked());
ret = ld->ops->open(tty); ret = ld->ops->open(tty);
if (ret)
clear_bit(TTY_LDISC_OPEN, &tty->flags);
return ret; return ret;
} }
return 0; return 0;

View File

@ -366,6 +366,7 @@ struct tty_file_private {
#define TTY_HUPPED 18 /* Post driver->hangup() */ #define TTY_HUPPED 18 /* Post driver->hangup() */
#define TTY_FLUSHING 19 /* Flushing to ldisc in progress */ #define TTY_FLUSHING 19 /* Flushing to ldisc in progress */
#define TTY_FLUSHPENDING 20 /* Queued buffer flush pending */ #define TTY_FLUSHPENDING 20 /* Queued buffer flush pending */
#define TTY_HUPPING 21 /* ->hangup() in progress */
#define TTY_WRITE_FLUSH(tty) tty_write_flush((tty)) #define TTY_WRITE_FLUSH(tty) tty_write_flush((tty))