c10d40c4c5cac49739dc7dd842023976acf553cc
[deliverable/linux.git] / drivers / char / tty_ioctl.c
1 /*
2 * linux/drivers/char/tty_ioctl.c
3 *
4 * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
5 *
6 * Modified by Fred N. van Kempen, 01/29/93, to add line disciplines
7 * which can be dynamically activated and de-activated by the line
8 * discipline handling modules (like SLIP).
9 */
10
11 #include <linux/types.h>
12 #include <linux/termios.h>
13 #include <linux/errno.h>
14 #include <linux/sched.h>
15 #include <linux/kernel.h>
16 #include <linux/major.h>
17 #include <linux/tty.h>
18 #include <linux/fcntl.h>
19 #include <linux/string.h>
20 #include <linux/mm.h>
21 #include <linux/module.h>
22 #include <linux/bitops.h>
23 #include <linux/mutex.h>
24 #include <linux/smp_lock.h>
25
26 #include <asm/io.h>
27 #include <asm/uaccess.h>
28 #include <asm/system.h>
29
30 #undef TTY_DEBUG_WAIT_UNTIL_SENT
31
32 #undef DEBUG
33
34 /*
35 * Internal flag options for termios setting behavior
36 */
37 #define TERMIOS_FLUSH 1
38 #define TERMIOS_WAIT 2
39 #define TERMIOS_TERMIO 4
40 #define TERMIOS_OLD 8
41
42
43 int tty_chars_in_buffer(struct tty_struct *tty)
44 {
45 if (tty->ops->chars_in_buffer)
46 return tty->ops->chars_in_buffer(tty);
47 else
48 return 0;
49 }
50
51 EXPORT_SYMBOL(tty_chars_in_buffer);
52
53 int tty_write_room(struct tty_struct *tty)
54 {
55 if (tty->ops->write_room)
56 return tty->ops->write_room(tty);
57 return 2048;
58 }
59
60 EXPORT_SYMBOL(tty_write_room);
61
62 void tty_driver_flush_buffer(struct tty_struct *tty)
63 {
64 if (tty->ops->flush_buffer)
65 tty->ops->flush_buffer(tty);
66 }
67
68 EXPORT_SYMBOL(tty_driver_flush_buffer);
69
70
71 /**
72 * tty_wait_until_sent - wait for I/O to finish
73 * @tty: tty we are waiting for
74 * @timeout: how long we will wait
75 *
76 * Wait for characters pending in a tty driver to hit the wire, or
77 * for a timeout to occur (eg due to flow control)
78 *
79 * Locking: none
80 */
81
82 void tty_wait_until_sent(struct tty_struct *tty, long timeout)
83 {
84 #ifdef TTY_DEBUG_WAIT_UNTIL_SENT
85 char buf[64];
86
87 printk(KERN_DEBUG "%s wait until sent...\n", tty_name(tty, buf));
88 #endif
89 if (!timeout)
90 timeout = MAX_SCHEDULE_TIMEOUT;
91 if (wait_event_interruptible_timeout(tty->write_wait,
92 !tty_chars_in_buffer(tty), timeout) >= 0) {
93 if (tty->ops->wait_until_sent)
94 tty->ops->wait_until_sent(tty, timeout);
95 }
96 }
97 EXPORT_SYMBOL(tty_wait_until_sent);
98
99 static void unset_locked_termios(struct ktermios *termios,
100 struct ktermios *old,
101 struct ktermios *locked)
102 {
103 int i;
104
105 #define NOSET_MASK(x, y, z) (x = ((x) & ~(z)) | ((y) & (z)))
106
107 if (!locked) {
108 printk(KERN_WARNING "Warning?!? termios_locked is NULL.\n");
109 return;
110 }
111
112 NOSET_MASK(termios->c_iflag, old->c_iflag, locked->c_iflag);
113 NOSET_MASK(termios->c_oflag, old->c_oflag, locked->c_oflag);
114 NOSET_MASK(termios->c_cflag, old->c_cflag, locked->c_cflag);
115 NOSET_MASK(termios->c_lflag, old->c_lflag, locked->c_lflag);
116 termios->c_line = locked->c_line ? old->c_line : termios->c_line;
117 for (i = 0; i < NCCS; i++)
118 termios->c_cc[i] = locked->c_cc[i] ?
119 old->c_cc[i] : termios->c_cc[i];
120 /* FIXME: What should we do for i/ospeed */
121 }
122
123 /*
124 * Routine which returns the baud rate of the tty
125 *
126 * Note that the baud_table needs to be kept in sync with the
127 * include/asm/termbits.h file.
128 */
129 static const speed_t baud_table[] = {
130 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
131 9600, 19200, 38400, 57600, 115200, 230400, 460800,
132 #ifdef __sparc__
133 76800, 153600, 307200, 614400, 921600
134 #else
135 500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000,
136 2500000, 3000000, 3500000, 4000000
137 #endif
138 };
139
140 #ifndef __sparc__
141 static const tcflag_t baud_bits[] = {
142 B0, B50, B75, B110, B134, B150, B200, B300, B600,
143 B1200, B1800, B2400, B4800, B9600, B19200, B38400,
144 B57600, B115200, B230400, B460800, B500000, B576000,
145 B921600, B1000000, B1152000, B1500000, B2000000, B2500000,
146 B3000000, B3500000, B4000000
147 };
148 #else
149 static const tcflag_t baud_bits[] = {
150 B0, B50, B75, B110, B134, B150, B200, B300, B600,
151 B1200, B1800, B2400, B4800, B9600, B19200, B38400,
152 B57600, B115200, B230400, B460800, B76800, B153600,
153 B307200, B614400, B921600
154 };
155 #endif
156
157 static int n_baud_table = ARRAY_SIZE(baud_table);
158
159 /**
160 * tty_termios_baud_rate
161 * @termios: termios structure
162 *
163 * Convert termios baud rate data into a speed. This should be called
164 * with the termios lock held if this termios is a terminal termios
165 * structure. May change the termios data. Device drivers can call this
166 * function but should use ->c_[io]speed directly as they are updated.
167 *
168 * Locking: none
169 */
170
171 speed_t tty_termios_baud_rate(struct ktermios *termios)
172 {
173 unsigned int cbaud;
174
175 cbaud = termios->c_cflag & CBAUD;
176
177 #ifdef BOTHER
178 /* Magic token for arbitary speed via c_ispeed/c_ospeed */
179 if (cbaud == BOTHER)
180 return termios->c_ospeed;
181 #endif
182 if (cbaud & CBAUDEX) {
183 cbaud &= ~CBAUDEX;
184
185 if (cbaud < 1 || cbaud + 15 > n_baud_table)
186 termios->c_cflag &= ~CBAUDEX;
187 else
188 cbaud += 15;
189 }
190 return baud_table[cbaud];
191 }
192 EXPORT_SYMBOL(tty_termios_baud_rate);
193
194 /**
195 * tty_termios_input_baud_rate
196 * @termios: termios structure
197 *
198 * Convert termios baud rate data into a speed. This should be called
199 * with the termios lock held if this termios is a terminal termios
200 * structure. May change the termios data. Device drivers can call this
201 * function but should use ->c_[io]speed directly as they are updated.
202 *
203 * Locking: none
204 */
205
206 speed_t tty_termios_input_baud_rate(struct ktermios *termios)
207 {
208 #ifdef IBSHIFT
209 unsigned int cbaud = (termios->c_cflag >> IBSHIFT) & CBAUD;
210
211 if (cbaud == B0)
212 return tty_termios_baud_rate(termios);
213
214 /* Magic token for arbitary speed via c_ispeed*/
215 if (cbaud == BOTHER)
216 return termios->c_ispeed;
217
218 if (cbaud & CBAUDEX) {
219 cbaud &= ~CBAUDEX;
220
221 if (cbaud < 1 || cbaud + 15 > n_baud_table)
222 termios->c_cflag &= ~(CBAUDEX << IBSHIFT);
223 else
224 cbaud += 15;
225 }
226 return baud_table[cbaud];
227 #else
228 return tty_termios_baud_rate(termios);
229 #endif
230 }
231 EXPORT_SYMBOL(tty_termios_input_baud_rate);
232
233 /**
234 * tty_termios_encode_baud_rate
235 * @termios: ktermios structure holding user requested state
236 * @ispeed: input speed
237 * @ospeed: output speed
238 *
239 * Encode the speeds set into the passed termios structure. This is
240 * used as a library helper for drivers os that they can report back
241 * the actual speed selected when it differs from the speed requested
242 *
243 * For maximal back compatibility with legacy SYS5/POSIX *nix behaviour
244 * we need to carefully set the bits when the user does not get the
245 * desired speed. We allow small margins and preserve as much of possible
246 * of the input intent to keep compatiblity.
247 *
248 * Locking: Caller should hold termios lock. This is already held
249 * when calling this function from the driver termios handler.
250 *
251 * The ifdefs deal with platforms whose owners have yet to update them
252 * and will all go away once this is done.
253 */
254
255 void tty_termios_encode_baud_rate(struct ktermios *termios,
256 speed_t ibaud, speed_t obaud)
257 {
258 int i = 0;
259 int ifound = -1, ofound = -1;
260 int iclose = ibaud/50, oclose = obaud/50;
261 int ibinput = 0;
262
263 if (obaud == 0) /* CD dropped */
264 ibaud = 0; /* Clear ibaud to be sure */
265
266 termios->c_ispeed = ibaud;
267 termios->c_ospeed = obaud;
268
269 #ifdef BOTHER
270 /* If the user asked for a precise weird speed give a precise weird
271 answer. If they asked for a Bfoo speed they many have problems
272 digesting non-exact replies so fuzz a bit */
273
274 if ((termios->c_cflag & CBAUD) == BOTHER)
275 oclose = 0;
276 if (((termios->c_cflag >> IBSHIFT) & CBAUD) == BOTHER)
277 iclose = 0;
278 if ((termios->c_cflag >> IBSHIFT) & CBAUD)
279 ibinput = 1; /* An input speed was specified */
280 #endif
281 termios->c_cflag &= ~CBAUD;
282
283 /*
284 * Our goal is to find a close match to the standard baud rate
285 * returned. Walk the baud rate table and if we get a very close
286 * match then report back the speed as a POSIX Bxxxx value by
287 * preference
288 */
289
290 do {
291 if (obaud - oclose <= baud_table[i] &&
292 obaud + oclose >= baud_table[i]) {
293 termios->c_cflag |= baud_bits[i];
294 ofound = i;
295 }
296 if (ibaud - iclose <= baud_table[i] &&
297 ibaud + iclose >= baud_table[i]) {
298 /* For the case input == output don't set IBAUD bits
299 if the user didn't do so */
300 if (ofound == i && !ibinput)
301 ifound = i;
302 #ifdef IBSHIFT
303 else {
304 ifound = i;
305 termios->c_cflag |= (baud_bits[i] << IBSHIFT);
306 }
307 #endif
308 }
309 } while (++i < n_baud_table);
310
311 /*
312 * If we found no match then use BOTHER if provided or warn
313 * the user their platform maintainer needs to wake up if not.
314 */
315 #ifdef BOTHER
316 if (ofound == -1)
317 termios->c_cflag |= BOTHER;
318 /* Set exact input bits only if the input and output differ or the
319 user already did */
320 if (ifound == -1 && (ibaud != obaud || ibinput))
321 termios->c_cflag |= (BOTHER << IBSHIFT);
322 #else
323 if (ifound == -1 || ofound == -1) {
324 static int warned;
325 if (!warned++)
326 printk(KERN_WARNING "tty: Unable to return correct "
327 "speed data as your architecture needs updating.\n");
328 }
329 #endif
330 }
331 EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate);
332
333 void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud)
334 {
335 tty_termios_encode_baud_rate(tty->termios, ibaud, obaud);
336 }
337 EXPORT_SYMBOL_GPL(tty_encode_baud_rate);
338
339 /**
340 * tty_get_baud_rate - get tty bit rates
341 * @tty: tty to query
342 *
343 * Returns the baud rate as an integer for this terminal. The
344 * termios lock must be held by the caller and the terminal bit
345 * flags may be updated.
346 *
347 * Locking: none
348 */
349
350 speed_t tty_get_baud_rate(struct tty_struct *tty)
351 {
352 speed_t baud = tty_termios_baud_rate(tty->termios);
353
354 if (baud == 38400 && tty->alt_speed) {
355 if (!tty->warned) {
356 printk(KERN_WARNING "Use of setserial/setrocket to "
357 "set SPD_* flags is deprecated\n");
358 tty->warned = 1;
359 }
360 baud = tty->alt_speed;
361 }
362
363 return baud;
364 }
365 EXPORT_SYMBOL(tty_get_baud_rate);
366
367 /**
368 * tty_termios_copy_hw - copy hardware settings
369 * @new: New termios
370 * @old: Old termios
371 *
372 * Propogate the hardware specific terminal setting bits from
373 * the old termios structure to the new one. This is used in cases
374 * where the hardware does not support reconfiguration or as a helper
375 * in some cases where only minimal reconfiguration is supported
376 */
377
378 void tty_termios_copy_hw(struct ktermios *new, struct ktermios *old)
379 {
380 /* The bits a dumb device handles in software. Smart devices need
381 to always provide a set_termios method */
382 new->c_cflag &= HUPCL | CREAD | CLOCAL;
383 new->c_cflag |= old->c_cflag & ~(HUPCL | CREAD | CLOCAL);
384 new->c_ispeed = old->c_ispeed;
385 new->c_ospeed = old->c_ospeed;
386 }
387 EXPORT_SYMBOL(tty_termios_copy_hw);
388
389 /**
390 * tty_termios_hw_change - check for setting change
391 * @a: termios
392 * @b: termios to compare
393 *
394 * Check if any of the bits that affect a dumb device have changed
395 * between the two termios structures, or a speed change is needed.
396 */
397
398 int tty_termios_hw_change(struct ktermios *a, struct ktermios *b)
399 {
400 if (a->c_ispeed != b->c_ispeed || a->c_ospeed != b->c_ospeed)
401 return 1;
402 if ((a->c_cflag ^ b->c_cflag) & ~(HUPCL | CREAD | CLOCAL))
403 return 1;
404 return 0;
405 }
406 EXPORT_SYMBOL(tty_termios_hw_change);
407
408 /**
409 * change_termios - update termios values
410 * @tty: tty to update
411 * @new_termios: desired new value
412 *
413 * Perform updates to the termios values set on this terminal. There
414 * is a bit of layering violation here with n_tty in terms of the
415 * internal knowledge of this function.
416 *
417 * Locking: termios_sem
418 */
419
420 static void change_termios(struct tty_struct *tty, struct ktermios *new_termios)
421 {
422 int canon_change;
423 struct ktermios old_termios;
424 struct tty_ldisc *ld;
425 unsigned long flags;
426
427 /*
428 * Perform the actual termios internal changes under lock.
429 */
430
431
432 /* FIXME: we need to decide on some locking/ordering semantics
433 for the set_termios notification eventually */
434 mutex_lock(&tty->termios_mutex);
435 old_termios = *tty->termios;
436 *tty->termios = *new_termios;
437 unset_locked_termios(tty->termios, &old_termios, tty->termios_locked);
438 canon_change = (old_termios.c_lflag ^ tty->termios->c_lflag) & ICANON;
439 if (canon_change) {
440 memset(&tty->read_flags, 0, sizeof tty->read_flags);
441 tty->canon_head = tty->read_tail;
442 tty->canon_data = 0;
443 tty->erasing = 0;
444 }
445
446 /* This bit should be in the ldisc code */
447 if (canon_change && !L_ICANON(tty) && tty->read_cnt)
448 /* Get characters left over from canonical mode. */
449 wake_up_interruptible(&tty->read_wait);
450
451 /* See if packet mode change of state. */
452 if (tty->link && tty->link->packet) {
453 int old_flow = ((old_termios.c_iflag & IXON) &&
454 (old_termios.c_cc[VSTOP] == '\023') &&
455 (old_termios.c_cc[VSTART] == '\021'));
456 int new_flow = (I_IXON(tty) &&
457 STOP_CHAR(tty) == '\023' &&
458 START_CHAR(tty) == '\021');
459 if (old_flow != new_flow) {
460 spin_lock_irqsave(&tty->ctrl_lock, flags);
461 tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP);
462 if (new_flow)
463 tty->ctrl_status |= TIOCPKT_DOSTOP;
464 else
465 tty->ctrl_status |= TIOCPKT_NOSTOP;
466 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
467 wake_up_interruptible(&tty->link->read_wait);
468 }
469 }
470
471 if (tty->ops->set_termios)
472 (*tty->ops->set_termios)(tty, &old_termios);
473 else
474 tty_termios_copy_hw(tty->termios, &old_termios);
475
476 ld = tty_ldisc_ref(tty);
477 if (ld != NULL) {
478 if (ld->set_termios)
479 (ld->set_termios)(tty, &old_termios);
480 tty_ldisc_deref(ld);
481 }
482 mutex_unlock(&tty->termios_mutex);
483 }
484
485 /**
486 * set_termios - set termios values for a tty
487 * @tty: terminal device
488 * @arg: user data
489 * @opt: option information
490 *
491 * Helper function to prepare termios data and run necessary other
492 * functions before using change_termios to do the actual changes.
493 *
494 * Locking:
495 * Called functions take ldisc and termios_sem locks
496 */
497
498 static int set_termios(struct tty_struct *tty, void __user *arg, int opt)
499 {
500 struct ktermios tmp_termios;
501 struct tty_ldisc *ld;
502 int retval = tty_check_change(tty);
503
504 if (retval)
505 return retval;
506
507 mutex_lock(&tty->termios_mutex);
508 memcpy(&tmp_termios, tty->termios, sizeof(struct ktermios));
509 mutex_unlock(&tty->termios_mutex);
510
511 if (opt & TERMIOS_TERMIO) {
512 if (user_termio_to_kernel_termios(&tmp_termios,
513 (struct termio __user *)arg))
514 return -EFAULT;
515 #ifdef TCGETS2
516 } else if (opt & TERMIOS_OLD) {
517 if (user_termios_to_kernel_termios_1(&tmp_termios,
518 (struct termios __user *)arg))
519 return -EFAULT;
520 } else {
521 if (user_termios_to_kernel_termios(&tmp_termios,
522 (struct termios2 __user *)arg))
523 return -EFAULT;
524 }
525 #else
526 } else if (user_termios_to_kernel_termios(&tmp_termios,
527 (struct termios __user *)arg))
528 return -EFAULT;
529 #endif
530
531 /* If old style Bfoo values are used then load c_ispeed/c_ospeed
532 * with the real speed so its unconditionally usable */
533 tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios);
534 tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios);
535
536 ld = tty_ldisc_ref(tty);
537
538 if (ld != NULL) {
539 if ((opt & TERMIOS_FLUSH) && ld->flush_buffer)
540 ld->flush_buffer(tty);
541 tty_ldisc_deref(ld);
542 }
543
544 if (opt & TERMIOS_WAIT) {
545 tty_wait_until_sent(tty, 0);
546 if (signal_pending(current))
547 return -EINTR;
548 }
549
550 change_termios(tty, &tmp_termios);
551
552 /* FIXME: Arguably if tmp_termios == tty->termios AND the
553 actual requested termios was not tmp_termios then we may
554 want to return an error as no user requested change has
555 succeeded */
556 return 0;
557 }
558
559 static int get_termio(struct tty_struct *tty, struct termio __user *termio)
560 {
561 if (kernel_termios_to_user_termio(termio, tty->termios))
562 return -EFAULT;
563 return 0;
564 }
565
566 static unsigned long inq_canon(struct tty_struct *tty)
567 {
568 int nr, head, tail;
569
570 if (!tty->canon_data || !tty->read_buf)
571 return 0;
572 head = tty->canon_head;
573 tail = tty->read_tail;
574 nr = (head - tail) & (N_TTY_BUF_SIZE-1);
575 /* Skip EOF-chars.. */
576 while (head != tail) {
577 if (test_bit(tail, tty->read_flags) &&
578 tty->read_buf[tail] == __DISABLED_CHAR)
579 nr--;
580 tail = (tail+1) & (N_TTY_BUF_SIZE-1);
581 }
582 return nr;
583 }
584
585 #ifdef TIOCGETP
586 /*
587 * These are deprecated, but there is limited support..
588 *
589 * The "sg_flags" translation is a joke..
590 */
591 static int get_sgflags(struct tty_struct *tty)
592 {
593 int flags = 0;
594
595 if (!(tty->termios->c_lflag & ICANON)) {
596 if (tty->termios->c_lflag & ISIG)
597 flags |= 0x02; /* cbreak */
598 else
599 flags |= 0x20; /* raw */
600 }
601 if (tty->termios->c_lflag & ECHO)
602 flags |= 0x08; /* echo */
603 if (tty->termios->c_oflag & OPOST)
604 if (tty->termios->c_oflag & ONLCR)
605 flags |= 0x10; /* crmod */
606 return flags;
607 }
608
609 static int get_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
610 {
611 struct sgttyb tmp;
612
613 mutex_lock(&tty->termios_mutex);
614 tmp.sg_ispeed = tty->termios->c_ispeed;
615 tmp.sg_ospeed = tty->termios->c_ospeed;
616 tmp.sg_erase = tty->termios->c_cc[VERASE];
617 tmp.sg_kill = tty->termios->c_cc[VKILL];
618 tmp.sg_flags = get_sgflags(tty);
619 mutex_unlock(&tty->termios_mutex);
620
621 return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0;
622 }
623
624 static void set_sgflags(struct ktermios *termios, int flags)
625 {
626 termios->c_iflag = ICRNL | IXON;
627 termios->c_oflag = 0;
628 termios->c_lflag = ISIG | ICANON;
629 if (flags & 0x02) { /* cbreak */
630 termios->c_iflag = 0;
631 termios->c_lflag &= ~ICANON;
632 }
633 if (flags & 0x08) { /* echo */
634 termios->c_lflag |= ECHO | ECHOE | ECHOK |
635 ECHOCTL | ECHOKE | IEXTEN;
636 }
637 if (flags & 0x10) { /* crmod */
638 termios->c_oflag |= OPOST | ONLCR;
639 }
640 if (flags & 0x20) { /* raw */
641 termios->c_iflag = 0;
642 termios->c_lflag &= ~(ISIG | ICANON);
643 }
644 if (!(termios->c_lflag & ICANON)) {
645 termios->c_cc[VMIN] = 1;
646 termios->c_cc[VTIME] = 0;
647 }
648 }
649
650 /**
651 * set_sgttyb - set legacy terminal values
652 * @tty: tty structure
653 * @sgttyb: pointer to old style terminal structure
654 *
655 * Updates a terminal from the legacy BSD style terminal information
656 * structure.
657 *
658 * Locking: termios_sem
659 */
660
661 static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
662 {
663 int retval;
664 struct sgttyb tmp;
665 struct ktermios termios;
666
667 retval = tty_check_change(tty);
668 if (retval)
669 return retval;
670
671 if (copy_from_user(&tmp, sgttyb, sizeof(tmp)))
672 return -EFAULT;
673
674 mutex_lock(&tty->termios_mutex);
675 termios = *tty->termios;
676 termios.c_cc[VERASE] = tmp.sg_erase;
677 termios.c_cc[VKILL] = tmp.sg_kill;
678 set_sgflags(&termios, tmp.sg_flags);
679 /* Try and encode into Bfoo format */
680 #ifdef BOTHER
681 tty_termios_encode_baud_rate(&termios, termios.c_ispeed,
682 termios.c_ospeed);
683 #endif
684 mutex_unlock(&tty->termios_mutex);
685 change_termios(tty, &termios);
686 return 0;
687 }
688 #endif
689
690 #ifdef TIOCGETC
691 static int get_tchars(struct tty_struct *tty, struct tchars __user *tchars)
692 {
693 struct tchars tmp;
694
695 mutex_lock(&tty->termios_mutex);
696 tmp.t_intrc = tty->termios->c_cc[VINTR];
697 tmp.t_quitc = tty->termios->c_cc[VQUIT];
698 tmp.t_startc = tty->termios->c_cc[VSTART];
699 tmp.t_stopc = tty->termios->c_cc[VSTOP];
700 tmp.t_eofc = tty->termios->c_cc[VEOF];
701 tmp.t_brkc = tty->termios->c_cc[VEOL2]; /* what is brkc anyway? */
702 mutex_unlock(&tty->termios_mutex);
703 return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
704 }
705
706 static int set_tchars(struct tty_struct *tty, struct tchars __user *tchars)
707 {
708 struct tchars tmp;
709
710 if (copy_from_user(&tmp, tchars, sizeof(tmp)))
711 return -EFAULT;
712 mutex_lock(&tty->termios_mutex);
713 tty->termios->c_cc[VINTR] = tmp.t_intrc;
714 tty->termios->c_cc[VQUIT] = tmp.t_quitc;
715 tty->termios->c_cc[VSTART] = tmp.t_startc;
716 tty->termios->c_cc[VSTOP] = tmp.t_stopc;
717 tty->termios->c_cc[VEOF] = tmp.t_eofc;
718 tty->termios->c_cc[VEOL2] = tmp.t_brkc; /* what is brkc anyway? */
719 mutex_unlock(&tty->termios_mutex);
720 return 0;
721 }
722 #endif
723
724 #ifdef TIOCGLTC
725 static int get_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
726 {
727 struct ltchars tmp;
728
729 mutex_lock(&tty->termios_mutex);
730 tmp.t_suspc = tty->termios->c_cc[VSUSP];
731 /* what is dsuspc anyway? */
732 tmp.t_dsuspc = tty->termios->c_cc[VSUSP];
733 tmp.t_rprntc = tty->termios->c_cc[VREPRINT];
734 /* what is flushc anyway? */
735 tmp.t_flushc = tty->termios->c_cc[VEOL2];
736 tmp.t_werasc = tty->termios->c_cc[VWERASE];
737 tmp.t_lnextc = tty->termios->c_cc[VLNEXT];
738 mutex_unlock(&tty->termios_mutex);
739 return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
740 }
741
742 static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
743 {
744 struct ltchars tmp;
745
746 if (copy_from_user(&tmp, ltchars, sizeof(tmp)))
747 return -EFAULT;
748
749 mutex_lock(&tty->termios_mutex);
750 tty->termios->c_cc[VSUSP] = tmp.t_suspc;
751 /* what is dsuspc anyway? */
752 tty->termios->c_cc[VEOL2] = tmp.t_dsuspc;
753 tty->termios->c_cc[VREPRINT] = tmp.t_rprntc;
754 /* what is flushc anyway? */
755 tty->termios->c_cc[VEOL2] = tmp.t_flushc;
756 tty->termios->c_cc[VWERASE] = tmp.t_werasc;
757 tty->termios->c_cc[VLNEXT] = tmp.t_lnextc;
758 mutex_unlock(&tty->termios_mutex);
759 return 0;
760 }
761 #endif
762
763 /**
764 * send_prio_char - send priority character
765 *
766 * Send a high priority character to the tty even if stopped
767 *
768 * Locking: none for xchar method, write ordering for write method.
769 */
770
771 static int send_prio_char(struct tty_struct *tty, char ch)
772 {
773 int was_stopped = tty->stopped;
774
775 if (tty->ops->send_xchar) {
776 tty->ops->send_xchar(tty, ch);
777 return 0;
778 }
779
780 if (tty_write_lock(tty, 0) < 0)
781 return -ERESTARTSYS;
782
783 if (was_stopped)
784 start_tty(tty);
785 tty->ops->write(tty, &ch, 1);
786 if (was_stopped)
787 stop_tty(tty);
788 tty_write_unlock(tty);
789 return 0;
790 }
791
792 /**
793 * tty_change_softcar - carrier change ioctl helper
794 * @tty: tty to update
795 * @arg: enable/disable CLOCAL
796 *
797 * Perform a change to the CLOCAL state and call into the driver
798 * layer to make it visible. All done with the termios mutex
799 */
800
801 static int tty_change_softcar(struct tty_struct *tty, int arg)
802 {
803 int ret = 0;
804 int bit = arg ? CLOCAL : 0;
805 struct ktermios old;
806
807 mutex_lock(&tty->termios_mutex);
808 old = *tty->termios;
809 tty->termios->c_cflag &= ~CLOCAL;
810 tty->termios->c_cflag |= bit;
811 if (tty->ops->set_termios)
812 tty->ops->set_termios(tty, &old);
813 if ((tty->termios->c_cflag & CLOCAL) != bit)
814 ret = -EINVAL;
815 mutex_unlock(&tty->termios_mutex);
816 return ret;
817 }
818
819 /**
820 * tty_mode_ioctl - mode related ioctls
821 * @tty: tty for the ioctl
822 * @file: file pointer for the tty
823 * @cmd: command
824 * @arg: ioctl argument
825 *
826 * Perform non line discipline specific mode control ioctls. This
827 * is designed to be called by line disciplines to ensure they provide
828 * consistent mode setting.
829 */
830
831 int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
832 unsigned int cmd, unsigned long arg)
833 {
834 struct tty_struct *real_tty;
835 void __user *p = (void __user *)arg;
836
837 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
838 tty->driver->subtype == PTY_TYPE_MASTER)
839 real_tty = tty->link;
840 else
841 real_tty = tty;
842
843 switch (cmd) {
844 #ifdef TIOCGETP
845 case TIOCGETP:
846 return get_sgttyb(real_tty, (struct sgttyb __user *) arg);
847 case TIOCSETP:
848 case TIOCSETN:
849 return set_sgttyb(real_tty, (struct sgttyb __user *) arg);
850 #endif
851 #ifdef TIOCGETC
852 case TIOCGETC:
853 return get_tchars(real_tty, p);
854 case TIOCSETC:
855 return set_tchars(real_tty, p);
856 #endif
857 #ifdef TIOCGLTC
858 case TIOCGLTC:
859 return get_ltchars(real_tty, p);
860 case TIOCSLTC:
861 return set_ltchars(real_tty, p);
862 #endif
863 case TCSETSF:
864 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_OLD);
865 case TCSETSW:
866 return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_OLD);
867 case TCSETS:
868 return set_termios(real_tty, p, TERMIOS_OLD);
869 #ifndef TCGETS2
870 case TCGETS:
871 if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios))
872 return -EFAULT;
873 return 0;
874 #else
875 case TCGETS:
876 if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios))
877 return -EFAULT;
878 return 0;
879 case TCGETS2:
880 if (kernel_termios_to_user_termios((struct termios2 __user *)arg, real_tty->termios))
881 return -EFAULT;
882 return 0;
883 case TCSETSF2:
884 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT);
885 case TCSETSW2:
886 return set_termios(real_tty, p, TERMIOS_WAIT);
887 case TCSETS2:
888 return set_termios(real_tty, p, 0);
889 #endif
890 case TCGETA:
891 return get_termio(real_tty, p);
892 case TCSETAF:
893 return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_TERMIO);
894 case TCSETAW:
895 return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_TERMIO);
896 case TCSETA:
897 return set_termios(real_tty, p, TERMIOS_TERMIO);
898 #ifndef TCGETS2
899 case TIOCGLCKTRMIOS:
900 if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios_locked))
901 return -EFAULT;
902 return 0;
903 case TIOCSLCKTRMIOS:
904 if (!capable(CAP_SYS_ADMIN))
905 return -EPERM;
906 if (user_termios_to_kernel_termios(real_tty->termios_locked,
907 (struct termios __user *) arg))
908 return -EFAULT;
909 return 0;
910 #else
911 case TIOCGLCKTRMIOS:
912 if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios_locked))
913 return -EFAULT;
914 return 0;
915 case TIOCSLCKTRMIOS:
916 if (!capable(CAP_SYS_ADMIN))
917 return -EPERM;
918 if (user_termios_to_kernel_termios_1(real_tty->termios_locked,
919 (struct termios __user *) arg))
920 return -EFAULT;
921 return 0;
922 #endif
923 case TIOCGSOFTCAR:
924 return put_user(C_CLOCAL(tty) ? 1 : 0,
925 (int __user *)arg);
926 case TIOCSSOFTCAR:
927 if (get_user(arg, (unsigned int __user *) arg))
928 return -EFAULT;
929 return tty_change_softcar(tty, arg);
930 default:
931 return -ENOIOCTLCMD;
932 }
933 }
934 EXPORT_SYMBOL_GPL(tty_mode_ioctl);
935
936 int tty_perform_flush(struct tty_struct *tty, unsigned long arg)
937 {
938 struct tty_ldisc *ld;
939 int retval = tty_check_change(tty);
940 if (retval)
941 return retval;
942
943 ld = tty_ldisc_ref(tty);
944 switch (arg) {
945 case TCIFLUSH:
946 if (ld && ld->flush_buffer)
947 ld->flush_buffer(tty);
948 break;
949 case TCIOFLUSH:
950 if (ld && ld->flush_buffer)
951 ld->flush_buffer(tty);
952 /* fall through */
953 case TCOFLUSH:
954 tty_driver_flush_buffer(tty);
955 break;
956 default:
957 tty_ldisc_deref(ld);
958 return -EINVAL;
959 }
960 tty_ldisc_deref(ld);
961 return 0;
962 }
963 EXPORT_SYMBOL_GPL(tty_perform_flush);
964
965 int n_tty_ioctl(struct tty_struct *tty, struct file *file,
966 unsigned int cmd, unsigned long arg)
967 {
968 struct tty_struct *real_tty;
969 unsigned long flags;
970 int retval;
971
972 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
973 tty->driver->subtype == PTY_TYPE_MASTER)
974 real_tty = tty->link;
975 else
976 real_tty = tty;
977
978 switch (cmd) {
979 case TCXONC:
980 retval = tty_check_change(tty);
981 if (retval)
982 return retval;
983 switch (arg) {
984 case TCOOFF:
985 if (!tty->flow_stopped) {
986 tty->flow_stopped = 1;
987 stop_tty(tty);
988 }
989 break;
990 case TCOON:
991 if (tty->flow_stopped) {
992 tty->flow_stopped = 0;
993 start_tty(tty);
994 }
995 break;
996 case TCIOFF:
997 if (STOP_CHAR(tty) != __DISABLED_CHAR)
998 return send_prio_char(tty, STOP_CHAR(tty));
999 break;
1000 case TCION:
1001 if (START_CHAR(tty) != __DISABLED_CHAR)
1002 return send_prio_char(tty, START_CHAR(tty));
1003 break;
1004 default:
1005 return -EINVAL;
1006 }
1007 return 0;
1008 case TCFLSH:
1009 return tty_perform_flush(tty, arg);
1010 case TIOCOUTQ:
1011 return put_user(tty_chars_in_buffer(tty), (int __user *) arg);
1012 case TIOCINQ:
1013 retval = tty->read_cnt;
1014 if (L_ICANON(tty))
1015 retval = inq_canon(tty);
1016 return put_user(retval, (unsigned int __user *) arg);
1017 case TIOCPKT:
1018 {
1019 int pktmode;
1020
1021 if (tty->driver->type != TTY_DRIVER_TYPE_PTY ||
1022 tty->driver->subtype != PTY_TYPE_MASTER)
1023 return -ENOTTY;
1024 if (get_user(pktmode, (int __user *) arg))
1025 return -EFAULT;
1026 spin_lock_irqsave(&tty->ctrl_lock, flags);
1027 if (pktmode) {
1028 if (!tty->packet) {
1029 tty->packet = 1;
1030 tty->link->ctrl_status = 0;
1031 }
1032 } else
1033 tty->packet = 0;
1034 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
1035 return 0;
1036 }
1037 default:
1038 /* Try the mode commands */
1039 return tty_mode_ioctl(tty, file, cmd, arg);
1040 }
1041 }
1042 EXPORT_SYMBOL(n_tty_ioctl);
This page took 0.070352 seconds and 4 git commands to generate.