提交 eed5ee1a 编写于 作者: L Linus Torvalds

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
...@@ -577,7 +577,7 @@ static int x25_asy_open_tty(struct tty_struct *tty) ...@@ -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;
} }
......
...@@ -2872,7 +2872,7 @@ static struct console serial8250_console = { ...@@ -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,
}; };
......
...@@ -900,8 +900,7 @@ serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios, ...@@ -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, ...@@ -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 */
......
...@@ -559,6 +559,9 @@ void __tty_hangup(struct tty_struct *tty) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 &&
......
...@@ -454,6 +454,8 @@ static int tty_ldisc_open(struct tty_struct *tty, struct tty_ldisc *ld) ...@@ -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;
......
...@@ -366,6 +366,7 @@ struct tty_file_private { ...@@ -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))
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册