aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tty_io.c
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2006-12-08 05:38:44 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-08 11:28:56 -0500
commitedc6afc5496875a640bef0913604be7550c1795d (patch)
treeb05cd34a9a0d71edc9d6d7487ad551f0e15887b8 /drivers/char/tty_io.c
parentbe90038a24c814dc98bc5a813f41855779000018 (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.c137
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
112struct termios tty_std_termios = { /* for the benefit of tty drivers */ 112struct 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
121EXPORT_SYMBOL(tty_std_termios); 123EXPORT_SYMBOL(tty_std_termios);
@@ -1239,6 +1241,22 @@ void tty_ldisc_flush(struct tty_struct *tty)
1239} 1241}
1240 1242
1241EXPORT_SYMBOL_GPL(tty_ldisc_flush); 1243EXPORT_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
1252static 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:
2104static void release_mem(struct tty_struct *tty, int idx) 2121static 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 */
3467static 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
3478static 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
3491int 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
3508EXPORT_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
3521int 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
3537EXPORT_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);
3798int tty_unregister_driver(struct tty_driver *driver) 3737int 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)