aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--drivers/char/tty_io.c137
-rw-r--r--drivers/char/tty_ioctl.c258
-rw-r--r--include/linux/tty.h9
-rw-r--r--include/linux/tty_driver.h12
-rw-r--r--include/linux/tty_ldisc.h4
-rw-r--r--include/net/irda/ircomm_tty.h2
-rw-r--r--net/irda/ircomm/ircomm_tty_ioctl.c2
7 files changed, 297 insertions, 127 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)
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index 3b6fa7b0be8b..0ffba4e911ca 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -36,6 +36,7 @@
36#define TERMIOS_FLUSH 1 36#define TERMIOS_FLUSH 1
37#define TERMIOS_WAIT 2 37#define TERMIOS_WAIT 2
38#define TERMIOS_TERMIO 4 38#define TERMIOS_TERMIO 4
39#define TERMIOS_OLD 8
39 40
40 41
41/** 42/**
@@ -84,9 +85,9 @@ stop_waiting:
84 85
85EXPORT_SYMBOL(tty_wait_until_sent); 86EXPORT_SYMBOL(tty_wait_until_sent);
86 87
87static void unset_locked_termios(struct termios *termios, 88static void unset_locked_termios(struct ktermios *termios,
88 struct termios *old, 89 struct ktermios *old,
89 struct termios *locked) 90 struct ktermios *locked)
90{ 91{
91 int i; 92 int i;
92 93
@@ -105,8 +106,204 @@ static void unset_locked_termios(struct termios *termios,
105 for (i=0; i < NCCS; i++) 106 for (i=0; i < NCCS; i++)
106 termios->c_cc[i] = locked->c_cc[i] ? 107 termios->c_cc[i] = locked->c_cc[i] ?
107 old->c_cc[i] : termios->c_cc[i]; 108 old->c_cc[i] : termios->c_cc[i];
109 /* FIXME: What should we do for i/ospeed */
108} 110}
109 111
112/*
113 * Routine which returns the baud rate of the tty
114 *
115 * Note that the baud_table needs to be kept in sync with the
116 * include/asm/termbits.h file.
117 */
118static const speed_t baud_table[] = {
119 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
120 9600, 19200, 38400, 57600, 115200, 230400, 460800,
121#ifdef __sparc__
122 76800, 153600, 307200, 614400, 921600
123#else
124 500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000,
125 2500000, 3000000, 3500000, 4000000
126#endif
127};
128
129#ifndef __sparc__
130static const tcflag_t baud_bits[] = {
131 B0, B50, B75, B110, B134, B150, B200, B300, B600,
132 B1200, B1800, B2400, B4800, B9600, B19200, B38400,
133 B57600, B115200, B230400, B460800, B500000, B576000,
134 B921600, B1000000, B1152000, B1500000, B2000000, B2500000,
135 B3000000, B3500000, B4000000
136};
137#else
138static const tcflag_t baud_bits[] = {
139 B0, B50, B75, B110, B134, B150, B200, B300, B600,
140 B1200, B1800, B2400, B4800, B9600, B19200, B38400,
141 B57600, B115200, B230400, B460800, B76800, B153600,
142 B307200, B614400, B921600
143};
144#endif
145
146static int n_baud_table = ARRAY_SIZE(baud_table);
147
148/**
149 * tty_termios_baud_rate
150 * @termios: termios structure
151 *
152 * Convert termios baud rate data into a speed. This should be called
153 * with the termios lock held if this termios is a terminal termios
154 * structure. May change the termios data. Device drivers can call this
155 * function but should use ->c_[io]speed directly as they are updated.
156 *
157 * Locking: none
158 */
159
160speed_t tty_termios_baud_rate(struct ktermios *termios)
161{
162 unsigned int cbaud;
163
164 cbaud = termios->c_cflag & CBAUD;
165
166#ifdef BOTHER
167 /* Magic token for arbitary speed via c_ispeed/c_ospeed */
168 if (cbaud == BOTHER)
169 return termios->c_ospeed;
170#endif
171 if (cbaud & CBAUDEX) {
172 cbaud &= ~CBAUDEX;
173
174 if (cbaud < 1 || cbaud + 15 > n_baud_table)
175 termios->c_cflag &= ~CBAUDEX;
176 else
177 cbaud += 15;
178 }
179 return baud_table[cbaud];
180}
181
182EXPORT_SYMBOL(tty_termios_baud_rate);
183
184/**
185 * tty_termios_input_baud_rate
186 * @termios: termios structure
187 *
188 * Convert termios baud rate data into a speed. This should be called
189 * with the termios lock held if this termios is a terminal termios
190 * structure. May change the termios data. Device drivers can call this
191 * function but should use ->c_[io]speed directly as they are updated.
192 *
193 * Locking: none
194 */
195
196speed_t tty_termios_input_baud_rate(struct ktermios *termios)
197{
198#ifdef IBSHIFT
199 unsigned int cbaud = (termios->c_cflag >> IBSHIFT) & CBAUD;
200
201 if (cbaud == B0)
202 return tty_termios_baud_rate(termios);
203
204 /* Magic token for arbitary speed via c_ispeed*/
205 if (cbaud == BOTHER)
206 return termios->c_ispeed;
207
208 if (cbaud & CBAUDEX) {
209 cbaud &= ~CBAUDEX;
210
211 if (cbaud < 1 || cbaud + 15 > n_baud_table)
212 termios->c_cflag &= ~(CBAUDEX << IBSHIFT);
213 else
214 cbaud += 15;
215 }
216 return baud_table[cbaud];
217#else
218 return tty_termios_baud_rate(termios);
219#endif
220}
221
222EXPORT_SYMBOL(tty_termios_input_baud_rate);
223
224#ifdef BOTHER
225
226/**
227 * tty_termios_encode_baud_rate
228 * @termios: termios structure
229 * @ispeed: input speed
230 * @ospeed: output speed
231 *
232 * Encode the speeds set into the passed termios structure. This is
233 * used as a library helper for drivers os that they can report back
234 * the actual speed selected when it differs from the speed requested
235 *
236 * For now input and output speed must agree.
237 *
238 * Locking: Caller should hold termios lock. This is already held
239 * when calling this function from the driver termios handler.
240 */
241
242void tty_termios_encode_baud_rate(struct ktermios *termios, speed_t ibaud, speed_t obaud)
243{
244 int i = 0;
245 int ifound = 0, ofound = 0;
246
247 termios->c_ispeed = ibaud;
248 termios->c_ospeed = obaud;
249
250 termios->c_cflag &= ~CBAUD;
251 /* Identical speed means no input encoding (ie B0 << IBSHIFT)*/
252 if (termios->c_ispeed == termios->c_ospeed)
253 ifound = 1;
254
255 do {
256 if (obaud == baud_table[i]) {
257 termios->c_cflag |= baud_bits[i];
258 ofound = 1;
259 /* So that if ibaud == obaud we don't set it */
260 continue;
261 }
262 if (ibaud == baud_table[i]) {
263 termios->c_cflag |= (baud_bits[i] << IBSHIFT);
264 ifound = 1;
265 }
266 }
267 while(++i < n_baud_table);
268 if (!ofound)
269 termios->c_cflag |= BOTHER;
270 if (!ifound)
271 termios->c_cflag |= (BOTHER << IBSHIFT);
272}
273
274EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate);
275
276#endif
277
278/**
279 * tty_get_baud_rate - get tty bit rates
280 * @tty: tty to query
281 *
282 * Returns the baud rate as an integer for this terminal. The
283 * termios lock must be held by the caller and the terminal bit
284 * flags may be updated.
285 *
286 * Locking: none
287 */
288
289speed_t tty_get_baud_rate(struct tty_struct *tty)
290{
291 speed_t baud = tty_termios_baud_rate(tty->termios);
292
293 if (baud == 38400 && tty->alt_speed) {
294 if (!tty->warned) {
295 printk(KERN_WARNING "Use of setserial/setrocket to "
296 "set SPD_* flags is deprecated\n");
297 tty->warned = 1;
298 }
299 baud = tty->alt_speed;
300 }
301
302 return baud;
303}
304
305EXPORT_SYMBOL(tty_get_baud_rate);
306
110/** 307/**
111 * change_termios - update termios values 308 * change_termios - update termios values
112 * @tty: tty to update 309 * @tty: tty to update
@@ -119,10 +316,10 @@ static void unset_locked_termios(struct termios *termios,
119 * Locking: termios_sem 316 * Locking: termios_sem
120 */ 317 */
121 318
122static void change_termios(struct tty_struct * tty, struct termios * new_termios) 319static void change_termios(struct tty_struct * tty, struct ktermios * new_termios)
123{ 320{
124 int canon_change; 321 int canon_change;
125 struct termios old_termios = *tty->termios; 322 struct ktermios old_termios = *tty->termios;
126 struct tty_ldisc *ld; 323 struct tty_ldisc *ld;
127 324
128 /* 325 /*
@@ -195,7 +392,7 @@ static void change_termios(struct tty_struct * tty, struct termios * new_termios
195 392
196static int set_termios(struct tty_struct * tty, void __user *arg, int opt) 393static int set_termios(struct tty_struct * tty, void __user *arg, int opt)
197{ 394{
198 struct termios tmp_termios; 395 struct ktermios tmp_termios;
199 struct tty_ldisc *ld; 396 struct tty_ldisc *ld;
200 int retval = tty_check_change(tty); 397 int retval = tty_check_change(tty);
201 398
@@ -203,16 +400,28 @@ static int set_termios(struct tty_struct * tty, void __user *arg, int opt)
203 return retval; 400 return retval;
204 401
205 if (opt & TERMIOS_TERMIO) { 402 if (opt & TERMIOS_TERMIO) {
206 memcpy(&tmp_termios, tty->termios, sizeof(struct termios)); 403 memcpy(&tmp_termios, tty->termios, sizeof(struct ktermios));
207 if (user_termio_to_kernel_termios(&tmp_termios, 404 if (user_termio_to_kernel_termios(&tmp_termios,
208 (struct termio __user *)arg)) 405 (struct termio __user *)arg))
209 return -EFAULT; 406 return -EFAULT;
407#ifdef TCGETS2
408 } else if (opt & TERMIOS_OLD) {
409 memcpy(&tmp_termios, tty->termios, sizeof(struct termios));
410 if (user_termios_to_kernel_termios_1(&tmp_termios,
411 (struct termios_v1 __user *)arg))
412 return -EFAULT;
413#endif
210 } else { 414 } else {
211 if (user_termios_to_kernel_termios(&tmp_termios, 415 if (user_termios_to_kernel_termios(&tmp_termios,
212 (struct termios __user *)arg)) 416 (struct termios __user *)arg))
213 return -EFAULT; 417 return -EFAULT;
214 } 418 }
215 419
420 /* If old style Bfoo values are used then load c_ispeed/c_ospeed with the real speed
421 so its unconditionally usable */
422 tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios);
423 tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios);
424
216 ld = tty_ldisc_ref(tty); 425 ld = tty_ldisc_ref(tty);
217 426
218 if (ld != NULL) { 427 if (ld != NULL) {
@@ -286,8 +495,8 @@ static int get_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb)
286 struct sgttyb tmp; 495 struct sgttyb tmp;
287 496
288 mutex_lock(&tty->termios_mutex); 497 mutex_lock(&tty->termios_mutex);
289 tmp.sg_ispeed = 0; 498 tmp.sg_ispeed = tty->c_ispeed;
290 tmp.sg_ospeed = 0; 499 tmp.sg_ospeed = tty->c_ospeed;
291 tmp.sg_erase = tty->termios->c_cc[VERASE]; 500 tmp.sg_erase = tty->termios->c_cc[VERASE];
292 tmp.sg_kill = tty->termios->c_cc[VKILL]; 501 tmp.sg_kill = tty->termios->c_cc[VKILL];
293 tmp.sg_flags = get_sgflags(tty); 502 tmp.sg_flags = get_sgflags(tty);
@@ -296,7 +505,7 @@ static int get_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb)
296 return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0; 505 return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0;
297} 506}
298 507
299static void set_sgflags(struct termios * termios, int flags) 508static void set_sgflags(struct ktermios * termios, int flags)
300{ 509{
301 termios->c_iflag = ICRNL | IXON; 510 termios->c_iflag = ICRNL | IXON;
302 termios->c_oflag = 0; 511 termios->c_oflag = 0;
@@ -337,7 +546,7 @@ static int set_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb)
337{ 546{
338 int retval; 547 int retval;
339 struct sgttyb tmp; 548 struct sgttyb tmp;
340 struct termios termios; 549 struct ktermios termios;
341 550
342 retval = tty_check_change(tty); 551 retval = tty_check_change(tty);
343 if (retval) 552 if (retval)
@@ -351,6 +560,10 @@ static int set_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb)
351 termios.c_cc[VERASE] = tmp.sg_erase; 560 termios.c_cc[VERASE] = tmp.sg_erase;
352 termios.c_cc[VKILL] = tmp.sg_kill; 561 termios.c_cc[VKILL] = tmp.sg_kill;
353 set_sgflags(&termios, tmp.sg_flags); 562 set_sgflags(&termios, tmp.sg_flags);
563 /* Try and encode into Bfoo format */
564#ifdef BOTHER
565 tty_termios_encode_baud_rate(&termios, termios.c_ispeed, termios.c_ospeed);
566#endif
354 mutex_unlock(&tty->termios_mutex); 567 mutex_unlock(&tty->termios_mutex);
355 change_termios(tty, &termios); 568 change_termios(tty, &termios);
356 return 0; 569 return 0;
@@ -481,16 +694,33 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
481 case TIOCSLTC: 694 case TIOCSLTC:
482 return set_ltchars(real_tty, p); 695 return set_ltchars(real_tty, p);
483#endif 696#endif
697 case TCSETSF:
698 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_OLD);
699 case TCSETSW:
700 return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_OLD);
701 case TCSETS:
702 return set_termios(real_tty, p, TERMIOS_OLD);
703#ifndef TCGETS2
484 case TCGETS: 704 case TCGETS:
485 if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios)) 705 if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios))
486 return -EFAULT; 706 return -EFAULT;
487 return 0; 707 return 0;
488 case TCSETSF: 708#else
709 case TCGETS:
710 if (kernel_termios_to_user_termios_1((struct termios_v1 __user *)arg, real_tty->termios))
711 return -EFAULT;
712 return 0;
713 case TCGETS2:
714 if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios))
715 return -EFAULT;
716 return 0;
717 case TCSETSF2:
489 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT); 718 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT);
490 case TCSETSW: 719 case TCSETSW2:
491 return set_termios(real_tty, p, TERMIOS_WAIT); 720 return set_termios(real_tty, p, TERMIOS_WAIT);
492 case TCSETS: 721 case TCSETS2:
493 return set_termios(real_tty, p, 0); 722 return set_termios(real_tty, p, 0);
723#endif
494 case TCGETA: 724 case TCGETA:
495 return get_termio(real_tty, p); 725 return get_termio(real_tty, p);
496 case TCSETAF: 726 case TCSETAF:
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 1d29999a3439..65cbcf22c31e 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -175,7 +175,7 @@ struct tty_struct {
175 int index; 175 int index;
176 struct tty_ldisc ldisc; 176 struct tty_ldisc ldisc;
177 struct mutex termios_mutex; 177 struct mutex termios_mutex;
178 struct termios *termios, *termios_locked; 178 struct ktermios *termios, *termios_locked;
179 char name[64]; 179 char name[64];
180 int pgrp; 180 int pgrp;
181 int session; 181 int session;
@@ -258,7 +258,7 @@ struct tty_struct {
258 258
259extern void tty_write_flush(struct tty_struct *); 259extern void tty_write_flush(struct tty_struct *);
260 260
261extern struct termios tty_std_termios; 261extern struct ktermios tty_std_termios;
262 262
263extern int kmsg_redirect; 263extern int kmsg_redirect;
264 264
@@ -293,8 +293,9 @@ extern int tty_hung_up_p(struct file * filp);
293extern void do_SAK(struct tty_struct *tty); 293extern void do_SAK(struct tty_struct *tty);
294extern void disassociate_ctty(int priv); 294extern void disassociate_ctty(int priv);
295extern void tty_flip_buffer_push(struct tty_struct *tty); 295extern void tty_flip_buffer_push(struct tty_struct *tty);
296extern int tty_get_baud_rate(struct tty_struct *tty); 296extern speed_t tty_get_baud_rate(struct tty_struct *tty);
297extern int tty_termios_baud_rate(struct termios *termios); 297extern speed_t tty_termios_baud_rate(struct ktermios *termios);
298extern speed_t tty_termios_input_baud_rate(struct ktermios *termios);
298 299
299extern struct tty_ldisc *tty_ldisc_ref(struct tty_struct *); 300extern struct tty_ldisc *tty_ldisc_ref(struct tty_struct *);
300extern void tty_ldisc_deref(struct tty_ldisc *); 301extern void tty_ldisc_deref(struct tty_ldisc *);
diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h
index 5c8473bb6882..659487e3ebeb 100644
--- a/include/linux/tty_driver.h
+++ b/include/linux/tty_driver.h
@@ -53,7 +53,7 @@
53 * device-specific ioctl's. If the ioctl number passed in cmd 53 * device-specific ioctl's. If the ioctl number passed in cmd
54 * is not recognized by the driver, it should return ENOIOCTLCMD. 54 * is not recognized by the driver, it should return ENOIOCTLCMD.
55 * 55 *
56 * void (*set_termios)(struct tty_struct *tty, struct termios * old); 56 * void (*set_termios)(struct tty_struct *tty, struct ktermios * old);
57 * 57 *
58 * This routine allows the tty driver to be notified when 58 * This routine allows the tty driver to be notified when
59 * device's termios settings have changed. Note that a 59 * device's termios settings have changed. Note that a
@@ -132,7 +132,7 @@ struct tty_operations {
132 int (*chars_in_buffer)(struct tty_struct *tty); 132 int (*chars_in_buffer)(struct tty_struct *tty);
133 int (*ioctl)(struct tty_struct *tty, struct file * file, 133 int (*ioctl)(struct tty_struct *tty, struct file * file,
134 unsigned int cmd, unsigned long arg); 134 unsigned int cmd, unsigned long arg);
135 void (*set_termios)(struct tty_struct *tty, struct termios * old); 135 void (*set_termios)(struct tty_struct *tty, struct ktermios * old);
136 void (*throttle)(struct tty_struct * tty); 136 void (*throttle)(struct tty_struct * tty);
137 void (*unthrottle)(struct tty_struct * tty); 137 void (*unthrottle)(struct tty_struct * tty);
138 void (*stop)(struct tty_struct *tty); 138 void (*stop)(struct tty_struct *tty);
@@ -165,7 +165,7 @@ struct tty_driver {
165 int num; /* number of devices allocated */ 165 int num; /* number of devices allocated */
166 short type; /* type of tty driver */ 166 short type; /* type of tty driver */
167 short subtype; /* subtype of tty driver */ 167 short subtype; /* subtype of tty driver */
168 struct termios init_termios; /* Initial termios */ 168 struct ktermios init_termios; /* Initial termios */
169 int flags; /* tty driver flags */ 169 int flags; /* tty driver flags */
170 int refcount; /* for loadable tty drivers */ 170 int refcount; /* for loadable tty drivers */
171 struct proc_dir_entry *proc_entry; /* /proc fs entry */ 171 struct proc_dir_entry *proc_entry; /* /proc fs entry */
@@ -175,8 +175,8 @@ struct tty_driver {
175 * Pointer to the tty data structures 175 * Pointer to the tty data structures
176 */ 176 */
177 struct tty_struct **ttys; 177 struct tty_struct **ttys;
178 struct termios **termios; 178 struct ktermios **termios;
179 struct termios **termios_locked; 179 struct ktermios **termios_locked;
180 void *driver_state; /* only used for the PTY driver */ 180 void *driver_state; /* only used for the PTY driver */
181 181
182 /* 182 /*
@@ -193,7 +193,7 @@ struct tty_driver {
193 int (*chars_in_buffer)(struct tty_struct *tty); 193 int (*chars_in_buffer)(struct tty_struct *tty);
194 int (*ioctl)(struct tty_struct *tty, struct file * file, 194 int (*ioctl)(struct tty_struct *tty, struct file * file,
195 unsigned int cmd, unsigned long arg); 195 unsigned int cmd, unsigned long arg);
196 void (*set_termios)(struct tty_struct *tty, struct termios * old); 196 void (*set_termios)(struct tty_struct *tty, struct ktermios * old);
197 void (*throttle)(struct tty_struct * tty); 197 void (*throttle)(struct tty_struct * tty);
198 void (*unthrottle)(struct tty_struct * tty); 198 void (*unthrottle)(struct tty_struct * tty);
199 void (*stop)(struct tty_struct *tty); 199 void (*stop)(struct tty_struct *tty);
diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h
index 83c6e6c10ebb..d75932e27710 100644
--- a/include/linux/tty_ldisc.h
+++ b/include/linux/tty_ldisc.h
@@ -59,7 +59,7 @@
59 * low-level driver can "grab" an ioctl request before the line 59 * low-level driver can "grab" an ioctl request before the line
60 * discpline has a chance to see it. 60 * discpline has a chance to see it.
61 * 61 *
62 * void (*set_termios)(struct tty_struct *tty, struct termios * old); 62 * void (*set_termios)(struct tty_struct *tty, struct ktermios * old);
63 * 63 *
64 * This function notifies the line discpline that a change has 64 * This function notifies the line discpline that a change has
65 * been made to the termios structure. 65 * been made to the termios structure.
@@ -118,7 +118,7 @@ struct tty_ldisc {
118 const unsigned char * buf, size_t nr); 118 const unsigned char * buf, size_t nr);
119 int (*ioctl)(struct tty_struct * tty, struct file * file, 119 int (*ioctl)(struct tty_struct * tty, struct file * file,
120 unsigned int cmd, unsigned long arg); 120 unsigned int cmd, unsigned long arg);
121 void (*set_termios)(struct tty_struct *tty, struct termios * old); 121 void (*set_termios)(struct tty_struct *tty, struct ktermios * old);
122 unsigned int (*poll)(struct tty_struct *, struct file *, 122 unsigned int (*poll)(struct tty_struct *, struct file *,
123 struct poll_table_struct *); 123 struct poll_table_struct *);
124 int (*hangup)(struct tty_struct *tty); 124 int (*hangup)(struct tty_struct *tty);
diff --git a/include/net/irda/ircomm_tty.h b/include/net/irda/ircomm_tty.h
index 87699cb4ef8c..8dabdd603fe1 100644
--- a/include/net/irda/ircomm_tty.h
+++ b/include/net/irda/ircomm_tty.h
@@ -126,7 +126,7 @@ extern int ircomm_tty_tiocmset(struct tty_struct *tty, struct file *file,
126extern int ircomm_tty_ioctl(struct tty_struct *tty, struct file *file, 126extern int ircomm_tty_ioctl(struct tty_struct *tty, struct file *file,
127 unsigned int cmd, unsigned long arg); 127 unsigned int cmd, unsigned long arg);
128extern void ircomm_tty_set_termios(struct tty_struct *tty, 128extern void ircomm_tty_set_termios(struct tty_struct *tty,
129 struct termios *old_termios); 129 struct ktermios *old_termios);
130extern hashbin_t *ircomm_tty; 130extern hashbin_t *ircomm_tty;
131 131
132#endif 132#endif
diff --git a/net/irda/ircomm/ircomm_tty_ioctl.c b/net/irda/ircomm/ircomm_tty_ioctl.c
index 197e3e7ed7e2..75e39ea599d8 100644
--- a/net/irda/ircomm/ircomm_tty_ioctl.c
+++ b/net/irda/ircomm/ircomm_tty_ioctl.c
@@ -146,7 +146,7 @@ static void ircomm_tty_change_speed(struct ircomm_tty_cb *self)
146 * do something rational. 146 * do something rational.
147 */ 147 */
148void ircomm_tty_set_termios(struct tty_struct *tty, 148void ircomm_tty_set_termios(struct tty_struct *tty,
149 struct termios *old_termios) 149 struct ktermios *old_termios)
150{ 150{
151 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; 151 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
152 unsigned int cflag = tty->termios->c_cflag; 152 unsigned int cflag = tty->termios->c_cflag;