| .. | .. | 
|---|
| 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 | 
|---|