diff options
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/tty_io.c | 137 | ||||
-rw-r--r-- | drivers/char/tty_ioctl.c | 258 |
2 files changed, 282 insertions, 113 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) |
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 | ||
85 | EXPORT_SYMBOL(tty_wait_until_sent); | 86 | EXPORT_SYMBOL(tty_wait_until_sent); |
86 | 87 | ||
87 | static void unset_locked_termios(struct termios *termios, | 88 | static 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 | */ | ||
118 | static 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__ | ||
130 | static 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 | ||
138 | static 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 | |||
146 | static 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 | |||
160 | speed_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 | |||
182 | EXPORT_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 | |||
196 | speed_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 | |||
222 | EXPORT_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 | |||
242 | void 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 | |||
274 | EXPORT_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 | |||
289 | speed_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 | |||
305 | EXPORT_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 | ||
122 | static void change_termios(struct tty_struct * tty, struct termios * new_termios) | 319 | static 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 | ||
196 | static int set_termios(struct tty_struct * tty, void __user *arg, int opt) | 393 | static 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 | ||
299 | static void set_sgflags(struct termios * termios, int flags) | 508 | static 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: |