.. | .. |
---|
21 | 21 | #include <linux/bitops.h> |
---|
22 | 22 | #include <linux/mutex.h> |
---|
23 | 23 | #include <linux/compat.h> |
---|
| 24 | +#include "tty.h" |
---|
24 | 25 | |
---|
25 | 26 | #include <asm/io.h> |
---|
26 | 27 | #include <linux/uaccess.h> |
---|
.. | .. |
---|
397 | 398 | tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios); |
---|
398 | 399 | tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios); |
---|
399 | 400 | |
---|
400 | | - ld = tty_ldisc_ref(tty); |
---|
| 401 | + if (opt & (TERMIOS_FLUSH|TERMIOS_WAIT)) { |
---|
| 402 | +retry_write_wait: |
---|
| 403 | + retval = wait_event_interruptible(tty->write_wait, !tty_chars_in_buffer(tty)); |
---|
| 404 | + if (retval < 0) |
---|
| 405 | + return retval; |
---|
401 | 406 | |
---|
402 | | - if (ld != NULL) { |
---|
403 | | - if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer) |
---|
404 | | - ld->ops->flush_buffer(tty); |
---|
405 | | - tty_ldisc_deref(ld); |
---|
| 407 | + if (tty_write_lock(tty, 0) < 0) |
---|
| 408 | + goto retry_write_wait; |
---|
| 409 | + |
---|
| 410 | + /* Racing writer? */ |
---|
| 411 | + if (tty_chars_in_buffer(tty)) { |
---|
| 412 | + tty_write_unlock(tty); |
---|
| 413 | + goto retry_write_wait; |
---|
| 414 | + } |
---|
| 415 | + |
---|
| 416 | + ld = tty_ldisc_ref(tty); |
---|
| 417 | + if (ld != NULL) { |
---|
| 418 | + if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer) |
---|
| 419 | + ld->ops->flush_buffer(tty); |
---|
| 420 | + tty_ldisc_deref(ld); |
---|
| 421 | + } |
---|
| 422 | + |
---|
| 423 | + if ((opt & TERMIOS_WAIT) && tty->ops->wait_until_sent) { |
---|
| 424 | + tty->ops->wait_until_sent(tty, 0); |
---|
| 425 | + if (signal_pending(current)) { |
---|
| 426 | + tty_write_unlock(tty); |
---|
| 427 | + return -ERESTARTSYS; |
---|
| 428 | + } |
---|
| 429 | + } |
---|
| 430 | + |
---|
| 431 | + tty_set_termios(tty, &tmp_termios); |
---|
| 432 | + |
---|
| 433 | + tty_write_unlock(tty); |
---|
| 434 | + } else { |
---|
| 435 | + tty_set_termios(tty, &tmp_termios); |
---|
406 | 436 | } |
---|
407 | | - |
---|
408 | | - if (opt & TERMIOS_WAIT) { |
---|
409 | | - tty_wait_until_sent(tty, 0); |
---|
410 | | - if (signal_pending(current)) |
---|
411 | | - return -ERESTARTSYS; |
---|
412 | | - } |
---|
413 | | - |
---|
414 | | - tty_set_termios(tty, &tmp_termios); |
---|
415 | 437 | |
---|
416 | 438 | /* FIXME: Arguably if tmp_termios == tty->termios AND the |
---|
417 | 439 | actual requested termios was not tmp_termios then we may |
---|