diff options
author | Alan Cox <alan@lxorguk.ukuu.org.uk> | 2006-12-08 05:38:44 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-08 11:28:56 -0500 |
commit | edc6afc5496875a640bef0913604be7550c1795d (patch) | |
tree | b05cd34a9a0d71edc9d6d7487ad551f0e15887b8 /drivers/char/tty_io.c | |
parent | be90038a24c814dc98bc5a813f41855779000018 (diff) |
[PATCH] tty: switch to ktermios and new framework
This is the core of the switch to the new framework. I've split it from the
driver patches which are mostly search/replace and would encourage people to
give this one a good hard stare.
The references to BOTHER and ISHIFT are the termios values that must be
defined by a platform once it wants to turn on "new style" ioctl support. The
code patches here ensure that providing
1. The termios overlays the ktermios in memory
2. The only new kernel only fields are c_ispeed/c_ospeed (or none)
the existing behaviour is retained. This is true for the patches at this
point in time.
Future patches will define BOTHER, ISHIFT and enable newer termios structures
for each architecture, and once they are all done some of the ifdefs also
vanish.
[akpm@osdl.org: warning fix]
[akpm@osdl.org: IRDA fix]
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
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) |