diff options
Diffstat (limited to 'drivers/char/tty_io.c')
-rw-r--r-- | drivers/char/tty_io.c | 137 |
1 files changed, 38 insertions, 99 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 48cee2004e97..4044c864fdd4 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -109,13 +109,15 @@ | |||
109 | #define TTY_PARANOIA_CHECK 1 | 109 | #define TTY_PARANOIA_CHECK 1 |
110 | #define CHECK_TTY_COUNT 1 | 110 | #define CHECK_TTY_COUNT 1 |
111 | 111 | ||
112 | struct termios tty_std_termios = { /* for the benefit of tty drivers */ | 112 | struct ktermios tty_std_termios = { /* for the benefit of tty drivers */ |
113 | .c_iflag = ICRNL | IXON, | 113 | .c_iflag = ICRNL | IXON, |
114 | .c_oflag = OPOST | ONLCR, | 114 | .c_oflag = OPOST | ONLCR, |
115 | .c_cflag = B38400 | CS8 | CREAD | HUPCL, | 115 | .c_cflag = B38400 | CS8 | CREAD | HUPCL, |
116 | .c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK | | 116 | .c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK | |
117 | ECHOCTL | ECHOKE | IEXTEN, | 117 | ECHOCTL | ECHOKE | IEXTEN, |
118 | .c_cc = INIT_C_CC | 118 | .c_cc = INIT_C_CC, |
119 | .c_ispeed = 38400, | ||
120 | .c_ospeed = 38400 | ||
119 | }; | 121 | }; |
120 | 122 | ||
121 | EXPORT_SYMBOL(tty_std_termios); | 123 | EXPORT_SYMBOL(tty_std_termios); |
@@ -1239,6 +1241,22 @@ void tty_ldisc_flush(struct tty_struct *tty) | |||
1239 | } | 1241 | } |
1240 | 1242 | ||
1241 | EXPORT_SYMBOL_GPL(tty_ldisc_flush); | 1243 | EXPORT_SYMBOL_GPL(tty_ldisc_flush); |
1244 | |||
1245 | /** | ||
1246 | * tty_reset_termios - reset terminal state | ||
1247 | * @tty: tty to reset | ||
1248 | * | ||
1249 | * Restore a terminal to the driver default state | ||
1250 | */ | ||
1251 | |||
1252 | static void tty_reset_termios(struct tty_struct *tty) | ||
1253 | { | ||
1254 | mutex_lock(&tty->termios_mutex); | ||
1255 | *tty->termios = tty->driver->init_termios; | ||
1256 | tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios); | ||
1257 | tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios); | ||
1258 | mutex_unlock(&tty->termios_mutex); | ||
1259 | } | ||
1242 | 1260 | ||
1243 | /** | 1261 | /** |
1244 | * do_tty_hangup - actual handler for hangup events | 1262 | * do_tty_hangup - actual handler for hangup events |
@@ -1327,11 +1345,7 @@ static void do_tty_hangup(struct work_struct *work) | |||
1327 | * N_TTY. | 1345 | * N_TTY. |
1328 | */ | 1346 | */ |
1329 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) | 1347 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) |
1330 | { | 1348 | tty_reset_termios(tty); |
1331 | mutex_lock(&tty->termios_mutex); | ||
1332 | *tty->termios = tty->driver->init_termios; | ||
1333 | mutex_unlock(&tty->termios_mutex); | ||
1334 | } | ||
1335 | 1349 | ||
1336 | /* Defer ldisc switch */ | 1350 | /* Defer ldisc switch */ |
1337 | /* tty_deferred_ldisc_switch(N_TTY); | 1351 | /* tty_deferred_ldisc_switch(N_TTY); |
@@ -1870,8 +1884,8 @@ static int init_dev(struct tty_driver *driver, int idx, | |||
1870 | struct tty_struct **ret_tty) | 1884 | struct tty_struct **ret_tty) |
1871 | { | 1885 | { |
1872 | struct tty_struct *tty, *o_tty; | 1886 | struct tty_struct *tty, *o_tty; |
1873 | struct termios *tp, **tp_loc, *o_tp, **o_tp_loc; | 1887 | struct ktermios *tp, **tp_loc, *o_tp, **o_tp_loc; |
1874 | struct termios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc; | 1888 | struct ktermios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc; |
1875 | int retval = 0; | 1889 | int retval = 0; |
1876 | 1890 | ||
1877 | /* check whether we're reopening an existing tty */ | 1891 | /* check whether we're reopening an existing tty */ |
@@ -1918,7 +1932,7 @@ static int init_dev(struct tty_driver *driver, int idx, | |||
1918 | } | 1932 | } |
1919 | 1933 | ||
1920 | if (!*tp_loc) { | 1934 | if (!*tp_loc) { |
1921 | tp = (struct termios *) kmalloc(sizeof(struct termios), | 1935 | tp = (struct ktermios *) kmalloc(sizeof(struct ktermios), |
1922 | GFP_KERNEL); | 1936 | GFP_KERNEL); |
1923 | if (!tp) | 1937 | if (!tp) |
1924 | goto free_mem_out; | 1938 | goto free_mem_out; |
@@ -1926,11 +1940,11 @@ static int init_dev(struct tty_driver *driver, int idx, | |||
1926 | } | 1940 | } |
1927 | 1941 | ||
1928 | if (!*ltp_loc) { | 1942 | if (!*ltp_loc) { |
1929 | ltp = (struct termios *) kmalloc(sizeof(struct termios), | 1943 | ltp = (struct ktermios *) kmalloc(sizeof(struct ktermios), |
1930 | GFP_KERNEL); | 1944 | GFP_KERNEL); |
1931 | if (!ltp) | 1945 | if (!ltp) |
1932 | goto free_mem_out; | 1946 | goto free_mem_out; |
1933 | memset(ltp, 0, sizeof(struct termios)); | 1947 | memset(ltp, 0, sizeof(struct ktermios)); |
1934 | } | 1948 | } |
1935 | 1949 | ||
1936 | if (driver->type == TTY_DRIVER_TYPE_PTY) { | 1950 | if (driver->type == TTY_DRIVER_TYPE_PTY) { |
@@ -1951,19 +1965,19 @@ static int init_dev(struct tty_driver *driver, int idx, | |||
1951 | } | 1965 | } |
1952 | 1966 | ||
1953 | if (!*o_tp_loc) { | 1967 | if (!*o_tp_loc) { |
1954 | o_tp = (struct termios *) | 1968 | o_tp = (struct ktermios *) |
1955 | kmalloc(sizeof(struct termios), GFP_KERNEL); | 1969 | kmalloc(sizeof(struct ktermios), GFP_KERNEL); |
1956 | if (!o_tp) | 1970 | if (!o_tp) |
1957 | goto free_mem_out; | 1971 | goto free_mem_out; |
1958 | *o_tp = driver->other->init_termios; | 1972 | *o_tp = driver->other->init_termios; |
1959 | } | 1973 | } |
1960 | 1974 | ||
1961 | if (!*o_ltp_loc) { | 1975 | if (!*o_ltp_loc) { |
1962 | o_ltp = (struct termios *) | 1976 | o_ltp = (struct ktermios *) |
1963 | kmalloc(sizeof(struct termios), GFP_KERNEL); | 1977 | kmalloc(sizeof(struct ktermios), GFP_KERNEL); |
1964 | if (!o_ltp) | 1978 | if (!o_ltp) |
1965 | goto free_mem_out; | 1979 | goto free_mem_out; |
1966 | memset(o_ltp, 0, sizeof(struct termios)); | 1980 | memset(o_ltp, 0, sizeof(struct ktermios)); |
1967 | } | 1981 | } |
1968 | 1982 | ||
1969 | /* | 1983 | /* |
@@ -2002,6 +2016,9 @@ static int init_dev(struct tty_driver *driver, int idx, | |||
2002 | *ltp_loc = ltp; | 2016 | *ltp_loc = ltp; |
2003 | tty->termios = *tp_loc; | 2017 | tty->termios = *tp_loc; |
2004 | tty->termios_locked = *ltp_loc; | 2018 | tty->termios_locked = *ltp_loc; |
2019 | /* Compatibility until drivers always set this */ | ||
2020 | tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios); | ||
2021 | tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios); | ||
2005 | driver->refcount++; | 2022 | driver->refcount++; |
2006 | tty->count++; | 2023 | tty->count++; |
2007 | 2024 | ||
@@ -2104,7 +2121,7 @@ release_mem_out: | |||
2104 | static void release_mem(struct tty_struct *tty, int idx) | 2121 | static void release_mem(struct tty_struct *tty, int idx) |
2105 | { | 2122 | { |
2106 | struct tty_struct *o_tty; | 2123 | struct tty_struct *o_tty; |
2107 | struct termios *tp; | 2124 | struct ktermios *tp; |
2108 | int devpts = tty->driver->flags & TTY_DRIVER_DEVPTS_MEM; | 2125 | int devpts = tty->driver->flags & TTY_DRIVER_DEVPTS_MEM; |
2109 | 2126 | ||
2110 | if ((o_tty = tty->link) != NULL) { | 2127 | if ((o_tty = tty->link) != NULL) { |
@@ -3458,84 +3475,6 @@ static void flush_to_ldisc(struct work_struct *work) | |||
3458 | tty_ldisc_deref(disc); | 3475 | tty_ldisc_deref(disc); |
3459 | } | 3476 | } |
3460 | 3477 | ||
3461 | /* | ||
3462 | * Routine which returns the baud rate of the tty | ||
3463 | * | ||
3464 | * Note that the baud_table needs to be kept in sync with the | ||
3465 | * include/asm/termbits.h file. | ||
3466 | */ | ||
3467 | static int baud_table[] = { | ||
3468 | 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, | ||
3469 | 9600, 19200, 38400, 57600, 115200, 230400, 460800, | ||
3470 | #ifdef __sparc__ | ||
3471 | 76800, 153600, 307200, 614400, 921600 | ||
3472 | #else | ||
3473 | 500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000, | ||
3474 | 2500000, 3000000, 3500000, 4000000 | ||
3475 | #endif | ||
3476 | }; | ||
3477 | |||
3478 | static int n_baud_table = ARRAY_SIZE(baud_table); | ||
3479 | |||
3480 | /** | ||
3481 | * tty_termios_baud_rate | ||
3482 | * @termios: termios structure | ||
3483 | * | ||
3484 | * Convert termios baud rate data into a speed. This should be called | ||
3485 | * with the termios lock held if this termios is a terminal termios | ||
3486 | * structure. May change the termios data. | ||
3487 | * | ||
3488 | * Locking: none | ||
3489 | */ | ||
3490 | |||
3491 | int tty_termios_baud_rate(struct termios *termios) | ||
3492 | { | ||
3493 | unsigned int cbaud; | ||
3494 | |||
3495 | cbaud = termios->c_cflag & CBAUD; | ||
3496 | |||
3497 | if (cbaud & CBAUDEX) { | ||
3498 | cbaud &= ~CBAUDEX; | ||
3499 | |||
3500 | if (cbaud < 1 || cbaud + 15 > n_baud_table) | ||
3501 | termios->c_cflag &= ~CBAUDEX; | ||
3502 | else | ||
3503 | cbaud += 15; | ||
3504 | } | ||
3505 | return baud_table[cbaud]; | ||
3506 | } | ||
3507 | |||
3508 | EXPORT_SYMBOL(tty_termios_baud_rate); | ||
3509 | |||
3510 | /** | ||
3511 | * tty_get_baud_rate - get tty bit rates | ||
3512 | * @tty: tty to query | ||
3513 | * | ||
3514 | * Returns the baud rate as an integer for this terminal. The | ||
3515 | * termios lock must be held by the caller and the terminal bit | ||
3516 | * flags may be updated. | ||
3517 | * | ||
3518 | * Locking: none | ||
3519 | */ | ||
3520 | |||
3521 | int tty_get_baud_rate(struct tty_struct *tty) | ||
3522 | { | ||
3523 | int baud = tty_termios_baud_rate(tty->termios); | ||
3524 | |||
3525 | if (baud == 38400 && tty->alt_speed) { | ||
3526 | if (!tty->warned) { | ||
3527 | printk(KERN_WARNING "Use of setserial/setrocket to " | ||
3528 | "set SPD_* flags is deprecated\n"); | ||
3529 | tty->warned = 1; | ||
3530 | } | ||
3531 | baud = tty->alt_speed; | ||
3532 | } | ||
3533 | |||
3534 | return baud; | ||
3535 | } | ||
3536 | |||
3537 | EXPORT_SYMBOL(tty_get_baud_rate); | ||
3538 | |||
3539 | /** | 3478 | /** |
3540 | * tty_flip_buffer_push - terminal | 3479 | * tty_flip_buffer_push - terminal |
3541 | * @tty: tty to push | 3480 | * @tty: tty to push |
@@ -3758,8 +3697,8 @@ int tty_register_driver(struct tty_driver *driver) | |||
3758 | 3697 | ||
3759 | if (p) { | 3698 | if (p) { |
3760 | driver->ttys = (struct tty_struct **)p; | 3699 | driver->ttys = (struct tty_struct **)p; |
3761 | driver->termios = (struct termios **)(p + driver->num); | 3700 | driver->termios = (struct ktermios **)(p + driver->num); |
3762 | driver->termios_locked = (struct termios **)(p + driver->num * 2); | 3701 | driver->termios_locked = (struct ktermios **)(p + driver->num * 2); |
3763 | } else { | 3702 | } else { |
3764 | driver->ttys = NULL; | 3703 | driver->ttys = NULL; |
3765 | driver->termios = NULL; | 3704 | driver->termios = NULL; |
@@ -3798,7 +3737,7 @@ EXPORT_SYMBOL(tty_register_driver); | |||
3798 | int tty_unregister_driver(struct tty_driver *driver) | 3737 | int tty_unregister_driver(struct tty_driver *driver) |
3799 | { | 3738 | { |
3800 | int i; | 3739 | int i; |
3801 | struct termios *tp; | 3740 | struct ktermios *tp; |
3802 | void *p; | 3741 | void *p; |
3803 | 3742 | ||
3804 | if (driver->refcount) | 3743 | if (driver->refcount) |