Lines Matching +full:non +full:- +full:exclusive
1 // SPDX-License-Identifier: GPL-1.0+
3 * n_tty.c --- implements the N_TTY line discipline.
19 * Reduced memory usage for older ARM systems - Russell King.
26 * waiting writing processes-Sapan Bhatia <[email protected]>.
60 * This defines the low- and high-watermarks for throttling and
80 #define ECHO_DISCARD_WATERMARK N_TTY_BUF_SIZE - (ECHO_BLOCK + 32)
91 /* producer-published */
100 /* private to n_tty_receive_overrun (single-threaded) */
104 /* non-atomic */
107 /* must hold exclusive termios_rwsem to reset these */
116 /* consumer-published */
132 #define MASK(x) ((x) & (N_TTY_BUF_SIZE - 1))
136 return ldata->read_head - ldata->read_tail; in read_cnt()
141 return ldata->read_buf[MASK(i)]; in read_buf()
146 return &ldata->read_buf[MASK(i)]; in read_buf_addr()
152 return ldata->echo_buf[MASK(i)]; in echo_buf()
157 return &ldata->echo_buf[MASK(i)]; in echo_buf_addr()
170 struct n_tty_data *ldata = tty->disc_data; in tty_copy()
171 size_t size = N_TTY_BUF_SIZE - tail; in tty_copy()
179 n -= size; in tty_copy()
180 from = ldata->read_buf; in tty_copy()
189 * n_tty_kick_worker - start input worker (if required)
192 * Re-schedules the flip buffer work if it may have stopped.
195 * * Caller holds exclusive %termios_rwsem, or
197 * holds non-exclusive %termios_rwsem
201 struct n_tty_data *ldata = tty->disc_data; in n_tty_kick_worker()
204 if (unlikely(READ_ONCE(ldata->no_room))) { in n_tty_kick_worker()
205 WRITE_ONCE(ldata->no_room, 0); in n_tty_kick_worker()
207 WARN_RATELIMIT(tty->port->itty == NULL, in n_tty_kick_worker()
209 /* see if ldisc has been killed - if so, this means that in n_tty_kick_worker()
210 * even though the ldisc has been halted and ->buf.work in n_tty_kick_worker()
211 * cancelled, ->buf.work is about to be rescheduled in n_tty_kick_worker()
213 WARN_RATELIMIT(test_bit(TTY_LDISC_HALTED, &tty->flags), in n_tty_kick_worker()
215 tty_buffer_restart_work(tty->port); in n_tty_kick_worker()
221 const struct n_tty_data *ldata = tty->disc_data; in chars_in_buffer()
222 size_t head = ldata->icanon ? ldata->canon_head : ldata->commit_head; in chars_in_buffer()
224 return head - ldata->read_tail; in chars_in_buffer()
228 * n_tty_write_wakeup - asynchronous I/O notifier
236 clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); in n_tty_write_wakeup()
237 kill_fasync(&tty->fasync, SIGIO, POLL_OUT); in n_tty_write_wakeup()
242 struct n_tty_data *ldata = tty->disc_data; in n_tty_check_throttle()
249 if (ldata->icanon && ldata->canon_head == ldata->read_tail) in n_tty_check_throttle()
254 if (N_TTY_BUF_SIZE - read_cnt(ldata) >= TTY_THRESHOLD_THROTTLE) in n_tty_check_throttle()
263 if (tty->driver->type == TTY_DRIVER_TYPE_PTY) { in n_tty_check_unthrottle()
267 tty_wakeup(tty->link); in n_tty_check_unthrottle()
272 * low-level driver know. We use chars_in_buffer() to in n_tty_check_unthrottle()
291 * put_tty_queue - add character to tty
299 * caller holds non-exclusive %termios_rwsem
303 *read_buf_addr(ldata, ldata->read_head) = c; in put_tty_queue()
304 ldata->read_head++; in put_tty_queue()
308 * reset_buffer_flags - reset buffer state
315 * * caller holds exclusive %termios_rwsem, or
320 ldata->read_head = ldata->canon_head = ldata->read_tail = 0; in reset_buffer_flags()
321 ldata->commit_head = 0; in reset_buffer_flags()
322 ldata->line_start = 0; in reset_buffer_flags()
324 ldata->erasing = 0; in reset_buffer_flags()
325 bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE); in reset_buffer_flags()
326 ldata->push = 0; in reset_buffer_flags()
328 ldata->lookahead_count = 0; in reset_buffer_flags()
335 if (tty->link->ctrl.packet) { in n_tty_packet_mode_flush()
336 spin_lock_irqsave(&tty->ctrl.lock, flags); in n_tty_packet_mode_flush()
337 tty->ctrl.pktstatus |= TIOCPKT_FLUSHREAD; in n_tty_packet_mode_flush()
338 spin_unlock_irqrestore(&tty->ctrl.lock, flags); in n_tty_packet_mode_flush()
339 wake_up_interruptible(&tty->link->read_wait); in n_tty_packet_mode_flush()
344 * n_tty_flush_buffer - clean input queue
354 * Locking: %ctrl.lock, exclusive %termios_rwsem
358 down_write(&tty->termios_rwsem); in n_tty_flush_buffer()
359 reset_buffer_flags(tty->disc_data); in n_tty_flush_buffer()
362 if (tty->link) in n_tty_flush_buffer()
364 up_write(&tty->termios_rwsem); in n_tty_flush_buffer()
368 * is_utf8_continuation - utf8 multibyte check
372 * character. We use this to correctly compute the on-screen size of the
381 * is_continuation - multibyte check
394 * do_output_char - output one character
407 * Returns: the number of bytes of buffer space used or -1 if no space left.
414 struct n_tty_data *ldata = tty->disc_data; in do_output_char()
418 return -1; in do_output_char()
423 ldata->column = 0; in do_output_char()
426 return -1; in do_output_char()
427 ldata->canon_column = ldata->column = 0; in do_output_char()
428 tty->ops->write(tty, "\r\n", 2); in do_output_char()
431 ldata->canon_column = ldata->column; in do_output_char()
434 if (O_ONOCR(tty) && ldata->column == 0) in do_output_char()
439 ldata->canon_column = ldata->column = 0; in do_output_char()
442 ldata->canon_column = ldata->column = 0; in do_output_char()
445 spaces = 8 - (ldata->column & 7); in do_output_char()
448 return -1; in do_output_char()
449 ldata->column += spaces; in do_output_char()
450 tty->ops->write(tty, " ", spaces); in do_output_char()
453 ldata->column += spaces; in do_output_char()
456 if (ldata->column > 0) in do_output_char()
457 ldata->column--; in do_output_char()
464 ldata->column++; in do_output_char()
474 * process_output - output post processor
480 * Returns: -1 when the output device is full and the character must be
488 struct n_tty_data *ldata = tty->disc_data; in process_output()
492 mutex_lock(&ldata->output_lock); in process_output()
497 mutex_unlock(&ldata->output_lock); in process_output()
499 return -1; in process_output()
505 * process_output_block - block post processor
525 struct n_tty_data *ldata = tty->disc_data; in process_output_block()
530 mutex_lock(&ldata->output_lock); in process_output_block()
534 mutex_unlock(&ldata->output_lock); in process_output_block()
546 ldata->column = 0; in process_output_block()
549 ldata->canon_column = ldata->column; in process_output_block()
552 if (O_ONOCR(tty) && ldata->column == 0) in process_output_block()
556 ldata->canon_column = ldata->column = 0; in process_output_block()
561 if (ldata->column > 0) in process_output_block()
562 ldata->column--; in process_output_block()
569 ldata->column++; in process_output_block()
575 i = tty->ops->write(tty, buf, i); in process_output_block()
577 mutex_unlock(&ldata->output_lock); in process_output_block()
584 struct n_tty_data *ldata = tty->disc_data; in n_tty_process_echo_ops()
589 * might see only portion of multi-byte operation. in n_tty_process_echo_ops()
591 if (MASK(ldata->echo_commit) == MASK(*tail + 1)) in n_tty_process_echo_ops()
592 return -ENODATA; in n_tty_process_echo_ops()
595 * If the buffer byte is the start of a multi-byte operation, get the in n_tty_process_echo_ops()
604 if (MASK(ldata->echo_commit) == MASK(*tail + 2)) in n_tty_process_echo_ops()
605 return -ENODATA; in n_tty_process_echo_ops()
617 num_chars += ldata->canon_column; in n_tty_process_echo_ops()
618 num_bs = 8 - (num_chars & 7); in n_tty_process_echo_ops()
621 return -ENOSPC; in n_tty_process_echo_ops()
623 space -= num_bs; in n_tty_process_echo_ops()
624 while (num_bs--) { in n_tty_process_echo_ops()
626 if (ldata->column > 0) in n_tty_process_echo_ops()
627 ldata->column--; in n_tty_process_echo_ops()
633 ldata->canon_column = ldata->column; in n_tty_process_echo_ops()
638 if (ldata->column > 0) in n_tty_process_echo_ops()
639 ldata->column--; in n_tty_process_echo_ops()
646 return -ENOSPC; in n_tty_process_echo_ops()
649 ldata->column++; in n_tty_process_echo_ops()
650 space--; in n_tty_process_echo_ops()
662 return -ENOSPC; in n_tty_process_echo_ops()
666 ldata->column += 2; in n_tty_process_echo_ops()
667 space -= 2; in n_tty_process_echo_ops()
676 * __process_echoes - write pending echo characters
679 * Write previously buffered echo (and other ldisc-generated) characters to the
699 struct n_tty_data *ldata = tty->disc_data; in __process_echoes()
706 tail = ldata->echo_tail; in __process_echoes()
707 while (MASK(ldata->echo_commit) != MASK(tail)) { in __process_echoes()
711 if (ret == -ENODATA) in __process_echoes()
721 space -= retval; in __process_echoes()
726 space -= 1; in __process_echoes()
735 while (ldata->echo_commit > tail && in __process_echoes()
736 ldata->echo_commit - tail >= ECHO_DISCARD_WATERMARK) { in __process_echoes()
747 ldata->echo_tail = tail; in __process_echoes()
748 return old_space - space; in __process_echoes()
753 struct n_tty_data *ldata = tty->disc_data; in commit_echoes()
757 mutex_lock(&ldata->output_lock); in commit_echoes()
758 head = ldata->echo_head; in commit_echoes()
759 ldata->echo_mark = head; in commit_echoes()
760 old = ldata->echo_commit - ldata->echo_tail; in commit_echoes()
765 nr = head - ldata->echo_tail; in commit_echoes()
768 mutex_unlock(&ldata->output_lock); in commit_echoes()
772 ldata->echo_commit = head; in commit_echoes()
774 mutex_unlock(&ldata->output_lock); in commit_echoes()
776 if (echoed && tty->ops->flush_chars) in commit_echoes()
777 tty->ops->flush_chars(tty); in commit_echoes()
782 struct n_tty_data *ldata = tty->disc_data; in process_echoes()
785 if (ldata->echo_mark == ldata->echo_tail) in process_echoes()
788 mutex_lock(&ldata->output_lock); in process_echoes()
789 ldata->echo_commit = ldata->echo_mark; in process_echoes()
791 mutex_unlock(&ldata->output_lock); in process_echoes()
793 if (echoed && tty->ops->flush_chars) in process_echoes()
794 tty->ops->flush_chars(tty); in process_echoes()
800 struct n_tty_data *ldata = tty->disc_data; in flush_echoes()
803 ldata->echo_commit == ldata->echo_head) in flush_echoes()
806 mutex_lock(&ldata->output_lock); in flush_echoes()
807 ldata->echo_commit = ldata->echo_head; in flush_echoes()
809 mutex_unlock(&ldata->output_lock); in flush_echoes()
813 * add_echo_byte - add a byte to the echo buffer
821 *echo_buf_addr(ldata, ldata->echo_head) = c; in add_echo_byte()
823 ldata->echo_head++; in add_echo_byte()
827 * echo_move_back_col - add operation to move back a column
839 * echo_set_canon_col - add operation to set the canon column
852 * echo_erase_tab - add operation to erase a tab
881 * echo_char_raw - echo a character raw
901 * echo_char - echo a character
913 struct n_tty_data *ldata = tty->disc_data; in echo_char()
926 * finish_erasing - complete erase
931 if (ldata->erasing) { in finish_erasing()
933 ldata->erasing = 0; in finish_erasing()
938 * eraser - handle erase function
943 * stream from the driver layer. Handles the complexities of UTF-8 multibyte
947 * caller holds non-exclusive %termios_rwsem
951 struct n_tty_data *ldata = tty->disc_data; in eraser()
957 if (ldata->read_head == ldata->canon_head) { in eraser()
967 ldata->read_head = ldata->canon_head; in eraser()
971 ldata->read_head = ldata->canon_head; in eraser()
983 while (MASK(ldata->read_head) != MASK(ldata->canon_head)) { in eraser()
984 head = ldata->read_head; in eraser()
988 head--; in eraser()
991 MASK(head) != MASK(ldata->canon_head)); in eraser()
1004 cnt = ldata->read_head - head; in eraser()
1005 ldata->read_head = head; in eraser()
1008 if (!ldata->erasing) { in eraser()
1010 ldata->erasing = 1; in eraser()
1012 /* if cnt > 1, output a multi-byte character */ in eraser()
1014 while (--cnt > 0) { in eraser()
1024 size_t tail = ldata->read_head; in eraser()
1033 while (MASK(tail) != MASK(ldata->canon_head)) { in eraser()
1034 tail--; in eraser()
1063 if (ldata->read_head == ldata->canon_head && L_ECHO(tty)) in eraser()
1078 * isig - handle the ISIG optio
1093 struct n_tty_data *ldata = tty->disc_data; in isig()
1100 up_read(&tty->termios_rwsem); in isig()
1101 down_write(&tty->termios_rwsem); in isig()
1106 mutex_lock(&ldata->output_lock); in isig()
1107 ldata->echo_head = ldata->echo_tail = 0; in isig()
1108 ldata->echo_mark = ldata->echo_commit = 0; in isig()
1109 mutex_unlock(&ldata->output_lock); in isig()
1115 reset_buffer_flags(tty->disc_data); in isig()
1118 if (tty->link) in isig()
1121 up_write(&tty->termios_rwsem); in isig()
1122 down_read(&tty->termios_rwsem); in isig()
1127 * n_tty_receive_break - handle break
1134 * caller holds non-exclusive termios_rwsem
1136 * Note: may get exclusive %termios_rwsem if flushing input buffer
1140 struct n_tty_data *ldata = tty->disc_data; in n_tty_receive_break()
1156 * n_tty_receive_overrun - handle overrun reporting
1167 struct n_tty_data *ldata = tty->disc_data; in n_tty_receive_overrun()
1169 ldata->num_overrun++; in n_tty_receive_overrun()
1170 if (time_is_before_jiffies(ldata->overrun_time + HZ)) { in n_tty_receive_overrun()
1171 tty_warn(tty, "%u input overrun(s)\n", ldata->num_overrun); in n_tty_receive_overrun()
1172 ldata->overrun_time = jiffies; in n_tty_receive_overrun()
1173 ldata->num_overrun = 0; in n_tty_receive_overrun()
1178 * n_tty_receive_parity_error - error notifier
1186 * caller holds non-exclusive %termios_rwsem
1191 struct n_tty_data *ldata = tty->disc_data; in n_tty_receive_parity_error()
1225 * n_tty_receive_char_flow_ctrl - receive flow control chars
1236 * Returns true if @c is consumed as flow-control character, the character
1261 struct n_tty_data *ldata = tty->disc_data; in n_tty_receive_handle_newline()
1263 set_bit(MASK(ldata->read_head), ldata->read_flags); in n_tty_receive_handle_newline()
1265 smp_store_release(&ldata->canon_head, ldata->read_head); in n_tty_receive_handle_newline()
1266 kill_fasync(&tty->fasync, SIGIO, POLL_IN); in n_tty_receive_handle_newline()
1267 wake_up_interruptible_poll(&tty->read_wait, EPOLLIN | EPOLLRDNORM); in n_tty_receive_handle_newline()
1272 struct n_tty_data *ldata = tty->disc_data; in n_tty_receive_char_canon()
1283 ldata->lnext = 1; in n_tty_receive_char_canon()
1297 size_t tail = ldata->canon_head; in n_tty_receive_char_canon()
1302 while (MASK(tail) != MASK(ldata->read_head)) { in n_tty_receive_char_canon()
1335 if (ldata->canon_head == ldata->read_head) in n_tty_receive_char_canon()
1358 struct n_tty_data *ldata = tty->disc_data; in n_tty_receive_char_special()
1376 if (tty->flow.stopped && !tty->flow.tco_stopped && I_IXON(tty) && I_IXANY(tty)) { in n_tty_receive_char_special()
1389 if (ldata->icanon && n_tty_receive_char_canon(tty, c)) in n_tty_receive_char_special()
1398 if (ldata->canon_head == ldata->read_head) in n_tty_receive_char_special()
1413 * n_tty_receive_char - perform processing
1421 * caller holds non-exclusive %termios_rwsem
1426 struct n_tty_data *ldata = tty->disc_data; in n_tty_receive_char()
1428 if (tty->flow.stopped && !tty->flow.tco_stopped && I_IXON(tty) && I_IXANY(tty)) { in n_tty_receive_char()
1435 if (ldata->canon_head == ldata->read_head) in n_tty_receive_char()
1456 tty->flow.stopped && !tty->flow.tco_stopped && I_IXANY(tty) && in n_tty_receive_char_closing()
1488 struct n_tty_data *ldata = tty->disc_data; in n_tty_receive_char_lnext()
1490 ldata->lnext = 0; in n_tty_receive_char_lnext()
1505 struct n_tty_data *ldata = tty->disc_data; in n_tty_lookahead_flow_ctrl()
1508 ldata->lookahead_count += count; in n_tty_lookahead_flow_ctrl()
1513 while (count--) { in n_tty_lookahead_flow_ctrl()
1526 struct n_tty_data *ldata = tty->disc_data; in n_tty_receive_buf_real_raw()
1528 /* handle buffer wrap-around by a loop */ in n_tty_receive_buf_real_raw()
1530 size_t head = MASK(ldata->read_head); in n_tty_receive_buf_real_raw()
1531 size_t n = min(count, N_TTY_BUF_SIZE - head); in n_tty_receive_buf_real_raw()
1535 ldata->read_head += n; in n_tty_receive_buf_real_raw()
1537 count -= n; in n_tty_receive_buf_real_raw()
1545 struct n_tty_data *ldata = tty->disc_data; in n_tty_receive_buf_raw()
1548 while (count--) { in n_tty_receive_buf_raw()
1564 while (count--) { in n_tty_receive_buf_closing()
1576 struct n_tty_data *ldata = tty->disc_data; in n_tty_receive_buf_standard()
1579 while (count--) { in n_tty_receive_buf_standard()
1585 if (ldata->lnext) { in n_tty_receive_buf_standard()
1604 if (test_bit(c, ldata->char_map)) in n_tty_receive_buf_standard()
1614 struct n_tty_data *ldata = tty->disc_data; in __receive_buf()
1616 size_t la_count = min(ldata->lookahead_count, count); in __receive_buf()
1618 if (ldata->real_raw) in __receive_buf()
1620 else if (ldata->raw || (L_EXTPROC(tty) && !preops)) in __receive_buf()
1622 else if (tty->closing && !L_EXTPROC(tty)) { in __receive_buf()
1628 count -= la_count; in __receive_buf()
1638 count -= la_count; in __receive_buf()
1644 if (tty->ops->flush_chars) in __receive_buf()
1645 tty->ops->flush_chars(tty); in __receive_buf()
1648 ldata->lookahead_count -= la_count; in __receive_buf()
1650 if (ldata->icanon && !L_EXTPROC(tty)) in __receive_buf()
1654 smp_store_release(&ldata->commit_head, ldata->read_head); in __receive_buf()
1657 kill_fasync(&tty->fasync, SIGIO, POLL_IN); in __receive_buf()
1658 wake_up_interruptible_poll(&tty->read_wait, EPOLLIN | EPOLLRDNORM); in __receive_buf()
1663 * n_tty_receive_buf_common - process input
1683 * In non-canonical mode, the read buffer will only accept 4095 chars; this
1688 * non-canonical mode: the read buffer could already contain the maximum canon
1689 * line of 4096 chars when the mode is switched to non-canonical.
1692 * claims non-exclusive %termios_rwsem
1699 struct n_tty_data *ldata = tty->disc_data; in n_tty_receive_buf_common()
1703 down_read(&tty->termios_rwsem); in n_tty_receive_buf_common()
1715 * paired with store in *_copy_from_read_buf() -- guarantees in n_tty_receive_buf_common()
1719 size_t tail = smp_load_acquire(&ldata->read_tail); in n_tty_receive_buf_common()
1721 room = N_TTY_BUF_SIZE - (ldata->read_head - tail); in n_tty_receive_buf_common()
1724 room--; in n_tty_receive_buf_common()
1726 overflow = ldata->icanon && ldata->canon_head == tail; in n_tty_receive_buf_common()
1728 ldata->read_head--; in n_tty_receive_buf_common()
1730 WRITE_ONCE(ldata->no_room, flow && !room); in n_tty_receive_buf_common()
1745 count -= n; in n_tty_receive_buf_common()
1747 } while (!test_bit(TTY_LDISC_CHANGING, &tty->flags)); in n_tty_receive_buf_common()
1749 tty->receive_room = room; in n_tty_receive_buf_common()
1752 if (tty->driver->type == TTY_DRIVER_TYPE_PTY) { in n_tty_receive_buf_common()
1761 if (unlikely(ldata->no_room)) { in n_tty_receive_buf_common()
1765 * before ldata->no_room is set. in n_tty_receive_buf_common()
1772 up_read(&tty->termios_rwsem); in n_tty_receive_buf_common()
1790 * n_tty_set_termios - termios data changed
1796 * re-entry by the tty layer. The user is guaranteed that this function will
1797 * not be re-entered or in progress when the ldisc is closed.
1799 * Locking: Caller holds @tty->termios_rwsem
1803 struct n_tty_data *ldata = tty->disc_data; in n_tty_set_termios()
1805 if (!old || (old->c_lflag ^ tty->termios.c_lflag) & (ICANON | EXTPROC)) { in n_tty_set_termios()
1806 bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE); in n_tty_set_termios()
1807 ldata->line_start = ldata->read_tail; in n_tty_set_termios()
1809 ldata->canon_head = ldata->read_tail; in n_tty_set_termios()
1810 ldata->push = 0; in n_tty_set_termios()
1812 set_bit(MASK(ldata->read_head - 1), ldata->read_flags); in n_tty_set_termios()
1813 ldata->canon_head = ldata->read_head; in n_tty_set_termios()
1814 ldata->push = 1; in n_tty_set_termios()
1816 ldata->commit_head = ldata->read_head; in n_tty_set_termios()
1817 ldata->erasing = 0; in n_tty_set_termios()
1818 ldata->lnext = 0; in n_tty_set_termios()
1821 ldata->icanon = (L_ICANON(tty) != 0); in n_tty_set_termios()
1827 bitmap_zero(ldata->char_map, 256); in n_tty_set_termios()
1830 set_bit('\r', ldata->char_map); in n_tty_set_termios()
1832 set_bit('\n', ldata->char_map); in n_tty_set_termios()
1835 set_bit(ERASE_CHAR(tty), ldata->char_map); in n_tty_set_termios()
1836 set_bit(KILL_CHAR(tty), ldata->char_map); in n_tty_set_termios()
1837 set_bit(EOF_CHAR(tty), ldata->char_map); in n_tty_set_termios()
1838 set_bit('\n', ldata->char_map); in n_tty_set_termios()
1839 set_bit(EOL_CHAR(tty), ldata->char_map); in n_tty_set_termios()
1841 set_bit(WERASE_CHAR(tty), ldata->char_map); in n_tty_set_termios()
1842 set_bit(LNEXT_CHAR(tty), ldata->char_map); in n_tty_set_termios()
1843 set_bit(EOL2_CHAR(tty), ldata->char_map); in n_tty_set_termios()
1846 ldata->char_map); in n_tty_set_termios()
1850 set_bit(START_CHAR(tty), ldata->char_map); in n_tty_set_termios()
1851 set_bit(STOP_CHAR(tty), ldata->char_map); in n_tty_set_termios()
1854 set_bit(INTR_CHAR(tty), ldata->char_map); in n_tty_set_termios()
1855 set_bit(QUIT_CHAR(tty), ldata->char_map); in n_tty_set_termios()
1856 set_bit(SUSP_CHAR(tty), ldata->char_map); in n_tty_set_termios()
1858 clear_bit(__DISABLED_CHAR, ldata->char_map); in n_tty_set_termios()
1859 ldata->raw = 0; in n_tty_set_termios()
1860 ldata->real_raw = 0; in n_tty_set_termios()
1862 ldata->raw = 1; in n_tty_set_termios()
1865 (tty->driver->flags & TTY_DRIVER_REAL_RAW)) in n_tty_set_termios()
1866 ldata->real_raw = 1; in n_tty_set_termios()
1868 ldata->real_raw = 0; in n_tty_set_termios()
1874 if (!I_IXON(tty) && old && (old->c_iflag & IXON) && !tty->flow.tco_stopped) { in n_tty_set_termios()
1880 wake_up_interruptible(&tty->write_wait); in n_tty_set_termios()
1881 wake_up_interruptible(&tty->read_wait); in n_tty_set_termios()
1885 * n_tty_close - close the ldisc for this tty
1894 struct n_tty_data *ldata = tty->disc_data; in n_tty_close()
1896 if (tty->link) in n_tty_close()
1899 down_write(&tty->termios_rwsem); in n_tty_close()
1901 tty->disc_data = NULL; in n_tty_close()
1902 up_write(&tty->termios_rwsem); in n_tty_close()
1906 * n_tty_open - open an ldisc
1920 return -ENOMEM; in n_tty_open()
1922 ldata->overrun_time = jiffies; in n_tty_open()
1923 mutex_init(&ldata->atomic_read_lock); in n_tty_open()
1924 mutex_init(&ldata->output_lock); in n_tty_open()
1926 tty->disc_data = ldata; in n_tty_open()
1927 tty->closing = 0; in n_tty_open()
1929 clear_bit(TTY_LDISC_HALTED, &tty->flags); in n_tty_open()
1937 const struct n_tty_data *ldata = tty->disc_data; in input_available_p()
1940 if (ldata->icanon && !L_EXTPROC(tty)) in input_available_p()
1941 return ldata->canon_head != ldata->read_tail; in input_available_p()
1943 return ldata->commit_head - ldata->read_tail >= amt; in input_available_p()
1947 * copy_from_read_buf - copy read data directly
1959 * * called under the @ldata->atomic_read_lock sem
1961 * caller holds non-exclusive %termios_rwsem;
1968 struct n_tty_data *ldata = tty->disc_data; in copy_from_read_buf()
1971 size_t head = smp_load_acquire(&ldata->commit_head); in copy_from_read_buf()
1972 size_t tail = MASK(ldata->read_tail); in copy_from_read_buf()
1974 n = min3(head - ldata->read_tail, N_TTY_BUF_SIZE - tail, *nr); in copy_from_read_buf()
1983 smp_store_release(&ldata->read_tail, ldata->read_tail + n); in copy_from_read_buf()
1985 /* Turn single EOF into zero-length read */ in copy_from_read_buf()
1986 if (L_EXTPROC(tty) && ldata->icanon && is_eof && in copy_from_read_buf()
1987 head == ldata->read_tail) in copy_from_read_buf()
1991 *nr -= n; in copy_from_read_buf()
1994 return head != ldata->read_tail; in copy_from_read_buf()
1998 * canon_copy_from_read_buf - copy read data in canonical mode
2004 * copies one line of input up to and including the line-delimiting character
2007 * Note: When termios is changed from non-canonical to canonical mode and the
2009 * C-d were input) _without_ the %DISABLED_CHAR in the buffer. This causes data
2016 * caller holds non-exclusive %termios_rwsem;
2022 struct n_tty_data *ldata = tty->disc_data; in canon_copy_from_read_buf()
2032 canon_head = smp_load_acquire(&ldata->canon_head); in canon_copy_from_read_buf()
2033 n = min(*nr, canon_head - ldata->read_tail); in canon_copy_from_read_buf()
2035 tail = MASK(ldata->read_tail); in canon_copy_from_read_buf()
2041 eol = find_next_bit(ldata->read_flags, size, tail); in canon_copy_from_read_buf()
2042 more = n - (size - tail); in canon_copy_from_read_buf()
2045 eol = find_first_bit(ldata->read_flags, more); in canon_copy_from_read_buf()
2050 n = eol - tail; in canon_copy_from_read_buf()
2063 *nr -= n; in canon_copy_from_read_buf()
2066 clear_bit(eol, ldata->read_flags); in canon_copy_from_read_buf()
2067 smp_store_release(&ldata->read_tail, ldata->read_tail + c); in canon_copy_from_read_buf()
2070 if (!ldata->push) in canon_copy_from_read_buf()
2071 ldata->line_start = ldata->read_tail; in canon_copy_from_read_buf()
2073 ldata->push = 0; in canon_copy_from_read_buf()
2078 /* No EOL found - do a continuation retry if there is more data */ in canon_copy_from_read_buf()
2079 return ldata->read_tail != canon_head; in canon_copy_from_read_buf()
2091 canon_head = smp_load_acquire(&ldata->canon_head); in canon_skip_eof()
2092 tail = ldata->read_tail; in canon_skip_eof()
2099 tail &= (N_TTY_BUF_SIZE - 1); in canon_skip_eof()
2100 if (!test_bit(tail, ldata->read_flags)) in canon_skip_eof()
2106 clear_bit(tail, ldata->read_flags); in canon_skip_eof()
2107 smp_store_release(&ldata->read_tail, ldata->read_tail + 1); in canon_skip_eof()
2111 * job_control - check job control
2121 * * current->signal->tty check is safe
2122 * * ctrl.lock to safely reference @tty->ctrl.pgrp
2126 /* Job control check -- must be done at start and after in job_control()
2129 check of the logic of this change. -- jlc */ in job_control()
2131 if (file->f_op->write_iter == redirected_tty_write) in job_control()
2139 * n_tty_read - read function for tty
2144 * @cookie: if non-%NULL, this is a continuation read
2155 * claims non-exclusive termios_rwsem;
2161 struct n_tty_data *ldata = tty->disc_data; in n_tty_read()
2177 if (ldata->icanon && !L_EXTPROC(tty)) { in n_tty_read()
2186 return kb - kbuf; in n_tty_read()
2189 return kb - kbuf; in n_tty_read()
2192 /* No more data - release locks and stop retries */ in n_tty_read()
2195 up_read(&tty->termios_rwsem); in n_tty_read()
2196 mutex_unlock(&ldata->atomic_read_lock); in n_tty_read()
2198 return kb - kbuf; in n_tty_read()
2208 if (file->f_flags & O_NONBLOCK) { in n_tty_read()
2209 if (!mutex_trylock(&ldata->atomic_read_lock)) in n_tty_read()
2210 return -EAGAIN; in n_tty_read()
2212 if (mutex_lock_interruptible(&ldata->atomic_read_lock)) in n_tty_read()
2213 return -ERESTARTSYS; in n_tty_read()
2216 down_read(&tty->termios_rwsem); in n_tty_read()
2220 if (!ldata->icanon) { in n_tty_read()
2230 packet = tty->ctrl.packet; in n_tty_read()
2231 old_tail = ldata->read_tail; in n_tty_read()
2233 add_wait_queue(&tty->read_wait, &wait); in n_tty_read()
2236 if (packet && tty->link->ctrl.pktstatus) { in n_tty_read()
2240 spin_lock_irq(&tty->link->ctrl.lock); in n_tty_read()
2241 cs = tty->link->ctrl.pktstatus; in n_tty_read()
2242 tty->link->ctrl.pktstatus = 0; in n_tty_read()
2243 spin_unlock_irq(&tty->link->ctrl.lock); in n_tty_read()
2245 nr--; in n_tty_read()
2250 up_read(&tty->termios_rwsem); in n_tty_read()
2251 tty_buffer_flush_work(tty->port); in n_tty_read()
2252 down_read(&tty->termios_rwsem); in n_tty_read()
2254 if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) { in n_tty_read()
2255 retval = -EIO; in n_tty_read()
2264 if (test_bit(TTY_HUPPING, &tty->flags)) in n_tty_read()
2269 retval = -EAGAIN; in n_tty_read()
2273 retval = -ERESTARTSYS; in n_tty_read()
2276 up_read(&tty->termios_rwsem); in n_tty_read()
2281 down_read(&tty->termios_rwsem); in n_tty_read()
2286 if (ldata->icanon && !L_EXTPROC(tty)) { in n_tty_read()
2293 nr--; in n_tty_read()
2305 if (copy_from_read_buf(tty, &kb, &nr) && kb - kbuf >= minimum) { in n_tty_read()
2307 remove_wait_queue(&tty->read_wait, &wait); in n_tty_read()
2309 return kb - kbuf; in n_tty_read()
2315 if (kb - kbuf >= minimum) in n_tty_read()
2320 if (old_tail != ldata->read_tail) { in n_tty_read()
2323 * before setting ldata->read_tail in copy_from_read_buf(). in n_tty_read()
2328 up_read(&tty->termios_rwsem); in n_tty_read()
2330 remove_wait_queue(&tty->read_wait, &wait); in n_tty_read()
2331 mutex_unlock(&ldata->atomic_read_lock); in n_tty_read()
2333 if (kb - kbuf) in n_tty_read()
2334 retval = kb - kbuf; in n_tty_read()
2340 * n_tty_write - write function for tty
2366 /* Job control check -- must be done at start (POSIX.1 7.1.1.4). */ in n_tty_write()
2367 if (L_TOSTOP(tty) && file->f_op->write_iter != redirected_tty_write) { in n_tty_write()
2373 down_read(&tty->termios_rwsem); in n_tty_write()
2378 add_wait_queue(&tty->write_wait, &wait); in n_tty_write()
2381 retval = -ERESTARTSYS; in n_tty_write()
2384 if (tty_hung_up_p(file) || (tty->link && !tty->link->count)) { in n_tty_write()
2385 retval = -EIO; in n_tty_write()
2392 if (num == -EAGAIN) in n_tty_write()
2398 nr -= num; in n_tty_write()
2403 b++; nr--; in n_tty_write()
2405 if (tty->ops->flush_chars) in n_tty_write()
2406 tty->ops->flush_chars(tty); in n_tty_write()
2408 struct n_tty_data *ldata = tty->disc_data; in n_tty_write()
2411 mutex_lock(&ldata->output_lock); in n_tty_write()
2412 num = tty->ops->write(tty, b, nr); in n_tty_write()
2413 mutex_unlock(&ldata->output_lock); in n_tty_write()
2421 nr -= num; in n_tty_write()
2427 retval = -EAGAIN; in n_tty_write()
2430 up_read(&tty->termios_rwsem); in n_tty_write()
2434 down_read(&tty->termios_rwsem); in n_tty_write()
2437 remove_wait_queue(&tty->write_wait, &wait); in n_tty_write()
2438 if (nr && tty->fasync) in n_tty_write()
2439 set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); in n_tty_write()
2440 up_read(&tty->termios_rwsem); in n_tty_write()
2441 return (b - buf) ? b - buf : retval; in n_tty_write()
2445 * n_tty_poll - poll method for N_TTY
2456 * Locking: called without the kernel lock held -- fine.
2463 poll_wait(file, &tty->read_wait, wait); in n_tty_poll()
2464 poll_wait(file, &tty->write_wait, wait); in n_tty_poll()
2468 tty_buffer_flush_work(tty->port); in n_tty_poll()
2472 if (tty->ctrl.packet && tty->link->ctrl.pktstatus) in n_tty_poll()
2474 if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) in n_tty_poll()
2478 if (tty->ops->write && !tty_is_writelocked(tty) && in n_tty_poll()
2489 if (ldata->canon_head == ldata->read_tail) in inq_canon()
2491 head = ldata->canon_head; in inq_canon()
2492 tail = ldata->read_tail; in inq_canon()
2493 nr = head - tail; in inq_canon()
2494 /* Skip EOF-chars.. */ in inq_canon()
2496 if (test_bit(MASK(tail), ldata->read_flags) && in inq_canon()
2498 nr--; in inq_canon()
2507 struct n_tty_data *ldata = tty->disc_data; in n_tty_ioctl()
2514 down_write(&tty->termios_rwsem); in n_tty_ioctl()
2519 up_write(&tty->termios_rwsem); in n_tty_ioctl()
2545 * n_tty_inherit_ops - inherit N_TTY methods
2554 ops->owner = NULL; in n_tty_inherit_ops()