1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-1.0+
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * n_tty.c --- implements the N_TTY line discipline.
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * This code used to be in tty_io.c, but things are getting hairy
6*4882a593Smuzhiyun * enough that it made sense to split things off. (The N_TTY
7*4882a593Smuzhiyun * processing has changed so much that it's hardly recognizable,
8*4882a593Smuzhiyun * anyway...)
9*4882a593Smuzhiyun *
10*4882a593Smuzhiyun * Note that the open routine for N_TTY is guaranteed never to return
11*4882a593Smuzhiyun * an error. This is because Linux will fall back to setting a line
12*4882a593Smuzhiyun * to N_TTY if it can not switch to any other line discipline.
13*4882a593Smuzhiyun *
14*4882a593Smuzhiyun * Written by Theodore Ts'o, Copyright 1994.
15*4882a593Smuzhiyun *
16*4882a593Smuzhiyun * This file also contains code originally written by Linus Torvalds,
17*4882a593Smuzhiyun * Copyright 1991, 1992, 1993, and by Julian Cowley, Copyright 1994.
18*4882a593Smuzhiyun *
19*4882a593Smuzhiyun * Reduced memory usage for older ARM systems - Russell King.
20*4882a593Smuzhiyun *
21*4882a593Smuzhiyun * 2000/01/20 Fixed SMP locking on put_tty_queue using bits of
22*4882a593Smuzhiyun * the patch by Andrew J. Kroll <ag784@freenet.buffalo.edu>
23*4882a593Smuzhiyun * who actually finally proved there really was a race.
24*4882a593Smuzhiyun *
25*4882a593Smuzhiyun * 2002/03/18 Implemented n_tty_wakeup to send SIGIO POLL_OUTs to
26*4882a593Smuzhiyun * waiting writing processes-Sapan Bhatia <sapan@corewars.org>.
27*4882a593Smuzhiyun * Also fixed a bug in BLOCKING mode where n_tty_write returns
28*4882a593Smuzhiyun * EAGAIN
29*4882a593Smuzhiyun */
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun #include <linux/types.h>
32*4882a593Smuzhiyun #include <linux/major.h>
33*4882a593Smuzhiyun #include <linux/errno.h>
34*4882a593Smuzhiyun #include <linux/signal.h>
35*4882a593Smuzhiyun #include <linux/fcntl.h>
36*4882a593Smuzhiyun #include <linux/sched.h>
37*4882a593Smuzhiyun #include <linux/interrupt.h>
38*4882a593Smuzhiyun #include <linux/tty.h>
39*4882a593Smuzhiyun #include <linux/timer.h>
40*4882a593Smuzhiyun #include <linux/ctype.h>
41*4882a593Smuzhiyun #include <linux/mm.h>
42*4882a593Smuzhiyun #include <linux/string.h>
43*4882a593Smuzhiyun #include <linux/slab.h>
44*4882a593Smuzhiyun #include <linux/poll.h>
45*4882a593Smuzhiyun #include <linux/bitops.h>
46*4882a593Smuzhiyun #include <linux/audit.h>
47*4882a593Smuzhiyun #include <linux/file.h>
48*4882a593Smuzhiyun #include <linux/uaccess.h>
49*4882a593Smuzhiyun #include <linux/module.h>
50*4882a593Smuzhiyun #include <linux/ratelimit.h>
51*4882a593Smuzhiyun #include <linux/vmalloc.h>
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun /*
54*4882a593Smuzhiyun * Until this number of characters is queued in the xmit buffer, select will
55*4882a593Smuzhiyun * return "we have room for writes".
56*4882a593Smuzhiyun */
57*4882a593Smuzhiyun #define WAKEUP_CHARS 256
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun /*
60*4882a593Smuzhiyun * This defines the low- and high-watermarks for throttling and
61*4882a593Smuzhiyun * unthrottling the TTY driver. These watermarks are used for
62*4882a593Smuzhiyun * controlling the space in the read buffer.
63*4882a593Smuzhiyun */
64*4882a593Smuzhiyun #define TTY_THRESHOLD_THROTTLE 128 /* now based on remaining room */
65*4882a593Smuzhiyun #define TTY_THRESHOLD_UNTHROTTLE 128
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun /*
68*4882a593Smuzhiyun * Special byte codes used in the echo buffer to represent operations
69*4882a593Smuzhiyun * or special handling of characters. Bytes in the echo buffer that
70*4882a593Smuzhiyun * are not part of such special blocks are treated as normal character
71*4882a593Smuzhiyun * codes.
72*4882a593Smuzhiyun */
73*4882a593Smuzhiyun #define ECHO_OP_START 0xff
74*4882a593Smuzhiyun #define ECHO_OP_MOVE_BACK_COL 0x80
75*4882a593Smuzhiyun #define ECHO_OP_SET_CANON_COL 0x81
76*4882a593Smuzhiyun #define ECHO_OP_ERASE_TAB 0x82
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun #define ECHO_COMMIT_WATERMARK 256
79*4882a593Smuzhiyun #define ECHO_BLOCK 256
80*4882a593Smuzhiyun #define ECHO_DISCARD_WATERMARK N_TTY_BUF_SIZE - (ECHO_BLOCK + 32)
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun #undef N_TTY_TRACE
84*4882a593Smuzhiyun #ifdef N_TTY_TRACE
85*4882a593Smuzhiyun # define n_tty_trace(f, args...) trace_printk(f, ##args)
86*4882a593Smuzhiyun #else
87*4882a593Smuzhiyun # define n_tty_trace(f, args...) no_printk(f, ##args)
88*4882a593Smuzhiyun #endif
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun struct n_tty_data {
91*4882a593Smuzhiyun /* producer-published */
92*4882a593Smuzhiyun size_t read_head;
93*4882a593Smuzhiyun size_t commit_head;
94*4882a593Smuzhiyun size_t canon_head;
95*4882a593Smuzhiyun size_t echo_head;
96*4882a593Smuzhiyun size_t echo_commit;
97*4882a593Smuzhiyun size_t echo_mark;
98*4882a593Smuzhiyun DECLARE_BITMAP(char_map, 256);
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun /* private to n_tty_receive_overrun (single-threaded) */
101*4882a593Smuzhiyun unsigned long overrun_time;
102*4882a593Smuzhiyun int num_overrun;
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun /* non-atomic */
105*4882a593Smuzhiyun bool no_room;
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun /* must hold exclusive termios_rwsem to reset these */
108*4882a593Smuzhiyun unsigned char lnext:1, erasing:1, raw:1, real_raw:1, icanon:1;
109*4882a593Smuzhiyun unsigned char push:1;
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun /* shared by producer and consumer */
112*4882a593Smuzhiyun char read_buf[N_TTY_BUF_SIZE];
113*4882a593Smuzhiyun DECLARE_BITMAP(read_flags, N_TTY_BUF_SIZE);
114*4882a593Smuzhiyun unsigned char echo_buf[N_TTY_BUF_SIZE];
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun /* consumer-published */
117*4882a593Smuzhiyun size_t read_tail;
118*4882a593Smuzhiyun size_t line_start;
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun /* protected by output lock */
121*4882a593Smuzhiyun unsigned int column;
122*4882a593Smuzhiyun unsigned int canon_column;
123*4882a593Smuzhiyun size_t echo_tail;
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun struct mutex atomic_read_lock;
126*4882a593Smuzhiyun struct mutex output_lock;
127*4882a593Smuzhiyun };
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun #define MASK(x) ((x) & (N_TTY_BUF_SIZE - 1))
130*4882a593Smuzhiyun
read_cnt(struct n_tty_data * ldata)131*4882a593Smuzhiyun static inline size_t read_cnt(struct n_tty_data *ldata)
132*4882a593Smuzhiyun {
133*4882a593Smuzhiyun return ldata->read_head - ldata->read_tail;
134*4882a593Smuzhiyun }
135*4882a593Smuzhiyun
read_buf(struct n_tty_data * ldata,size_t i)136*4882a593Smuzhiyun static inline unsigned char read_buf(struct n_tty_data *ldata, size_t i)
137*4882a593Smuzhiyun {
138*4882a593Smuzhiyun return ldata->read_buf[i & (N_TTY_BUF_SIZE - 1)];
139*4882a593Smuzhiyun }
140*4882a593Smuzhiyun
read_buf_addr(struct n_tty_data * ldata,size_t i)141*4882a593Smuzhiyun static inline unsigned char *read_buf_addr(struct n_tty_data *ldata, size_t i)
142*4882a593Smuzhiyun {
143*4882a593Smuzhiyun return &ldata->read_buf[i & (N_TTY_BUF_SIZE - 1)];
144*4882a593Smuzhiyun }
145*4882a593Smuzhiyun
echo_buf(struct n_tty_data * ldata,size_t i)146*4882a593Smuzhiyun static inline unsigned char echo_buf(struct n_tty_data *ldata, size_t i)
147*4882a593Smuzhiyun {
148*4882a593Smuzhiyun smp_rmb(); /* Matches smp_wmb() in add_echo_byte(). */
149*4882a593Smuzhiyun return ldata->echo_buf[i & (N_TTY_BUF_SIZE - 1)];
150*4882a593Smuzhiyun }
151*4882a593Smuzhiyun
echo_buf_addr(struct n_tty_data * ldata,size_t i)152*4882a593Smuzhiyun static inline unsigned char *echo_buf_addr(struct n_tty_data *ldata, size_t i)
153*4882a593Smuzhiyun {
154*4882a593Smuzhiyun return &ldata->echo_buf[i & (N_TTY_BUF_SIZE - 1)];
155*4882a593Smuzhiyun }
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun /* If we are not echoing the data, perhaps this is a secret so erase it */
zero_buffer(struct tty_struct * tty,u8 * buffer,int size)158*4882a593Smuzhiyun static void zero_buffer(struct tty_struct *tty, u8 *buffer, int size)
159*4882a593Smuzhiyun {
160*4882a593Smuzhiyun bool icanon = !!L_ICANON(tty);
161*4882a593Smuzhiyun bool no_echo = !L_ECHO(tty);
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun if (icanon && no_echo)
164*4882a593Smuzhiyun memset(buffer, 0x00, size);
165*4882a593Smuzhiyun }
166*4882a593Smuzhiyun
tty_copy(struct tty_struct * tty,void * to,size_t tail,size_t n)167*4882a593Smuzhiyun static void tty_copy(struct tty_struct *tty, void *to, size_t tail, size_t n)
168*4882a593Smuzhiyun {
169*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
170*4882a593Smuzhiyun size_t size = N_TTY_BUF_SIZE - tail;
171*4882a593Smuzhiyun void *from = read_buf_addr(ldata, tail);
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun if (n > size) {
174*4882a593Smuzhiyun tty_audit_add_data(tty, from, size);
175*4882a593Smuzhiyun memcpy(to, from, size);
176*4882a593Smuzhiyun zero_buffer(tty, from, size);
177*4882a593Smuzhiyun to += size;
178*4882a593Smuzhiyun n -= size;
179*4882a593Smuzhiyun from = ldata->read_buf;
180*4882a593Smuzhiyun }
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun tty_audit_add_data(tty, from, n);
183*4882a593Smuzhiyun memcpy(to, from, n);
184*4882a593Smuzhiyun zero_buffer(tty, from, n);
185*4882a593Smuzhiyun }
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun /**
188*4882a593Smuzhiyun * n_tty_kick_worker - start input worker (if required)
189*4882a593Smuzhiyun * @tty: terminal
190*4882a593Smuzhiyun *
191*4882a593Smuzhiyun * Re-schedules the flip buffer work if it may have stopped
192*4882a593Smuzhiyun *
193*4882a593Smuzhiyun * Caller holds exclusive termios_rwsem
194*4882a593Smuzhiyun * or
195*4882a593Smuzhiyun * n_tty_read()/consumer path:
196*4882a593Smuzhiyun * holds non-exclusive termios_rwsem
197*4882a593Smuzhiyun */
198*4882a593Smuzhiyun
n_tty_kick_worker(struct tty_struct * tty)199*4882a593Smuzhiyun static void n_tty_kick_worker(struct tty_struct *tty)
200*4882a593Smuzhiyun {
201*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
202*4882a593Smuzhiyun
203*4882a593Smuzhiyun /* Did the input worker stop? Restart it */
204*4882a593Smuzhiyun if (unlikely(ldata->no_room)) {
205*4882a593Smuzhiyun ldata->no_room = 0;
206*4882a593Smuzhiyun
207*4882a593Smuzhiyun WARN_RATELIMIT(tty->port->itty == NULL,
208*4882a593Smuzhiyun "scheduling with invalid itty\n");
209*4882a593Smuzhiyun /* see if ldisc has been killed - if so, this means that
210*4882a593Smuzhiyun * even though the ldisc has been halted and ->buf.work
211*4882a593Smuzhiyun * cancelled, ->buf.work is about to be rescheduled
212*4882a593Smuzhiyun */
213*4882a593Smuzhiyun WARN_RATELIMIT(test_bit(TTY_LDISC_HALTED, &tty->flags),
214*4882a593Smuzhiyun "scheduling buffer work for halted ldisc\n");
215*4882a593Smuzhiyun tty_buffer_restart_work(tty->port);
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun }
218*4882a593Smuzhiyun
chars_in_buffer(struct tty_struct * tty)219*4882a593Smuzhiyun static ssize_t chars_in_buffer(struct tty_struct *tty)
220*4882a593Smuzhiyun {
221*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
222*4882a593Smuzhiyun ssize_t n = 0;
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun if (!ldata->icanon)
225*4882a593Smuzhiyun n = ldata->commit_head - ldata->read_tail;
226*4882a593Smuzhiyun else
227*4882a593Smuzhiyun n = ldata->canon_head - ldata->read_tail;
228*4882a593Smuzhiyun return n;
229*4882a593Smuzhiyun }
230*4882a593Smuzhiyun
231*4882a593Smuzhiyun /**
232*4882a593Smuzhiyun * n_tty_write_wakeup - asynchronous I/O notifier
233*4882a593Smuzhiyun * @tty: tty device
234*4882a593Smuzhiyun *
235*4882a593Smuzhiyun * Required for the ptys, serial driver etc. since processes
236*4882a593Smuzhiyun * that attach themselves to the master and rely on ASYNC
237*4882a593Smuzhiyun * IO must be woken up
238*4882a593Smuzhiyun */
239*4882a593Smuzhiyun
n_tty_write_wakeup(struct tty_struct * tty)240*4882a593Smuzhiyun static void n_tty_write_wakeup(struct tty_struct *tty)
241*4882a593Smuzhiyun {
242*4882a593Smuzhiyun clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
243*4882a593Smuzhiyun kill_fasync(&tty->fasync, SIGIO, POLL_OUT);
244*4882a593Smuzhiyun }
245*4882a593Smuzhiyun
n_tty_check_throttle(struct tty_struct * tty)246*4882a593Smuzhiyun static void n_tty_check_throttle(struct tty_struct *tty)
247*4882a593Smuzhiyun {
248*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun /*
251*4882a593Smuzhiyun * Check the remaining room for the input canonicalization
252*4882a593Smuzhiyun * mode. We don't want to throttle the driver if we're in
253*4882a593Smuzhiyun * canonical mode and don't have a newline yet!
254*4882a593Smuzhiyun */
255*4882a593Smuzhiyun if (ldata->icanon && ldata->canon_head == ldata->read_tail)
256*4882a593Smuzhiyun return;
257*4882a593Smuzhiyun
258*4882a593Smuzhiyun while (1) {
259*4882a593Smuzhiyun int throttled;
260*4882a593Smuzhiyun tty_set_flow_change(tty, TTY_THROTTLE_SAFE);
261*4882a593Smuzhiyun if (N_TTY_BUF_SIZE - read_cnt(ldata) >= TTY_THRESHOLD_THROTTLE)
262*4882a593Smuzhiyun break;
263*4882a593Smuzhiyun throttled = tty_throttle_safe(tty);
264*4882a593Smuzhiyun if (!throttled)
265*4882a593Smuzhiyun break;
266*4882a593Smuzhiyun }
267*4882a593Smuzhiyun __tty_set_flow_change(tty, 0);
268*4882a593Smuzhiyun }
269*4882a593Smuzhiyun
n_tty_check_unthrottle(struct tty_struct * tty)270*4882a593Smuzhiyun static void n_tty_check_unthrottle(struct tty_struct *tty)
271*4882a593Smuzhiyun {
272*4882a593Smuzhiyun if (tty->driver->type == TTY_DRIVER_TYPE_PTY) {
273*4882a593Smuzhiyun if (chars_in_buffer(tty) > TTY_THRESHOLD_UNTHROTTLE)
274*4882a593Smuzhiyun return;
275*4882a593Smuzhiyun n_tty_kick_worker(tty);
276*4882a593Smuzhiyun tty_wakeup(tty->link);
277*4882a593Smuzhiyun return;
278*4882a593Smuzhiyun }
279*4882a593Smuzhiyun
280*4882a593Smuzhiyun /* If there is enough space in the read buffer now, let the
281*4882a593Smuzhiyun * low-level driver know. We use chars_in_buffer() to
282*4882a593Smuzhiyun * check the buffer, as it now knows about canonical mode.
283*4882a593Smuzhiyun * Otherwise, if the driver is throttled and the line is
284*4882a593Smuzhiyun * longer than TTY_THRESHOLD_UNTHROTTLE in canonical mode,
285*4882a593Smuzhiyun * we won't get any more characters.
286*4882a593Smuzhiyun */
287*4882a593Smuzhiyun
288*4882a593Smuzhiyun while (1) {
289*4882a593Smuzhiyun int unthrottled;
290*4882a593Smuzhiyun tty_set_flow_change(tty, TTY_UNTHROTTLE_SAFE);
291*4882a593Smuzhiyun if (chars_in_buffer(tty) > TTY_THRESHOLD_UNTHROTTLE)
292*4882a593Smuzhiyun break;
293*4882a593Smuzhiyun n_tty_kick_worker(tty);
294*4882a593Smuzhiyun unthrottled = tty_unthrottle_safe(tty);
295*4882a593Smuzhiyun if (!unthrottled)
296*4882a593Smuzhiyun break;
297*4882a593Smuzhiyun }
298*4882a593Smuzhiyun __tty_set_flow_change(tty, 0);
299*4882a593Smuzhiyun }
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun /**
302*4882a593Smuzhiyun * put_tty_queue - add character to tty
303*4882a593Smuzhiyun * @c: character
304*4882a593Smuzhiyun * @ldata: n_tty data
305*4882a593Smuzhiyun *
306*4882a593Smuzhiyun * Add a character to the tty read_buf queue.
307*4882a593Smuzhiyun *
308*4882a593Smuzhiyun * n_tty_receive_buf()/producer path:
309*4882a593Smuzhiyun * caller holds non-exclusive termios_rwsem
310*4882a593Smuzhiyun */
311*4882a593Smuzhiyun
put_tty_queue(unsigned char c,struct n_tty_data * ldata)312*4882a593Smuzhiyun static inline void put_tty_queue(unsigned char c, struct n_tty_data *ldata)
313*4882a593Smuzhiyun {
314*4882a593Smuzhiyun *read_buf_addr(ldata, ldata->read_head) = c;
315*4882a593Smuzhiyun ldata->read_head++;
316*4882a593Smuzhiyun }
317*4882a593Smuzhiyun
318*4882a593Smuzhiyun /**
319*4882a593Smuzhiyun * reset_buffer_flags - reset buffer state
320*4882a593Smuzhiyun * @ldata: line disc data to reset
321*4882a593Smuzhiyun *
322*4882a593Smuzhiyun * Reset the read buffer counters and clear the flags.
323*4882a593Smuzhiyun * Called from n_tty_open() and n_tty_flush_buffer().
324*4882a593Smuzhiyun *
325*4882a593Smuzhiyun * Locking: caller holds exclusive termios_rwsem
326*4882a593Smuzhiyun * (or locking is not required)
327*4882a593Smuzhiyun */
328*4882a593Smuzhiyun
reset_buffer_flags(struct n_tty_data * ldata)329*4882a593Smuzhiyun static void reset_buffer_flags(struct n_tty_data *ldata)
330*4882a593Smuzhiyun {
331*4882a593Smuzhiyun ldata->read_head = ldata->canon_head = ldata->read_tail = 0;
332*4882a593Smuzhiyun ldata->commit_head = 0;
333*4882a593Smuzhiyun ldata->line_start = 0;
334*4882a593Smuzhiyun
335*4882a593Smuzhiyun ldata->erasing = 0;
336*4882a593Smuzhiyun bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE);
337*4882a593Smuzhiyun ldata->push = 0;
338*4882a593Smuzhiyun }
339*4882a593Smuzhiyun
n_tty_packet_mode_flush(struct tty_struct * tty)340*4882a593Smuzhiyun static void n_tty_packet_mode_flush(struct tty_struct *tty)
341*4882a593Smuzhiyun {
342*4882a593Smuzhiyun unsigned long flags;
343*4882a593Smuzhiyun
344*4882a593Smuzhiyun if (tty->link->packet) {
345*4882a593Smuzhiyun spin_lock_irqsave(&tty->ctrl_lock, flags);
346*4882a593Smuzhiyun tty->ctrl_status |= TIOCPKT_FLUSHREAD;
347*4882a593Smuzhiyun spin_unlock_irqrestore(&tty->ctrl_lock, flags);
348*4882a593Smuzhiyun wake_up_interruptible(&tty->link->read_wait);
349*4882a593Smuzhiyun }
350*4882a593Smuzhiyun }
351*4882a593Smuzhiyun
352*4882a593Smuzhiyun /**
353*4882a593Smuzhiyun * n_tty_flush_buffer - clean input queue
354*4882a593Smuzhiyun * @tty: terminal device
355*4882a593Smuzhiyun *
356*4882a593Smuzhiyun * Flush the input buffer. Called when the tty layer wants the
357*4882a593Smuzhiyun * buffer flushed (eg at hangup) or when the N_TTY line discipline
358*4882a593Smuzhiyun * internally has to clean the pending queue (for example some signals).
359*4882a593Smuzhiyun *
360*4882a593Smuzhiyun * Holds termios_rwsem to exclude producer/consumer while
361*4882a593Smuzhiyun * buffer indices are reset.
362*4882a593Smuzhiyun *
363*4882a593Smuzhiyun * Locking: ctrl_lock, exclusive termios_rwsem
364*4882a593Smuzhiyun */
365*4882a593Smuzhiyun
n_tty_flush_buffer(struct tty_struct * tty)366*4882a593Smuzhiyun static void n_tty_flush_buffer(struct tty_struct *tty)
367*4882a593Smuzhiyun {
368*4882a593Smuzhiyun down_write(&tty->termios_rwsem);
369*4882a593Smuzhiyun reset_buffer_flags(tty->disc_data);
370*4882a593Smuzhiyun n_tty_kick_worker(tty);
371*4882a593Smuzhiyun
372*4882a593Smuzhiyun if (tty->link)
373*4882a593Smuzhiyun n_tty_packet_mode_flush(tty);
374*4882a593Smuzhiyun up_write(&tty->termios_rwsem);
375*4882a593Smuzhiyun }
376*4882a593Smuzhiyun
377*4882a593Smuzhiyun /**
378*4882a593Smuzhiyun * is_utf8_continuation - utf8 multibyte check
379*4882a593Smuzhiyun * @c: byte to check
380*4882a593Smuzhiyun *
381*4882a593Smuzhiyun * Returns true if the utf8 character 'c' is a multibyte continuation
382*4882a593Smuzhiyun * character. We use this to correctly compute the on screen size
383*4882a593Smuzhiyun * of the character when printing
384*4882a593Smuzhiyun */
385*4882a593Smuzhiyun
is_utf8_continuation(unsigned char c)386*4882a593Smuzhiyun static inline int is_utf8_continuation(unsigned char c)
387*4882a593Smuzhiyun {
388*4882a593Smuzhiyun return (c & 0xc0) == 0x80;
389*4882a593Smuzhiyun }
390*4882a593Smuzhiyun
391*4882a593Smuzhiyun /**
392*4882a593Smuzhiyun * is_continuation - multibyte check
393*4882a593Smuzhiyun * @c: byte to check
394*4882a593Smuzhiyun *
395*4882a593Smuzhiyun * Returns true if the utf8 character 'c' is a multibyte continuation
396*4882a593Smuzhiyun * character and the terminal is in unicode mode.
397*4882a593Smuzhiyun */
398*4882a593Smuzhiyun
is_continuation(unsigned char c,struct tty_struct * tty)399*4882a593Smuzhiyun static inline int is_continuation(unsigned char c, struct tty_struct *tty)
400*4882a593Smuzhiyun {
401*4882a593Smuzhiyun return I_IUTF8(tty) && is_utf8_continuation(c);
402*4882a593Smuzhiyun }
403*4882a593Smuzhiyun
404*4882a593Smuzhiyun /**
405*4882a593Smuzhiyun * do_output_char - output one character
406*4882a593Smuzhiyun * @c: character (or partial unicode symbol)
407*4882a593Smuzhiyun * @tty: terminal device
408*4882a593Smuzhiyun * @space: space available in tty driver write buffer
409*4882a593Smuzhiyun *
410*4882a593Smuzhiyun * This is a helper function that handles one output character
411*4882a593Smuzhiyun * (including special characters like TAB, CR, LF, etc.),
412*4882a593Smuzhiyun * doing OPOST processing and putting the results in the
413*4882a593Smuzhiyun * tty driver's write buffer.
414*4882a593Smuzhiyun *
415*4882a593Smuzhiyun * Note that Linux currently ignores TABDLY, CRDLY, VTDLY, FFDLY
416*4882a593Smuzhiyun * and NLDLY. They simply aren't relevant in the world today.
417*4882a593Smuzhiyun * If you ever need them, add them here.
418*4882a593Smuzhiyun *
419*4882a593Smuzhiyun * Returns the number of bytes of buffer space used or -1 if
420*4882a593Smuzhiyun * no space left.
421*4882a593Smuzhiyun *
422*4882a593Smuzhiyun * Locking: should be called under the output_lock to protect
423*4882a593Smuzhiyun * the column state and space left in the buffer
424*4882a593Smuzhiyun */
425*4882a593Smuzhiyun
do_output_char(unsigned char c,struct tty_struct * tty,int space)426*4882a593Smuzhiyun static int do_output_char(unsigned char c, struct tty_struct *tty, int space)
427*4882a593Smuzhiyun {
428*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
429*4882a593Smuzhiyun int spaces;
430*4882a593Smuzhiyun
431*4882a593Smuzhiyun if (!space)
432*4882a593Smuzhiyun return -1;
433*4882a593Smuzhiyun
434*4882a593Smuzhiyun switch (c) {
435*4882a593Smuzhiyun case '\n':
436*4882a593Smuzhiyun if (O_ONLRET(tty))
437*4882a593Smuzhiyun ldata->column = 0;
438*4882a593Smuzhiyun if (O_ONLCR(tty)) {
439*4882a593Smuzhiyun if (space < 2)
440*4882a593Smuzhiyun return -1;
441*4882a593Smuzhiyun ldata->canon_column = ldata->column = 0;
442*4882a593Smuzhiyun tty->ops->write(tty, "\r\n", 2);
443*4882a593Smuzhiyun return 2;
444*4882a593Smuzhiyun }
445*4882a593Smuzhiyun ldata->canon_column = ldata->column;
446*4882a593Smuzhiyun break;
447*4882a593Smuzhiyun case '\r':
448*4882a593Smuzhiyun if (O_ONOCR(tty) && ldata->column == 0)
449*4882a593Smuzhiyun return 0;
450*4882a593Smuzhiyun if (O_OCRNL(tty)) {
451*4882a593Smuzhiyun c = '\n';
452*4882a593Smuzhiyun if (O_ONLRET(tty))
453*4882a593Smuzhiyun ldata->canon_column = ldata->column = 0;
454*4882a593Smuzhiyun break;
455*4882a593Smuzhiyun }
456*4882a593Smuzhiyun ldata->canon_column = ldata->column = 0;
457*4882a593Smuzhiyun break;
458*4882a593Smuzhiyun case '\t':
459*4882a593Smuzhiyun spaces = 8 - (ldata->column & 7);
460*4882a593Smuzhiyun if (O_TABDLY(tty) == XTABS) {
461*4882a593Smuzhiyun if (space < spaces)
462*4882a593Smuzhiyun return -1;
463*4882a593Smuzhiyun ldata->column += spaces;
464*4882a593Smuzhiyun tty->ops->write(tty, " ", spaces);
465*4882a593Smuzhiyun return spaces;
466*4882a593Smuzhiyun }
467*4882a593Smuzhiyun ldata->column += spaces;
468*4882a593Smuzhiyun break;
469*4882a593Smuzhiyun case '\b':
470*4882a593Smuzhiyun if (ldata->column > 0)
471*4882a593Smuzhiyun ldata->column--;
472*4882a593Smuzhiyun break;
473*4882a593Smuzhiyun default:
474*4882a593Smuzhiyun if (!iscntrl(c)) {
475*4882a593Smuzhiyun if (O_OLCUC(tty))
476*4882a593Smuzhiyun c = toupper(c);
477*4882a593Smuzhiyun if (!is_continuation(c, tty))
478*4882a593Smuzhiyun ldata->column++;
479*4882a593Smuzhiyun }
480*4882a593Smuzhiyun break;
481*4882a593Smuzhiyun }
482*4882a593Smuzhiyun
483*4882a593Smuzhiyun tty_put_char(tty, c);
484*4882a593Smuzhiyun return 1;
485*4882a593Smuzhiyun }
486*4882a593Smuzhiyun
487*4882a593Smuzhiyun /**
488*4882a593Smuzhiyun * process_output - output post processor
489*4882a593Smuzhiyun * @c: character (or partial unicode symbol)
490*4882a593Smuzhiyun * @tty: terminal device
491*4882a593Smuzhiyun *
492*4882a593Smuzhiyun * Output one character with OPOST processing.
493*4882a593Smuzhiyun * Returns -1 when the output device is full and the character
494*4882a593Smuzhiyun * must be retried.
495*4882a593Smuzhiyun *
496*4882a593Smuzhiyun * Locking: output_lock to protect column state and space left
497*4882a593Smuzhiyun * (also, this is called from n_tty_write under the
498*4882a593Smuzhiyun * tty layer write lock)
499*4882a593Smuzhiyun */
500*4882a593Smuzhiyun
process_output(unsigned char c,struct tty_struct * tty)501*4882a593Smuzhiyun static int process_output(unsigned char c, struct tty_struct *tty)
502*4882a593Smuzhiyun {
503*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
504*4882a593Smuzhiyun int space, retval;
505*4882a593Smuzhiyun
506*4882a593Smuzhiyun mutex_lock(&ldata->output_lock);
507*4882a593Smuzhiyun
508*4882a593Smuzhiyun space = tty_write_room(tty);
509*4882a593Smuzhiyun retval = do_output_char(c, tty, space);
510*4882a593Smuzhiyun
511*4882a593Smuzhiyun mutex_unlock(&ldata->output_lock);
512*4882a593Smuzhiyun if (retval < 0)
513*4882a593Smuzhiyun return -1;
514*4882a593Smuzhiyun else
515*4882a593Smuzhiyun return 0;
516*4882a593Smuzhiyun }
517*4882a593Smuzhiyun
518*4882a593Smuzhiyun /**
519*4882a593Smuzhiyun * process_output_block - block post processor
520*4882a593Smuzhiyun * @tty: terminal device
521*4882a593Smuzhiyun * @buf: character buffer
522*4882a593Smuzhiyun * @nr: number of bytes to output
523*4882a593Smuzhiyun *
524*4882a593Smuzhiyun * Output a block of characters with OPOST processing.
525*4882a593Smuzhiyun * Returns the number of characters output.
526*4882a593Smuzhiyun *
527*4882a593Smuzhiyun * This path is used to speed up block console writes, among other
528*4882a593Smuzhiyun * things when processing blocks of output data. It handles only
529*4882a593Smuzhiyun * the simple cases normally found and helps to generate blocks of
530*4882a593Smuzhiyun * symbols for the console driver and thus improve performance.
531*4882a593Smuzhiyun *
532*4882a593Smuzhiyun * Locking: output_lock to protect column state and space left
533*4882a593Smuzhiyun * (also, this is called from n_tty_write under the
534*4882a593Smuzhiyun * tty layer write lock)
535*4882a593Smuzhiyun */
536*4882a593Smuzhiyun
process_output_block(struct tty_struct * tty,const unsigned char * buf,unsigned int nr)537*4882a593Smuzhiyun static ssize_t process_output_block(struct tty_struct *tty,
538*4882a593Smuzhiyun const unsigned char *buf, unsigned int nr)
539*4882a593Smuzhiyun {
540*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
541*4882a593Smuzhiyun int space;
542*4882a593Smuzhiyun int i;
543*4882a593Smuzhiyun const unsigned char *cp;
544*4882a593Smuzhiyun
545*4882a593Smuzhiyun mutex_lock(&ldata->output_lock);
546*4882a593Smuzhiyun
547*4882a593Smuzhiyun space = tty_write_room(tty);
548*4882a593Smuzhiyun if (space <= 0) {
549*4882a593Smuzhiyun mutex_unlock(&ldata->output_lock);
550*4882a593Smuzhiyun return space;
551*4882a593Smuzhiyun }
552*4882a593Smuzhiyun if (nr > space)
553*4882a593Smuzhiyun nr = space;
554*4882a593Smuzhiyun
555*4882a593Smuzhiyun for (i = 0, cp = buf; i < nr; i++, cp++) {
556*4882a593Smuzhiyun unsigned char c = *cp;
557*4882a593Smuzhiyun
558*4882a593Smuzhiyun switch (c) {
559*4882a593Smuzhiyun case '\n':
560*4882a593Smuzhiyun if (O_ONLRET(tty))
561*4882a593Smuzhiyun ldata->column = 0;
562*4882a593Smuzhiyun if (O_ONLCR(tty))
563*4882a593Smuzhiyun goto break_out;
564*4882a593Smuzhiyun ldata->canon_column = ldata->column;
565*4882a593Smuzhiyun break;
566*4882a593Smuzhiyun case '\r':
567*4882a593Smuzhiyun if (O_ONOCR(tty) && ldata->column == 0)
568*4882a593Smuzhiyun goto break_out;
569*4882a593Smuzhiyun if (O_OCRNL(tty))
570*4882a593Smuzhiyun goto break_out;
571*4882a593Smuzhiyun ldata->canon_column = ldata->column = 0;
572*4882a593Smuzhiyun break;
573*4882a593Smuzhiyun case '\t':
574*4882a593Smuzhiyun goto break_out;
575*4882a593Smuzhiyun case '\b':
576*4882a593Smuzhiyun if (ldata->column > 0)
577*4882a593Smuzhiyun ldata->column--;
578*4882a593Smuzhiyun break;
579*4882a593Smuzhiyun default:
580*4882a593Smuzhiyun if (!iscntrl(c)) {
581*4882a593Smuzhiyun if (O_OLCUC(tty))
582*4882a593Smuzhiyun goto break_out;
583*4882a593Smuzhiyun if (!is_continuation(c, tty))
584*4882a593Smuzhiyun ldata->column++;
585*4882a593Smuzhiyun }
586*4882a593Smuzhiyun break;
587*4882a593Smuzhiyun }
588*4882a593Smuzhiyun }
589*4882a593Smuzhiyun break_out:
590*4882a593Smuzhiyun i = tty->ops->write(tty, buf, i);
591*4882a593Smuzhiyun
592*4882a593Smuzhiyun mutex_unlock(&ldata->output_lock);
593*4882a593Smuzhiyun return i;
594*4882a593Smuzhiyun }
595*4882a593Smuzhiyun
596*4882a593Smuzhiyun /**
597*4882a593Smuzhiyun * process_echoes - write pending echo characters
598*4882a593Smuzhiyun * @tty: terminal device
599*4882a593Smuzhiyun *
600*4882a593Smuzhiyun * Write previously buffered echo (and other ldisc-generated)
601*4882a593Smuzhiyun * characters to the tty.
602*4882a593Smuzhiyun *
603*4882a593Smuzhiyun * Characters generated by the ldisc (including echoes) need to
604*4882a593Smuzhiyun * be buffered because the driver's write buffer can fill during
605*4882a593Smuzhiyun * heavy program output. Echoing straight to the driver will
606*4882a593Smuzhiyun * often fail under these conditions, causing lost characters and
607*4882a593Smuzhiyun * resulting mismatches of ldisc state information.
608*4882a593Smuzhiyun *
609*4882a593Smuzhiyun * Since the ldisc state must represent the characters actually sent
610*4882a593Smuzhiyun * to the driver at the time of the write, operations like certain
611*4882a593Smuzhiyun * changes in column state are also saved in the buffer and executed
612*4882a593Smuzhiyun * here.
613*4882a593Smuzhiyun *
614*4882a593Smuzhiyun * A circular fifo buffer is used so that the most recent characters
615*4882a593Smuzhiyun * are prioritized. Also, when control characters are echoed with a
616*4882a593Smuzhiyun * prefixed "^", the pair is treated atomically and thus not separated.
617*4882a593Smuzhiyun *
618*4882a593Smuzhiyun * Locking: callers must hold output_lock
619*4882a593Smuzhiyun */
620*4882a593Smuzhiyun
__process_echoes(struct tty_struct * tty)621*4882a593Smuzhiyun static size_t __process_echoes(struct tty_struct *tty)
622*4882a593Smuzhiyun {
623*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
624*4882a593Smuzhiyun int space, old_space;
625*4882a593Smuzhiyun size_t tail;
626*4882a593Smuzhiyun unsigned char c;
627*4882a593Smuzhiyun
628*4882a593Smuzhiyun old_space = space = tty_write_room(tty);
629*4882a593Smuzhiyun
630*4882a593Smuzhiyun tail = ldata->echo_tail;
631*4882a593Smuzhiyun while (MASK(ldata->echo_commit) != MASK(tail)) {
632*4882a593Smuzhiyun c = echo_buf(ldata, tail);
633*4882a593Smuzhiyun if (c == ECHO_OP_START) {
634*4882a593Smuzhiyun unsigned char op;
635*4882a593Smuzhiyun int no_space_left = 0;
636*4882a593Smuzhiyun
637*4882a593Smuzhiyun /*
638*4882a593Smuzhiyun * Since add_echo_byte() is called without holding
639*4882a593Smuzhiyun * output_lock, we might see only portion of multi-byte
640*4882a593Smuzhiyun * operation.
641*4882a593Smuzhiyun */
642*4882a593Smuzhiyun if (MASK(ldata->echo_commit) == MASK(tail + 1))
643*4882a593Smuzhiyun goto not_yet_stored;
644*4882a593Smuzhiyun /*
645*4882a593Smuzhiyun * If the buffer byte is the start of a multi-byte
646*4882a593Smuzhiyun * operation, get the next byte, which is either the
647*4882a593Smuzhiyun * op code or a control character value.
648*4882a593Smuzhiyun */
649*4882a593Smuzhiyun op = echo_buf(ldata, tail + 1);
650*4882a593Smuzhiyun
651*4882a593Smuzhiyun switch (op) {
652*4882a593Smuzhiyun case ECHO_OP_ERASE_TAB: {
653*4882a593Smuzhiyun unsigned int num_chars, num_bs;
654*4882a593Smuzhiyun
655*4882a593Smuzhiyun if (MASK(ldata->echo_commit) == MASK(tail + 2))
656*4882a593Smuzhiyun goto not_yet_stored;
657*4882a593Smuzhiyun num_chars = echo_buf(ldata, tail + 2);
658*4882a593Smuzhiyun
659*4882a593Smuzhiyun /*
660*4882a593Smuzhiyun * Determine how many columns to go back
661*4882a593Smuzhiyun * in order to erase the tab.
662*4882a593Smuzhiyun * This depends on the number of columns
663*4882a593Smuzhiyun * used by other characters within the tab
664*4882a593Smuzhiyun * area. If this (modulo 8) count is from
665*4882a593Smuzhiyun * the start of input rather than from a
666*4882a593Smuzhiyun * previous tab, we offset by canon column.
667*4882a593Smuzhiyun * Otherwise, tab spacing is normal.
668*4882a593Smuzhiyun */
669*4882a593Smuzhiyun if (!(num_chars & 0x80))
670*4882a593Smuzhiyun num_chars += ldata->canon_column;
671*4882a593Smuzhiyun num_bs = 8 - (num_chars & 7);
672*4882a593Smuzhiyun
673*4882a593Smuzhiyun if (num_bs > space) {
674*4882a593Smuzhiyun no_space_left = 1;
675*4882a593Smuzhiyun break;
676*4882a593Smuzhiyun }
677*4882a593Smuzhiyun space -= num_bs;
678*4882a593Smuzhiyun while (num_bs--) {
679*4882a593Smuzhiyun tty_put_char(tty, '\b');
680*4882a593Smuzhiyun if (ldata->column > 0)
681*4882a593Smuzhiyun ldata->column--;
682*4882a593Smuzhiyun }
683*4882a593Smuzhiyun tail += 3;
684*4882a593Smuzhiyun break;
685*4882a593Smuzhiyun }
686*4882a593Smuzhiyun case ECHO_OP_SET_CANON_COL:
687*4882a593Smuzhiyun ldata->canon_column = ldata->column;
688*4882a593Smuzhiyun tail += 2;
689*4882a593Smuzhiyun break;
690*4882a593Smuzhiyun
691*4882a593Smuzhiyun case ECHO_OP_MOVE_BACK_COL:
692*4882a593Smuzhiyun if (ldata->column > 0)
693*4882a593Smuzhiyun ldata->column--;
694*4882a593Smuzhiyun tail += 2;
695*4882a593Smuzhiyun break;
696*4882a593Smuzhiyun
697*4882a593Smuzhiyun case ECHO_OP_START:
698*4882a593Smuzhiyun /* This is an escaped echo op start code */
699*4882a593Smuzhiyun if (!space) {
700*4882a593Smuzhiyun no_space_left = 1;
701*4882a593Smuzhiyun break;
702*4882a593Smuzhiyun }
703*4882a593Smuzhiyun tty_put_char(tty, ECHO_OP_START);
704*4882a593Smuzhiyun ldata->column++;
705*4882a593Smuzhiyun space--;
706*4882a593Smuzhiyun tail += 2;
707*4882a593Smuzhiyun break;
708*4882a593Smuzhiyun
709*4882a593Smuzhiyun default:
710*4882a593Smuzhiyun /*
711*4882a593Smuzhiyun * If the op is not a special byte code,
712*4882a593Smuzhiyun * it is a ctrl char tagged to be echoed
713*4882a593Smuzhiyun * as "^X" (where X is the letter
714*4882a593Smuzhiyun * representing the control char).
715*4882a593Smuzhiyun * Note that we must ensure there is
716*4882a593Smuzhiyun * enough space for the whole ctrl pair.
717*4882a593Smuzhiyun *
718*4882a593Smuzhiyun */
719*4882a593Smuzhiyun if (space < 2) {
720*4882a593Smuzhiyun no_space_left = 1;
721*4882a593Smuzhiyun break;
722*4882a593Smuzhiyun }
723*4882a593Smuzhiyun tty_put_char(tty, '^');
724*4882a593Smuzhiyun tty_put_char(tty, op ^ 0100);
725*4882a593Smuzhiyun ldata->column += 2;
726*4882a593Smuzhiyun space -= 2;
727*4882a593Smuzhiyun tail += 2;
728*4882a593Smuzhiyun }
729*4882a593Smuzhiyun
730*4882a593Smuzhiyun if (no_space_left)
731*4882a593Smuzhiyun break;
732*4882a593Smuzhiyun } else {
733*4882a593Smuzhiyun if (O_OPOST(tty)) {
734*4882a593Smuzhiyun int retval = do_output_char(c, tty, space);
735*4882a593Smuzhiyun if (retval < 0)
736*4882a593Smuzhiyun break;
737*4882a593Smuzhiyun space -= retval;
738*4882a593Smuzhiyun } else {
739*4882a593Smuzhiyun if (!space)
740*4882a593Smuzhiyun break;
741*4882a593Smuzhiyun tty_put_char(tty, c);
742*4882a593Smuzhiyun space -= 1;
743*4882a593Smuzhiyun }
744*4882a593Smuzhiyun tail += 1;
745*4882a593Smuzhiyun }
746*4882a593Smuzhiyun }
747*4882a593Smuzhiyun
748*4882a593Smuzhiyun /* If the echo buffer is nearly full (so that the possibility exists
749*4882a593Smuzhiyun * of echo overrun before the next commit), then discard enough
750*4882a593Smuzhiyun * data at the tail to prevent a subsequent overrun */
751*4882a593Smuzhiyun while (ldata->echo_commit > tail &&
752*4882a593Smuzhiyun ldata->echo_commit - tail >= ECHO_DISCARD_WATERMARK) {
753*4882a593Smuzhiyun if (echo_buf(ldata, tail) == ECHO_OP_START) {
754*4882a593Smuzhiyun if (echo_buf(ldata, tail + 1) == ECHO_OP_ERASE_TAB)
755*4882a593Smuzhiyun tail += 3;
756*4882a593Smuzhiyun else
757*4882a593Smuzhiyun tail += 2;
758*4882a593Smuzhiyun } else
759*4882a593Smuzhiyun tail++;
760*4882a593Smuzhiyun }
761*4882a593Smuzhiyun
762*4882a593Smuzhiyun not_yet_stored:
763*4882a593Smuzhiyun ldata->echo_tail = tail;
764*4882a593Smuzhiyun return old_space - space;
765*4882a593Smuzhiyun }
766*4882a593Smuzhiyun
commit_echoes(struct tty_struct * tty)767*4882a593Smuzhiyun static void commit_echoes(struct tty_struct *tty)
768*4882a593Smuzhiyun {
769*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
770*4882a593Smuzhiyun size_t nr, old, echoed;
771*4882a593Smuzhiyun size_t head;
772*4882a593Smuzhiyun
773*4882a593Smuzhiyun mutex_lock(&ldata->output_lock);
774*4882a593Smuzhiyun head = ldata->echo_head;
775*4882a593Smuzhiyun ldata->echo_mark = head;
776*4882a593Smuzhiyun old = ldata->echo_commit - ldata->echo_tail;
777*4882a593Smuzhiyun
778*4882a593Smuzhiyun /* Process committed echoes if the accumulated # of bytes
779*4882a593Smuzhiyun * is over the threshold (and try again each time another
780*4882a593Smuzhiyun * block is accumulated) */
781*4882a593Smuzhiyun nr = head - ldata->echo_tail;
782*4882a593Smuzhiyun if (nr < ECHO_COMMIT_WATERMARK ||
783*4882a593Smuzhiyun (nr % ECHO_BLOCK > old % ECHO_BLOCK)) {
784*4882a593Smuzhiyun mutex_unlock(&ldata->output_lock);
785*4882a593Smuzhiyun return;
786*4882a593Smuzhiyun }
787*4882a593Smuzhiyun
788*4882a593Smuzhiyun ldata->echo_commit = head;
789*4882a593Smuzhiyun echoed = __process_echoes(tty);
790*4882a593Smuzhiyun mutex_unlock(&ldata->output_lock);
791*4882a593Smuzhiyun
792*4882a593Smuzhiyun if (echoed && tty->ops->flush_chars)
793*4882a593Smuzhiyun tty->ops->flush_chars(tty);
794*4882a593Smuzhiyun }
795*4882a593Smuzhiyun
process_echoes(struct tty_struct * tty)796*4882a593Smuzhiyun static void process_echoes(struct tty_struct *tty)
797*4882a593Smuzhiyun {
798*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
799*4882a593Smuzhiyun size_t echoed;
800*4882a593Smuzhiyun
801*4882a593Smuzhiyun if (ldata->echo_mark == ldata->echo_tail)
802*4882a593Smuzhiyun return;
803*4882a593Smuzhiyun
804*4882a593Smuzhiyun mutex_lock(&ldata->output_lock);
805*4882a593Smuzhiyun ldata->echo_commit = ldata->echo_mark;
806*4882a593Smuzhiyun echoed = __process_echoes(tty);
807*4882a593Smuzhiyun mutex_unlock(&ldata->output_lock);
808*4882a593Smuzhiyun
809*4882a593Smuzhiyun if (echoed && tty->ops->flush_chars)
810*4882a593Smuzhiyun tty->ops->flush_chars(tty);
811*4882a593Smuzhiyun }
812*4882a593Smuzhiyun
813*4882a593Smuzhiyun /* NB: echo_mark and echo_head should be equivalent here */
flush_echoes(struct tty_struct * tty)814*4882a593Smuzhiyun static void flush_echoes(struct tty_struct *tty)
815*4882a593Smuzhiyun {
816*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
817*4882a593Smuzhiyun
818*4882a593Smuzhiyun if ((!L_ECHO(tty) && !L_ECHONL(tty)) ||
819*4882a593Smuzhiyun ldata->echo_commit == ldata->echo_head)
820*4882a593Smuzhiyun return;
821*4882a593Smuzhiyun
822*4882a593Smuzhiyun mutex_lock(&ldata->output_lock);
823*4882a593Smuzhiyun ldata->echo_commit = ldata->echo_head;
824*4882a593Smuzhiyun __process_echoes(tty);
825*4882a593Smuzhiyun mutex_unlock(&ldata->output_lock);
826*4882a593Smuzhiyun }
827*4882a593Smuzhiyun
828*4882a593Smuzhiyun /**
829*4882a593Smuzhiyun * add_echo_byte - add a byte to the echo buffer
830*4882a593Smuzhiyun * @c: unicode byte to echo
831*4882a593Smuzhiyun * @ldata: n_tty data
832*4882a593Smuzhiyun *
833*4882a593Smuzhiyun * Add a character or operation byte to the echo buffer.
834*4882a593Smuzhiyun */
835*4882a593Smuzhiyun
add_echo_byte(unsigned char c,struct n_tty_data * ldata)836*4882a593Smuzhiyun static inline void add_echo_byte(unsigned char c, struct n_tty_data *ldata)
837*4882a593Smuzhiyun {
838*4882a593Smuzhiyun *echo_buf_addr(ldata, ldata->echo_head) = c;
839*4882a593Smuzhiyun smp_wmb(); /* Matches smp_rmb() in echo_buf(). */
840*4882a593Smuzhiyun ldata->echo_head++;
841*4882a593Smuzhiyun }
842*4882a593Smuzhiyun
843*4882a593Smuzhiyun /**
844*4882a593Smuzhiyun * echo_move_back_col - add operation to move back a column
845*4882a593Smuzhiyun * @ldata: n_tty data
846*4882a593Smuzhiyun *
847*4882a593Smuzhiyun * Add an operation to the echo buffer to move back one column.
848*4882a593Smuzhiyun */
849*4882a593Smuzhiyun
echo_move_back_col(struct n_tty_data * ldata)850*4882a593Smuzhiyun static void echo_move_back_col(struct n_tty_data *ldata)
851*4882a593Smuzhiyun {
852*4882a593Smuzhiyun add_echo_byte(ECHO_OP_START, ldata);
853*4882a593Smuzhiyun add_echo_byte(ECHO_OP_MOVE_BACK_COL, ldata);
854*4882a593Smuzhiyun }
855*4882a593Smuzhiyun
856*4882a593Smuzhiyun /**
857*4882a593Smuzhiyun * echo_set_canon_col - add operation to set the canon column
858*4882a593Smuzhiyun * @ldata: n_tty data
859*4882a593Smuzhiyun *
860*4882a593Smuzhiyun * Add an operation to the echo buffer to set the canon column
861*4882a593Smuzhiyun * to the current column.
862*4882a593Smuzhiyun */
863*4882a593Smuzhiyun
echo_set_canon_col(struct n_tty_data * ldata)864*4882a593Smuzhiyun static void echo_set_canon_col(struct n_tty_data *ldata)
865*4882a593Smuzhiyun {
866*4882a593Smuzhiyun add_echo_byte(ECHO_OP_START, ldata);
867*4882a593Smuzhiyun add_echo_byte(ECHO_OP_SET_CANON_COL, ldata);
868*4882a593Smuzhiyun }
869*4882a593Smuzhiyun
870*4882a593Smuzhiyun /**
871*4882a593Smuzhiyun * echo_erase_tab - add operation to erase a tab
872*4882a593Smuzhiyun * @num_chars: number of character columns already used
873*4882a593Smuzhiyun * @after_tab: true if num_chars starts after a previous tab
874*4882a593Smuzhiyun * @ldata: n_tty data
875*4882a593Smuzhiyun *
876*4882a593Smuzhiyun * Add an operation to the echo buffer to erase a tab.
877*4882a593Smuzhiyun *
878*4882a593Smuzhiyun * Called by the eraser function, which knows how many character
879*4882a593Smuzhiyun * columns have been used since either a previous tab or the start
880*4882a593Smuzhiyun * of input. This information will be used later, along with
881*4882a593Smuzhiyun * canon column (if applicable), to go back the correct number
882*4882a593Smuzhiyun * of columns.
883*4882a593Smuzhiyun */
884*4882a593Smuzhiyun
echo_erase_tab(unsigned int num_chars,int after_tab,struct n_tty_data * ldata)885*4882a593Smuzhiyun static void echo_erase_tab(unsigned int num_chars, int after_tab,
886*4882a593Smuzhiyun struct n_tty_data *ldata)
887*4882a593Smuzhiyun {
888*4882a593Smuzhiyun add_echo_byte(ECHO_OP_START, ldata);
889*4882a593Smuzhiyun add_echo_byte(ECHO_OP_ERASE_TAB, ldata);
890*4882a593Smuzhiyun
891*4882a593Smuzhiyun /* We only need to know this modulo 8 (tab spacing) */
892*4882a593Smuzhiyun num_chars &= 7;
893*4882a593Smuzhiyun
894*4882a593Smuzhiyun /* Set the high bit as a flag if num_chars is after a previous tab */
895*4882a593Smuzhiyun if (after_tab)
896*4882a593Smuzhiyun num_chars |= 0x80;
897*4882a593Smuzhiyun
898*4882a593Smuzhiyun add_echo_byte(num_chars, ldata);
899*4882a593Smuzhiyun }
900*4882a593Smuzhiyun
901*4882a593Smuzhiyun /**
902*4882a593Smuzhiyun * echo_char_raw - echo a character raw
903*4882a593Smuzhiyun * @c: unicode byte to echo
904*4882a593Smuzhiyun * @ldata: line disc data
905*4882a593Smuzhiyun *
906*4882a593Smuzhiyun * Echo user input back onto the screen. This must be called only when
907*4882a593Smuzhiyun * L_ECHO(tty) is true. Called from the driver receive_buf path.
908*4882a593Smuzhiyun *
909*4882a593Smuzhiyun * This variant does not treat control characters specially.
910*4882a593Smuzhiyun */
911*4882a593Smuzhiyun
echo_char_raw(unsigned char c,struct n_tty_data * ldata)912*4882a593Smuzhiyun static void echo_char_raw(unsigned char c, struct n_tty_data *ldata)
913*4882a593Smuzhiyun {
914*4882a593Smuzhiyun if (c == ECHO_OP_START) {
915*4882a593Smuzhiyun add_echo_byte(ECHO_OP_START, ldata);
916*4882a593Smuzhiyun add_echo_byte(ECHO_OP_START, ldata);
917*4882a593Smuzhiyun } else {
918*4882a593Smuzhiyun add_echo_byte(c, ldata);
919*4882a593Smuzhiyun }
920*4882a593Smuzhiyun }
921*4882a593Smuzhiyun
922*4882a593Smuzhiyun /**
923*4882a593Smuzhiyun * echo_char - echo a character
924*4882a593Smuzhiyun * @c: unicode byte to echo
925*4882a593Smuzhiyun * @tty: terminal device
926*4882a593Smuzhiyun *
927*4882a593Smuzhiyun * Echo user input back onto the screen. This must be called only when
928*4882a593Smuzhiyun * L_ECHO(tty) is true. Called from the driver receive_buf path.
929*4882a593Smuzhiyun *
930*4882a593Smuzhiyun * This variant tags control characters to be echoed as "^X"
931*4882a593Smuzhiyun * (where X is the letter representing the control char).
932*4882a593Smuzhiyun */
933*4882a593Smuzhiyun
echo_char(unsigned char c,struct tty_struct * tty)934*4882a593Smuzhiyun static void echo_char(unsigned char c, struct tty_struct *tty)
935*4882a593Smuzhiyun {
936*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
937*4882a593Smuzhiyun
938*4882a593Smuzhiyun if (c == ECHO_OP_START) {
939*4882a593Smuzhiyun add_echo_byte(ECHO_OP_START, ldata);
940*4882a593Smuzhiyun add_echo_byte(ECHO_OP_START, ldata);
941*4882a593Smuzhiyun } else {
942*4882a593Smuzhiyun if (L_ECHOCTL(tty) && iscntrl(c) && c != '\t')
943*4882a593Smuzhiyun add_echo_byte(ECHO_OP_START, ldata);
944*4882a593Smuzhiyun add_echo_byte(c, ldata);
945*4882a593Smuzhiyun }
946*4882a593Smuzhiyun }
947*4882a593Smuzhiyun
948*4882a593Smuzhiyun /**
949*4882a593Smuzhiyun * finish_erasing - complete erase
950*4882a593Smuzhiyun * @ldata: n_tty data
951*4882a593Smuzhiyun */
952*4882a593Smuzhiyun
finish_erasing(struct n_tty_data * ldata)953*4882a593Smuzhiyun static inline void finish_erasing(struct n_tty_data *ldata)
954*4882a593Smuzhiyun {
955*4882a593Smuzhiyun if (ldata->erasing) {
956*4882a593Smuzhiyun echo_char_raw('/', ldata);
957*4882a593Smuzhiyun ldata->erasing = 0;
958*4882a593Smuzhiyun }
959*4882a593Smuzhiyun }
960*4882a593Smuzhiyun
961*4882a593Smuzhiyun /**
962*4882a593Smuzhiyun * eraser - handle erase function
963*4882a593Smuzhiyun * @c: character input
964*4882a593Smuzhiyun * @tty: terminal device
965*4882a593Smuzhiyun *
966*4882a593Smuzhiyun * Perform erase and necessary output when an erase character is
967*4882a593Smuzhiyun * present in the stream from the driver layer. Handles the complexities
968*4882a593Smuzhiyun * of UTF-8 multibyte symbols.
969*4882a593Smuzhiyun *
970*4882a593Smuzhiyun * n_tty_receive_buf()/producer path:
971*4882a593Smuzhiyun * caller holds non-exclusive termios_rwsem
972*4882a593Smuzhiyun */
973*4882a593Smuzhiyun
eraser(unsigned char c,struct tty_struct * tty)974*4882a593Smuzhiyun static void eraser(unsigned char c, struct tty_struct *tty)
975*4882a593Smuzhiyun {
976*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
977*4882a593Smuzhiyun enum { ERASE, WERASE, KILL } kill_type;
978*4882a593Smuzhiyun size_t head;
979*4882a593Smuzhiyun size_t cnt;
980*4882a593Smuzhiyun int seen_alnums;
981*4882a593Smuzhiyun
982*4882a593Smuzhiyun if (ldata->read_head == ldata->canon_head) {
983*4882a593Smuzhiyun /* process_output('\a', tty); */ /* what do you think? */
984*4882a593Smuzhiyun return;
985*4882a593Smuzhiyun }
986*4882a593Smuzhiyun if (c == ERASE_CHAR(tty))
987*4882a593Smuzhiyun kill_type = ERASE;
988*4882a593Smuzhiyun else if (c == WERASE_CHAR(tty))
989*4882a593Smuzhiyun kill_type = WERASE;
990*4882a593Smuzhiyun else {
991*4882a593Smuzhiyun if (!L_ECHO(tty)) {
992*4882a593Smuzhiyun ldata->read_head = ldata->canon_head;
993*4882a593Smuzhiyun return;
994*4882a593Smuzhiyun }
995*4882a593Smuzhiyun if (!L_ECHOK(tty) || !L_ECHOKE(tty) || !L_ECHOE(tty)) {
996*4882a593Smuzhiyun ldata->read_head = ldata->canon_head;
997*4882a593Smuzhiyun finish_erasing(ldata);
998*4882a593Smuzhiyun echo_char(KILL_CHAR(tty), tty);
999*4882a593Smuzhiyun /* Add a newline if ECHOK is on and ECHOKE is off. */
1000*4882a593Smuzhiyun if (L_ECHOK(tty))
1001*4882a593Smuzhiyun echo_char_raw('\n', ldata);
1002*4882a593Smuzhiyun return;
1003*4882a593Smuzhiyun }
1004*4882a593Smuzhiyun kill_type = KILL;
1005*4882a593Smuzhiyun }
1006*4882a593Smuzhiyun
1007*4882a593Smuzhiyun seen_alnums = 0;
1008*4882a593Smuzhiyun while (MASK(ldata->read_head) != MASK(ldata->canon_head)) {
1009*4882a593Smuzhiyun head = ldata->read_head;
1010*4882a593Smuzhiyun
1011*4882a593Smuzhiyun /* erase a single possibly multibyte character */
1012*4882a593Smuzhiyun do {
1013*4882a593Smuzhiyun head--;
1014*4882a593Smuzhiyun c = read_buf(ldata, head);
1015*4882a593Smuzhiyun } while (is_continuation(c, tty) &&
1016*4882a593Smuzhiyun MASK(head) != MASK(ldata->canon_head));
1017*4882a593Smuzhiyun
1018*4882a593Smuzhiyun /* do not partially erase */
1019*4882a593Smuzhiyun if (is_continuation(c, tty))
1020*4882a593Smuzhiyun break;
1021*4882a593Smuzhiyun
1022*4882a593Smuzhiyun if (kill_type == WERASE) {
1023*4882a593Smuzhiyun /* Equivalent to BSD's ALTWERASE. */
1024*4882a593Smuzhiyun if (isalnum(c) || c == '_')
1025*4882a593Smuzhiyun seen_alnums++;
1026*4882a593Smuzhiyun else if (seen_alnums)
1027*4882a593Smuzhiyun break;
1028*4882a593Smuzhiyun }
1029*4882a593Smuzhiyun cnt = ldata->read_head - head;
1030*4882a593Smuzhiyun ldata->read_head = head;
1031*4882a593Smuzhiyun if (L_ECHO(tty)) {
1032*4882a593Smuzhiyun if (L_ECHOPRT(tty)) {
1033*4882a593Smuzhiyun if (!ldata->erasing) {
1034*4882a593Smuzhiyun echo_char_raw('\\', ldata);
1035*4882a593Smuzhiyun ldata->erasing = 1;
1036*4882a593Smuzhiyun }
1037*4882a593Smuzhiyun /* if cnt > 1, output a multi-byte character */
1038*4882a593Smuzhiyun echo_char(c, tty);
1039*4882a593Smuzhiyun while (--cnt > 0) {
1040*4882a593Smuzhiyun head++;
1041*4882a593Smuzhiyun echo_char_raw(read_buf(ldata, head), ldata);
1042*4882a593Smuzhiyun echo_move_back_col(ldata);
1043*4882a593Smuzhiyun }
1044*4882a593Smuzhiyun } else if (kill_type == ERASE && !L_ECHOE(tty)) {
1045*4882a593Smuzhiyun echo_char(ERASE_CHAR(tty), tty);
1046*4882a593Smuzhiyun } else if (c == '\t') {
1047*4882a593Smuzhiyun unsigned int num_chars = 0;
1048*4882a593Smuzhiyun int after_tab = 0;
1049*4882a593Smuzhiyun size_t tail = ldata->read_head;
1050*4882a593Smuzhiyun
1051*4882a593Smuzhiyun /*
1052*4882a593Smuzhiyun * Count the columns used for characters
1053*4882a593Smuzhiyun * since the start of input or after a
1054*4882a593Smuzhiyun * previous tab.
1055*4882a593Smuzhiyun * This info is used to go back the correct
1056*4882a593Smuzhiyun * number of columns.
1057*4882a593Smuzhiyun */
1058*4882a593Smuzhiyun while (MASK(tail) != MASK(ldata->canon_head)) {
1059*4882a593Smuzhiyun tail--;
1060*4882a593Smuzhiyun c = read_buf(ldata, tail);
1061*4882a593Smuzhiyun if (c == '\t') {
1062*4882a593Smuzhiyun after_tab = 1;
1063*4882a593Smuzhiyun break;
1064*4882a593Smuzhiyun } else if (iscntrl(c)) {
1065*4882a593Smuzhiyun if (L_ECHOCTL(tty))
1066*4882a593Smuzhiyun num_chars += 2;
1067*4882a593Smuzhiyun } else if (!is_continuation(c, tty)) {
1068*4882a593Smuzhiyun num_chars++;
1069*4882a593Smuzhiyun }
1070*4882a593Smuzhiyun }
1071*4882a593Smuzhiyun echo_erase_tab(num_chars, after_tab, ldata);
1072*4882a593Smuzhiyun } else {
1073*4882a593Smuzhiyun if (iscntrl(c) && L_ECHOCTL(tty)) {
1074*4882a593Smuzhiyun echo_char_raw('\b', ldata);
1075*4882a593Smuzhiyun echo_char_raw(' ', ldata);
1076*4882a593Smuzhiyun echo_char_raw('\b', ldata);
1077*4882a593Smuzhiyun }
1078*4882a593Smuzhiyun if (!iscntrl(c) || L_ECHOCTL(tty)) {
1079*4882a593Smuzhiyun echo_char_raw('\b', ldata);
1080*4882a593Smuzhiyun echo_char_raw(' ', ldata);
1081*4882a593Smuzhiyun echo_char_raw('\b', ldata);
1082*4882a593Smuzhiyun }
1083*4882a593Smuzhiyun }
1084*4882a593Smuzhiyun }
1085*4882a593Smuzhiyun if (kill_type == ERASE)
1086*4882a593Smuzhiyun break;
1087*4882a593Smuzhiyun }
1088*4882a593Smuzhiyun if (ldata->read_head == ldata->canon_head && L_ECHO(tty))
1089*4882a593Smuzhiyun finish_erasing(ldata);
1090*4882a593Smuzhiyun }
1091*4882a593Smuzhiyun
1092*4882a593Smuzhiyun /**
1093*4882a593Smuzhiyun * isig - handle the ISIG optio
1094*4882a593Smuzhiyun * @sig: signal
1095*4882a593Smuzhiyun * @tty: terminal
1096*4882a593Smuzhiyun *
1097*4882a593Smuzhiyun * Called when a signal is being sent due to terminal input.
1098*4882a593Smuzhiyun * Called from the driver receive_buf path so serialized.
1099*4882a593Smuzhiyun *
1100*4882a593Smuzhiyun * Performs input and output flush if !NOFLSH. In this context, the echo
1101*4882a593Smuzhiyun * buffer is 'output'. The signal is processed first to alert any current
1102*4882a593Smuzhiyun * readers or writers to discontinue and exit their i/o loops.
1103*4882a593Smuzhiyun *
1104*4882a593Smuzhiyun * Locking: ctrl_lock
1105*4882a593Smuzhiyun */
1106*4882a593Smuzhiyun
__isig(int sig,struct tty_struct * tty)1107*4882a593Smuzhiyun static void __isig(int sig, struct tty_struct *tty)
1108*4882a593Smuzhiyun {
1109*4882a593Smuzhiyun struct pid *tty_pgrp = tty_get_pgrp(tty);
1110*4882a593Smuzhiyun if (tty_pgrp) {
1111*4882a593Smuzhiyun kill_pgrp(tty_pgrp, sig, 1);
1112*4882a593Smuzhiyun put_pid(tty_pgrp);
1113*4882a593Smuzhiyun }
1114*4882a593Smuzhiyun }
1115*4882a593Smuzhiyun
isig(int sig,struct tty_struct * tty)1116*4882a593Smuzhiyun static void isig(int sig, struct tty_struct *tty)
1117*4882a593Smuzhiyun {
1118*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
1119*4882a593Smuzhiyun
1120*4882a593Smuzhiyun if (L_NOFLSH(tty)) {
1121*4882a593Smuzhiyun /* signal only */
1122*4882a593Smuzhiyun __isig(sig, tty);
1123*4882a593Smuzhiyun
1124*4882a593Smuzhiyun } else { /* signal and flush */
1125*4882a593Smuzhiyun up_read(&tty->termios_rwsem);
1126*4882a593Smuzhiyun down_write(&tty->termios_rwsem);
1127*4882a593Smuzhiyun
1128*4882a593Smuzhiyun __isig(sig, tty);
1129*4882a593Smuzhiyun
1130*4882a593Smuzhiyun /* clear echo buffer */
1131*4882a593Smuzhiyun mutex_lock(&ldata->output_lock);
1132*4882a593Smuzhiyun ldata->echo_head = ldata->echo_tail = 0;
1133*4882a593Smuzhiyun ldata->echo_mark = ldata->echo_commit = 0;
1134*4882a593Smuzhiyun mutex_unlock(&ldata->output_lock);
1135*4882a593Smuzhiyun
1136*4882a593Smuzhiyun /* clear output buffer */
1137*4882a593Smuzhiyun tty_driver_flush_buffer(tty);
1138*4882a593Smuzhiyun
1139*4882a593Smuzhiyun /* clear input buffer */
1140*4882a593Smuzhiyun reset_buffer_flags(tty->disc_data);
1141*4882a593Smuzhiyun
1142*4882a593Smuzhiyun /* notify pty master of flush */
1143*4882a593Smuzhiyun if (tty->link)
1144*4882a593Smuzhiyun n_tty_packet_mode_flush(tty);
1145*4882a593Smuzhiyun
1146*4882a593Smuzhiyun up_write(&tty->termios_rwsem);
1147*4882a593Smuzhiyun down_read(&tty->termios_rwsem);
1148*4882a593Smuzhiyun }
1149*4882a593Smuzhiyun }
1150*4882a593Smuzhiyun
1151*4882a593Smuzhiyun /**
1152*4882a593Smuzhiyun * n_tty_receive_break - handle break
1153*4882a593Smuzhiyun * @tty: terminal
1154*4882a593Smuzhiyun *
1155*4882a593Smuzhiyun * An RS232 break event has been hit in the incoming bitstream. This
1156*4882a593Smuzhiyun * can cause a variety of events depending upon the termios settings.
1157*4882a593Smuzhiyun *
1158*4882a593Smuzhiyun * n_tty_receive_buf()/producer path:
1159*4882a593Smuzhiyun * caller holds non-exclusive termios_rwsem
1160*4882a593Smuzhiyun *
1161*4882a593Smuzhiyun * Note: may get exclusive termios_rwsem if flushing input buffer
1162*4882a593Smuzhiyun */
1163*4882a593Smuzhiyun
n_tty_receive_break(struct tty_struct * tty)1164*4882a593Smuzhiyun static void n_tty_receive_break(struct tty_struct *tty)
1165*4882a593Smuzhiyun {
1166*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
1167*4882a593Smuzhiyun
1168*4882a593Smuzhiyun if (I_IGNBRK(tty))
1169*4882a593Smuzhiyun return;
1170*4882a593Smuzhiyun if (I_BRKINT(tty)) {
1171*4882a593Smuzhiyun isig(SIGINT, tty);
1172*4882a593Smuzhiyun return;
1173*4882a593Smuzhiyun }
1174*4882a593Smuzhiyun if (I_PARMRK(tty)) {
1175*4882a593Smuzhiyun put_tty_queue('\377', ldata);
1176*4882a593Smuzhiyun put_tty_queue('\0', ldata);
1177*4882a593Smuzhiyun }
1178*4882a593Smuzhiyun put_tty_queue('\0', ldata);
1179*4882a593Smuzhiyun }
1180*4882a593Smuzhiyun
1181*4882a593Smuzhiyun /**
1182*4882a593Smuzhiyun * n_tty_receive_overrun - handle overrun reporting
1183*4882a593Smuzhiyun * @tty: terminal
1184*4882a593Smuzhiyun *
1185*4882a593Smuzhiyun * Data arrived faster than we could process it. While the tty
1186*4882a593Smuzhiyun * driver has flagged this the bits that were missed are gone
1187*4882a593Smuzhiyun * forever.
1188*4882a593Smuzhiyun *
1189*4882a593Smuzhiyun * Called from the receive_buf path so single threaded. Does not
1190*4882a593Smuzhiyun * need locking as num_overrun and overrun_time are function
1191*4882a593Smuzhiyun * private.
1192*4882a593Smuzhiyun */
1193*4882a593Smuzhiyun
n_tty_receive_overrun(struct tty_struct * tty)1194*4882a593Smuzhiyun static void n_tty_receive_overrun(struct tty_struct *tty)
1195*4882a593Smuzhiyun {
1196*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
1197*4882a593Smuzhiyun
1198*4882a593Smuzhiyun ldata->num_overrun++;
1199*4882a593Smuzhiyun if (time_after(jiffies, ldata->overrun_time + HZ) ||
1200*4882a593Smuzhiyun time_after(ldata->overrun_time, jiffies)) {
1201*4882a593Smuzhiyun tty_warn(tty, "%d input overrun(s)\n", ldata->num_overrun);
1202*4882a593Smuzhiyun ldata->overrun_time = jiffies;
1203*4882a593Smuzhiyun ldata->num_overrun = 0;
1204*4882a593Smuzhiyun }
1205*4882a593Smuzhiyun }
1206*4882a593Smuzhiyun
1207*4882a593Smuzhiyun /**
1208*4882a593Smuzhiyun * n_tty_receive_parity_error - error notifier
1209*4882a593Smuzhiyun * @tty: terminal device
1210*4882a593Smuzhiyun * @c: character
1211*4882a593Smuzhiyun *
1212*4882a593Smuzhiyun * Process a parity error and queue the right data to indicate
1213*4882a593Smuzhiyun * the error case if necessary.
1214*4882a593Smuzhiyun *
1215*4882a593Smuzhiyun * n_tty_receive_buf()/producer path:
1216*4882a593Smuzhiyun * caller holds non-exclusive termios_rwsem
1217*4882a593Smuzhiyun */
n_tty_receive_parity_error(struct tty_struct * tty,unsigned char c)1218*4882a593Smuzhiyun static void n_tty_receive_parity_error(struct tty_struct *tty, unsigned char c)
1219*4882a593Smuzhiyun {
1220*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
1221*4882a593Smuzhiyun
1222*4882a593Smuzhiyun if (I_INPCK(tty)) {
1223*4882a593Smuzhiyun if (I_IGNPAR(tty))
1224*4882a593Smuzhiyun return;
1225*4882a593Smuzhiyun if (I_PARMRK(tty)) {
1226*4882a593Smuzhiyun put_tty_queue('\377', ldata);
1227*4882a593Smuzhiyun put_tty_queue('\0', ldata);
1228*4882a593Smuzhiyun put_tty_queue(c, ldata);
1229*4882a593Smuzhiyun } else
1230*4882a593Smuzhiyun put_tty_queue('\0', ldata);
1231*4882a593Smuzhiyun } else
1232*4882a593Smuzhiyun put_tty_queue(c, ldata);
1233*4882a593Smuzhiyun }
1234*4882a593Smuzhiyun
1235*4882a593Smuzhiyun static void
n_tty_receive_signal_char(struct tty_struct * tty,int signal,unsigned char c)1236*4882a593Smuzhiyun n_tty_receive_signal_char(struct tty_struct *tty, int signal, unsigned char c)
1237*4882a593Smuzhiyun {
1238*4882a593Smuzhiyun isig(signal, tty);
1239*4882a593Smuzhiyun if (I_IXON(tty))
1240*4882a593Smuzhiyun start_tty(tty);
1241*4882a593Smuzhiyun if (L_ECHO(tty)) {
1242*4882a593Smuzhiyun echo_char(c, tty);
1243*4882a593Smuzhiyun commit_echoes(tty);
1244*4882a593Smuzhiyun } else
1245*4882a593Smuzhiyun process_echoes(tty);
1246*4882a593Smuzhiyun return;
1247*4882a593Smuzhiyun }
1248*4882a593Smuzhiyun
1249*4882a593Smuzhiyun /**
1250*4882a593Smuzhiyun * n_tty_receive_char - perform processing
1251*4882a593Smuzhiyun * @tty: terminal device
1252*4882a593Smuzhiyun * @c: character
1253*4882a593Smuzhiyun *
1254*4882a593Smuzhiyun * Process an individual character of input received from the driver.
1255*4882a593Smuzhiyun * This is serialized with respect to itself by the rules for the
1256*4882a593Smuzhiyun * driver above.
1257*4882a593Smuzhiyun *
1258*4882a593Smuzhiyun * n_tty_receive_buf()/producer path:
1259*4882a593Smuzhiyun * caller holds non-exclusive termios_rwsem
1260*4882a593Smuzhiyun * publishes canon_head if canonical mode is active
1261*4882a593Smuzhiyun *
1262*4882a593Smuzhiyun * Returns 1 if LNEXT was received, else returns 0
1263*4882a593Smuzhiyun */
1264*4882a593Smuzhiyun
1265*4882a593Smuzhiyun static int
n_tty_receive_char_special(struct tty_struct * tty,unsigned char c)1266*4882a593Smuzhiyun n_tty_receive_char_special(struct tty_struct *tty, unsigned char c)
1267*4882a593Smuzhiyun {
1268*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
1269*4882a593Smuzhiyun
1270*4882a593Smuzhiyun if (I_IXON(tty)) {
1271*4882a593Smuzhiyun if (c == START_CHAR(tty)) {
1272*4882a593Smuzhiyun start_tty(tty);
1273*4882a593Smuzhiyun process_echoes(tty);
1274*4882a593Smuzhiyun return 0;
1275*4882a593Smuzhiyun }
1276*4882a593Smuzhiyun if (c == STOP_CHAR(tty)) {
1277*4882a593Smuzhiyun stop_tty(tty);
1278*4882a593Smuzhiyun return 0;
1279*4882a593Smuzhiyun }
1280*4882a593Smuzhiyun }
1281*4882a593Smuzhiyun
1282*4882a593Smuzhiyun if (L_ISIG(tty)) {
1283*4882a593Smuzhiyun if (c == INTR_CHAR(tty)) {
1284*4882a593Smuzhiyun n_tty_receive_signal_char(tty, SIGINT, c);
1285*4882a593Smuzhiyun return 0;
1286*4882a593Smuzhiyun } else if (c == QUIT_CHAR(tty)) {
1287*4882a593Smuzhiyun n_tty_receive_signal_char(tty, SIGQUIT, c);
1288*4882a593Smuzhiyun return 0;
1289*4882a593Smuzhiyun } else if (c == SUSP_CHAR(tty)) {
1290*4882a593Smuzhiyun n_tty_receive_signal_char(tty, SIGTSTP, c);
1291*4882a593Smuzhiyun return 0;
1292*4882a593Smuzhiyun }
1293*4882a593Smuzhiyun }
1294*4882a593Smuzhiyun
1295*4882a593Smuzhiyun if (tty->stopped && !tty->flow_stopped && I_IXON(tty) && I_IXANY(tty)) {
1296*4882a593Smuzhiyun start_tty(tty);
1297*4882a593Smuzhiyun process_echoes(tty);
1298*4882a593Smuzhiyun }
1299*4882a593Smuzhiyun
1300*4882a593Smuzhiyun if (c == '\r') {
1301*4882a593Smuzhiyun if (I_IGNCR(tty))
1302*4882a593Smuzhiyun return 0;
1303*4882a593Smuzhiyun if (I_ICRNL(tty))
1304*4882a593Smuzhiyun c = '\n';
1305*4882a593Smuzhiyun } else if (c == '\n' && I_INLCR(tty))
1306*4882a593Smuzhiyun c = '\r';
1307*4882a593Smuzhiyun
1308*4882a593Smuzhiyun if (ldata->icanon) {
1309*4882a593Smuzhiyun if (c == ERASE_CHAR(tty) || c == KILL_CHAR(tty) ||
1310*4882a593Smuzhiyun (c == WERASE_CHAR(tty) && L_IEXTEN(tty))) {
1311*4882a593Smuzhiyun eraser(c, tty);
1312*4882a593Smuzhiyun commit_echoes(tty);
1313*4882a593Smuzhiyun return 0;
1314*4882a593Smuzhiyun }
1315*4882a593Smuzhiyun if (c == LNEXT_CHAR(tty) && L_IEXTEN(tty)) {
1316*4882a593Smuzhiyun ldata->lnext = 1;
1317*4882a593Smuzhiyun if (L_ECHO(tty)) {
1318*4882a593Smuzhiyun finish_erasing(ldata);
1319*4882a593Smuzhiyun if (L_ECHOCTL(tty)) {
1320*4882a593Smuzhiyun echo_char_raw('^', ldata);
1321*4882a593Smuzhiyun echo_char_raw('\b', ldata);
1322*4882a593Smuzhiyun commit_echoes(tty);
1323*4882a593Smuzhiyun }
1324*4882a593Smuzhiyun }
1325*4882a593Smuzhiyun return 1;
1326*4882a593Smuzhiyun }
1327*4882a593Smuzhiyun if (c == REPRINT_CHAR(tty) && L_ECHO(tty) && L_IEXTEN(tty)) {
1328*4882a593Smuzhiyun size_t tail = ldata->canon_head;
1329*4882a593Smuzhiyun
1330*4882a593Smuzhiyun finish_erasing(ldata);
1331*4882a593Smuzhiyun echo_char(c, tty);
1332*4882a593Smuzhiyun echo_char_raw('\n', ldata);
1333*4882a593Smuzhiyun while (MASK(tail) != MASK(ldata->read_head)) {
1334*4882a593Smuzhiyun echo_char(read_buf(ldata, tail), tty);
1335*4882a593Smuzhiyun tail++;
1336*4882a593Smuzhiyun }
1337*4882a593Smuzhiyun commit_echoes(tty);
1338*4882a593Smuzhiyun return 0;
1339*4882a593Smuzhiyun }
1340*4882a593Smuzhiyun if (c == '\n') {
1341*4882a593Smuzhiyun if (L_ECHO(tty) || L_ECHONL(tty)) {
1342*4882a593Smuzhiyun echo_char_raw('\n', ldata);
1343*4882a593Smuzhiyun commit_echoes(tty);
1344*4882a593Smuzhiyun }
1345*4882a593Smuzhiyun goto handle_newline;
1346*4882a593Smuzhiyun }
1347*4882a593Smuzhiyun if (c == EOF_CHAR(tty)) {
1348*4882a593Smuzhiyun c = __DISABLED_CHAR;
1349*4882a593Smuzhiyun goto handle_newline;
1350*4882a593Smuzhiyun }
1351*4882a593Smuzhiyun if ((c == EOL_CHAR(tty)) ||
1352*4882a593Smuzhiyun (c == EOL2_CHAR(tty) && L_IEXTEN(tty))) {
1353*4882a593Smuzhiyun /*
1354*4882a593Smuzhiyun * XXX are EOL_CHAR and EOL2_CHAR echoed?!?
1355*4882a593Smuzhiyun */
1356*4882a593Smuzhiyun if (L_ECHO(tty)) {
1357*4882a593Smuzhiyun /* Record the column of first canon char. */
1358*4882a593Smuzhiyun if (ldata->canon_head == ldata->read_head)
1359*4882a593Smuzhiyun echo_set_canon_col(ldata);
1360*4882a593Smuzhiyun echo_char(c, tty);
1361*4882a593Smuzhiyun commit_echoes(tty);
1362*4882a593Smuzhiyun }
1363*4882a593Smuzhiyun /*
1364*4882a593Smuzhiyun * XXX does PARMRK doubling happen for
1365*4882a593Smuzhiyun * EOL_CHAR and EOL2_CHAR?
1366*4882a593Smuzhiyun */
1367*4882a593Smuzhiyun if (c == (unsigned char) '\377' && I_PARMRK(tty))
1368*4882a593Smuzhiyun put_tty_queue(c, ldata);
1369*4882a593Smuzhiyun
1370*4882a593Smuzhiyun handle_newline:
1371*4882a593Smuzhiyun set_bit(ldata->read_head & (N_TTY_BUF_SIZE - 1), ldata->read_flags);
1372*4882a593Smuzhiyun put_tty_queue(c, ldata);
1373*4882a593Smuzhiyun smp_store_release(&ldata->canon_head, ldata->read_head);
1374*4882a593Smuzhiyun kill_fasync(&tty->fasync, SIGIO, POLL_IN);
1375*4882a593Smuzhiyun wake_up_interruptible_poll(&tty->read_wait, EPOLLIN | EPOLLRDNORM);
1376*4882a593Smuzhiyun return 0;
1377*4882a593Smuzhiyun }
1378*4882a593Smuzhiyun }
1379*4882a593Smuzhiyun
1380*4882a593Smuzhiyun if (L_ECHO(tty)) {
1381*4882a593Smuzhiyun finish_erasing(ldata);
1382*4882a593Smuzhiyun if (c == '\n')
1383*4882a593Smuzhiyun echo_char_raw('\n', ldata);
1384*4882a593Smuzhiyun else {
1385*4882a593Smuzhiyun /* Record the column of first canon char. */
1386*4882a593Smuzhiyun if (ldata->canon_head == ldata->read_head)
1387*4882a593Smuzhiyun echo_set_canon_col(ldata);
1388*4882a593Smuzhiyun echo_char(c, tty);
1389*4882a593Smuzhiyun }
1390*4882a593Smuzhiyun commit_echoes(tty);
1391*4882a593Smuzhiyun }
1392*4882a593Smuzhiyun
1393*4882a593Smuzhiyun /* PARMRK doubling check */
1394*4882a593Smuzhiyun if (c == (unsigned char) '\377' && I_PARMRK(tty))
1395*4882a593Smuzhiyun put_tty_queue(c, ldata);
1396*4882a593Smuzhiyun
1397*4882a593Smuzhiyun put_tty_queue(c, ldata);
1398*4882a593Smuzhiyun return 0;
1399*4882a593Smuzhiyun }
1400*4882a593Smuzhiyun
1401*4882a593Smuzhiyun static inline void
n_tty_receive_char_inline(struct tty_struct * tty,unsigned char c)1402*4882a593Smuzhiyun n_tty_receive_char_inline(struct tty_struct *tty, unsigned char c)
1403*4882a593Smuzhiyun {
1404*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
1405*4882a593Smuzhiyun
1406*4882a593Smuzhiyun if (tty->stopped && !tty->flow_stopped && I_IXON(tty) && I_IXANY(tty)) {
1407*4882a593Smuzhiyun start_tty(tty);
1408*4882a593Smuzhiyun process_echoes(tty);
1409*4882a593Smuzhiyun }
1410*4882a593Smuzhiyun if (L_ECHO(tty)) {
1411*4882a593Smuzhiyun finish_erasing(ldata);
1412*4882a593Smuzhiyun /* Record the column of first canon char. */
1413*4882a593Smuzhiyun if (ldata->canon_head == ldata->read_head)
1414*4882a593Smuzhiyun echo_set_canon_col(ldata);
1415*4882a593Smuzhiyun echo_char(c, tty);
1416*4882a593Smuzhiyun commit_echoes(tty);
1417*4882a593Smuzhiyun }
1418*4882a593Smuzhiyun /* PARMRK doubling check */
1419*4882a593Smuzhiyun if (c == (unsigned char) '\377' && I_PARMRK(tty))
1420*4882a593Smuzhiyun put_tty_queue(c, ldata);
1421*4882a593Smuzhiyun put_tty_queue(c, ldata);
1422*4882a593Smuzhiyun }
1423*4882a593Smuzhiyun
n_tty_receive_char(struct tty_struct * tty,unsigned char c)1424*4882a593Smuzhiyun static void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
1425*4882a593Smuzhiyun {
1426*4882a593Smuzhiyun n_tty_receive_char_inline(tty, c);
1427*4882a593Smuzhiyun }
1428*4882a593Smuzhiyun
1429*4882a593Smuzhiyun static inline void
n_tty_receive_char_fast(struct tty_struct * tty,unsigned char c)1430*4882a593Smuzhiyun n_tty_receive_char_fast(struct tty_struct *tty, unsigned char c)
1431*4882a593Smuzhiyun {
1432*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
1433*4882a593Smuzhiyun
1434*4882a593Smuzhiyun if (tty->stopped && !tty->flow_stopped && I_IXON(tty) && I_IXANY(tty)) {
1435*4882a593Smuzhiyun start_tty(tty);
1436*4882a593Smuzhiyun process_echoes(tty);
1437*4882a593Smuzhiyun }
1438*4882a593Smuzhiyun if (L_ECHO(tty)) {
1439*4882a593Smuzhiyun finish_erasing(ldata);
1440*4882a593Smuzhiyun /* Record the column of first canon char. */
1441*4882a593Smuzhiyun if (ldata->canon_head == ldata->read_head)
1442*4882a593Smuzhiyun echo_set_canon_col(ldata);
1443*4882a593Smuzhiyun echo_char(c, tty);
1444*4882a593Smuzhiyun commit_echoes(tty);
1445*4882a593Smuzhiyun }
1446*4882a593Smuzhiyun put_tty_queue(c, ldata);
1447*4882a593Smuzhiyun }
1448*4882a593Smuzhiyun
n_tty_receive_char_closing(struct tty_struct * tty,unsigned char c)1449*4882a593Smuzhiyun static void n_tty_receive_char_closing(struct tty_struct *tty, unsigned char c)
1450*4882a593Smuzhiyun {
1451*4882a593Smuzhiyun if (I_ISTRIP(tty))
1452*4882a593Smuzhiyun c &= 0x7f;
1453*4882a593Smuzhiyun if (I_IUCLC(tty) && L_IEXTEN(tty))
1454*4882a593Smuzhiyun c = tolower(c);
1455*4882a593Smuzhiyun
1456*4882a593Smuzhiyun if (I_IXON(tty)) {
1457*4882a593Smuzhiyun if (c == STOP_CHAR(tty))
1458*4882a593Smuzhiyun stop_tty(tty);
1459*4882a593Smuzhiyun else if (c == START_CHAR(tty) ||
1460*4882a593Smuzhiyun (tty->stopped && !tty->flow_stopped && I_IXANY(tty) &&
1461*4882a593Smuzhiyun c != INTR_CHAR(tty) && c != QUIT_CHAR(tty) &&
1462*4882a593Smuzhiyun c != SUSP_CHAR(tty))) {
1463*4882a593Smuzhiyun start_tty(tty);
1464*4882a593Smuzhiyun process_echoes(tty);
1465*4882a593Smuzhiyun }
1466*4882a593Smuzhiyun }
1467*4882a593Smuzhiyun }
1468*4882a593Smuzhiyun
1469*4882a593Smuzhiyun static void
n_tty_receive_char_flagged(struct tty_struct * tty,unsigned char c,char flag)1470*4882a593Smuzhiyun n_tty_receive_char_flagged(struct tty_struct *tty, unsigned char c, char flag)
1471*4882a593Smuzhiyun {
1472*4882a593Smuzhiyun switch (flag) {
1473*4882a593Smuzhiyun case TTY_BREAK:
1474*4882a593Smuzhiyun n_tty_receive_break(tty);
1475*4882a593Smuzhiyun break;
1476*4882a593Smuzhiyun case TTY_PARITY:
1477*4882a593Smuzhiyun case TTY_FRAME:
1478*4882a593Smuzhiyun n_tty_receive_parity_error(tty, c);
1479*4882a593Smuzhiyun break;
1480*4882a593Smuzhiyun case TTY_OVERRUN:
1481*4882a593Smuzhiyun n_tty_receive_overrun(tty);
1482*4882a593Smuzhiyun break;
1483*4882a593Smuzhiyun default:
1484*4882a593Smuzhiyun tty_err(tty, "unknown flag %d\n", flag);
1485*4882a593Smuzhiyun break;
1486*4882a593Smuzhiyun }
1487*4882a593Smuzhiyun }
1488*4882a593Smuzhiyun
1489*4882a593Smuzhiyun static void
n_tty_receive_char_lnext(struct tty_struct * tty,unsigned char c,char flag)1490*4882a593Smuzhiyun n_tty_receive_char_lnext(struct tty_struct *tty, unsigned char c, char flag)
1491*4882a593Smuzhiyun {
1492*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
1493*4882a593Smuzhiyun
1494*4882a593Smuzhiyun ldata->lnext = 0;
1495*4882a593Smuzhiyun if (likely(flag == TTY_NORMAL)) {
1496*4882a593Smuzhiyun if (I_ISTRIP(tty))
1497*4882a593Smuzhiyun c &= 0x7f;
1498*4882a593Smuzhiyun if (I_IUCLC(tty) && L_IEXTEN(tty))
1499*4882a593Smuzhiyun c = tolower(c);
1500*4882a593Smuzhiyun n_tty_receive_char(tty, c);
1501*4882a593Smuzhiyun } else
1502*4882a593Smuzhiyun n_tty_receive_char_flagged(tty, c, flag);
1503*4882a593Smuzhiyun }
1504*4882a593Smuzhiyun
1505*4882a593Smuzhiyun static void
n_tty_receive_buf_real_raw(struct tty_struct * tty,const unsigned char * cp,char * fp,int count)1506*4882a593Smuzhiyun n_tty_receive_buf_real_raw(struct tty_struct *tty, const unsigned char *cp,
1507*4882a593Smuzhiyun char *fp, int count)
1508*4882a593Smuzhiyun {
1509*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
1510*4882a593Smuzhiyun size_t n, head;
1511*4882a593Smuzhiyun
1512*4882a593Smuzhiyun head = ldata->read_head & (N_TTY_BUF_SIZE - 1);
1513*4882a593Smuzhiyun n = min_t(size_t, count, N_TTY_BUF_SIZE - head);
1514*4882a593Smuzhiyun memcpy(read_buf_addr(ldata, head), cp, n);
1515*4882a593Smuzhiyun ldata->read_head += n;
1516*4882a593Smuzhiyun cp += n;
1517*4882a593Smuzhiyun count -= n;
1518*4882a593Smuzhiyun
1519*4882a593Smuzhiyun head = ldata->read_head & (N_TTY_BUF_SIZE - 1);
1520*4882a593Smuzhiyun n = min_t(size_t, count, N_TTY_BUF_SIZE - head);
1521*4882a593Smuzhiyun memcpy(read_buf_addr(ldata, head), cp, n);
1522*4882a593Smuzhiyun ldata->read_head += n;
1523*4882a593Smuzhiyun }
1524*4882a593Smuzhiyun
1525*4882a593Smuzhiyun static void
n_tty_receive_buf_raw(struct tty_struct * tty,const unsigned char * cp,char * fp,int count)1526*4882a593Smuzhiyun n_tty_receive_buf_raw(struct tty_struct *tty, const unsigned char *cp,
1527*4882a593Smuzhiyun char *fp, int count)
1528*4882a593Smuzhiyun {
1529*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
1530*4882a593Smuzhiyun char flag = TTY_NORMAL;
1531*4882a593Smuzhiyun
1532*4882a593Smuzhiyun while (count--) {
1533*4882a593Smuzhiyun if (fp)
1534*4882a593Smuzhiyun flag = *fp++;
1535*4882a593Smuzhiyun if (likely(flag == TTY_NORMAL))
1536*4882a593Smuzhiyun put_tty_queue(*cp++, ldata);
1537*4882a593Smuzhiyun else
1538*4882a593Smuzhiyun n_tty_receive_char_flagged(tty, *cp++, flag);
1539*4882a593Smuzhiyun }
1540*4882a593Smuzhiyun }
1541*4882a593Smuzhiyun
1542*4882a593Smuzhiyun static void
n_tty_receive_buf_closing(struct tty_struct * tty,const unsigned char * cp,char * fp,int count)1543*4882a593Smuzhiyun n_tty_receive_buf_closing(struct tty_struct *tty, const unsigned char *cp,
1544*4882a593Smuzhiyun char *fp, int count)
1545*4882a593Smuzhiyun {
1546*4882a593Smuzhiyun char flag = TTY_NORMAL;
1547*4882a593Smuzhiyun
1548*4882a593Smuzhiyun while (count--) {
1549*4882a593Smuzhiyun if (fp)
1550*4882a593Smuzhiyun flag = *fp++;
1551*4882a593Smuzhiyun if (likely(flag == TTY_NORMAL))
1552*4882a593Smuzhiyun n_tty_receive_char_closing(tty, *cp++);
1553*4882a593Smuzhiyun }
1554*4882a593Smuzhiyun }
1555*4882a593Smuzhiyun
1556*4882a593Smuzhiyun static void
n_tty_receive_buf_standard(struct tty_struct * tty,const unsigned char * cp,char * fp,int count)1557*4882a593Smuzhiyun n_tty_receive_buf_standard(struct tty_struct *tty, const unsigned char *cp,
1558*4882a593Smuzhiyun char *fp, int count)
1559*4882a593Smuzhiyun {
1560*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
1561*4882a593Smuzhiyun char flag = TTY_NORMAL;
1562*4882a593Smuzhiyun
1563*4882a593Smuzhiyun while (count--) {
1564*4882a593Smuzhiyun if (fp)
1565*4882a593Smuzhiyun flag = *fp++;
1566*4882a593Smuzhiyun if (likely(flag == TTY_NORMAL)) {
1567*4882a593Smuzhiyun unsigned char c = *cp++;
1568*4882a593Smuzhiyun
1569*4882a593Smuzhiyun if (I_ISTRIP(tty))
1570*4882a593Smuzhiyun c &= 0x7f;
1571*4882a593Smuzhiyun if (I_IUCLC(tty) && L_IEXTEN(tty))
1572*4882a593Smuzhiyun c = tolower(c);
1573*4882a593Smuzhiyun if (L_EXTPROC(tty)) {
1574*4882a593Smuzhiyun put_tty_queue(c, ldata);
1575*4882a593Smuzhiyun continue;
1576*4882a593Smuzhiyun }
1577*4882a593Smuzhiyun if (!test_bit(c, ldata->char_map))
1578*4882a593Smuzhiyun n_tty_receive_char_inline(tty, c);
1579*4882a593Smuzhiyun else if (n_tty_receive_char_special(tty, c) && count) {
1580*4882a593Smuzhiyun if (fp)
1581*4882a593Smuzhiyun flag = *fp++;
1582*4882a593Smuzhiyun n_tty_receive_char_lnext(tty, *cp++, flag);
1583*4882a593Smuzhiyun count--;
1584*4882a593Smuzhiyun }
1585*4882a593Smuzhiyun } else
1586*4882a593Smuzhiyun n_tty_receive_char_flagged(tty, *cp++, flag);
1587*4882a593Smuzhiyun }
1588*4882a593Smuzhiyun }
1589*4882a593Smuzhiyun
1590*4882a593Smuzhiyun static void
n_tty_receive_buf_fast(struct tty_struct * tty,const unsigned char * cp,char * fp,int count)1591*4882a593Smuzhiyun n_tty_receive_buf_fast(struct tty_struct *tty, const unsigned char *cp,
1592*4882a593Smuzhiyun char *fp, int count)
1593*4882a593Smuzhiyun {
1594*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
1595*4882a593Smuzhiyun char flag = TTY_NORMAL;
1596*4882a593Smuzhiyun
1597*4882a593Smuzhiyun while (count--) {
1598*4882a593Smuzhiyun if (fp)
1599*4882a593Smuzhiyun flag = *fp++;
1600*4882a593Smuzhiyun if (likely(flag == TTY_NORMAL)) {
1601*4882a593Smuzhiyun unsigned char c = *cp++;
1602*4882a593Smuzhiyun
1603*4882a593Smuzhiyun if (!test_bit(c, ldata->char_map))
1604*4882a593Smuzhiyun n_tty_receive_char_fast(tty, c);
1605*4882a593Smuzhiyun else if (n_tty_receive_char_special(tty, c) && count) {
1606*4882a593Smuzhiyun if (fp)
1607*4882a593Smuzhiyun flag = *fp++;
1608*4882a593Smuzhiyun n_tty_receive_char_lnext(tty, *cp++, flag);
1609*4882a593Smuzhiyun count--;
1610*4882a593Smuzhiyun }
1611*4882a593Smuzhiyun } else
1612*4882a593Smuzhiyun n_tty_receive_char_flagged(tty, *cp++, flag);
1613*4882a593Smuzhiyun }
1614*4882a593Smuzhiyun }
1615*4882a593Smuzhiyun
__receive_buf(struct tty_struct * tty,const unsigned char * cp,char * fp,int count)1616*4882a593Smuzhiyun static void __receive_buf(struct tty_struct *tty, const unsigned char *cp,
1617*4882a593Smuzhiyun char *fp, int count)
1618*4882a593Smuzhiyun {
1619*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
1620*4882a593Smuzhiyun bool preops = I_ISTRIP(tty) || (I_IUCLC(tty) && L_IEXTEN(tty));
1621*4882a593Smuzhiyun
1622*4882a593Smuzhiyun if (ldata->real_raw)
1623*4882a593Smuzhiyun n_tty_receive_buf_real_raw(tty, cp, fp, count);
1624*4882a593Smuzhiyun else if (ldata->raw || (L_EXTPROC(tty) && !preops))
1625*4882a593Smuzhiyun n_tty_receive_buf_raw(tty, cp, fp, count);
1626*4882a593Smuzhiyun else if (tty->closing && !L_EXTPROC(tty))
1627*4882a593Smuzhiyun n_tty_receive_buf_closing(tty, cp, fp, count);
1628*4882a593Smuzhiyun else {
1629*4882a593Smuzhiyun if (ldata->lnext) {
1630*4882a593Smuzhiyun char flag = TTY_NORMAL;
1631*4882a593Smuzhiyun
1632*4882a593Smuzhiyun if (fp)
1633*4882a593Smuzhiyun flag = *fp++;
1634*4882a593Smuzhiyun n_tty_receive_char_lnext(tty, *cp++, flag);
1635*4882a593Smuzhiyun count--;
1636*4882a593Smuzhiyun }
1637*4882a593Smuzhiyun
1638*4882a593Smuzhiyun if (!preops && !I_PARMRK(tty))
1639*4882a593Smuzhiyun n_tty_receive_buf_fast(tty, cp, fp, count);
1640*4882a593Smuzhiyun else
1641*4882a593Smuzhiyun n_tty_receive_buf_standard(tty, cp, fp, count);
1642*4882a593Smuzhiyun
1643*4882a593Smuzhiyun flush_echoes(tty);
1644*4882a593Smuzhiyun if (tty->ops->flush_chars)
1645*4882a593Smuzhiyun tty->ops->flush_chars(tty);
1646*4882a593Smuzhiyun }
1647*4882a593Smuzhiyun
1648*4882a593Smuzhiyun if (ldata->icanon && !L_EXTPROC(tty))
1649*4882a593Smuzhiyun return;
1650*4882a593Smuzhiyun
1651*4882a593Smuzhiyun /* publish read_head to consumer */
1652*4882a593Smuzhiyun smp_store_release(&ldata->commit_head, ldata->read_head);
1653*4882a593Smuzhiyun
1654*4882a593Smuzhiyun if (read_cnt(ldata)) {
1655*4882a593Smuzhiyun kill_fasync(&tty->fasync, SIGIO, POLL_IN);
1656*4882a593Smuzhiyun wake_up_interruptible_poll(&tty->read_wait, EPOLLIN | EPOLLRDNORM);
1657*4882a593Smuzhiyun }
1658*4882a593Smuzhiyun }
1659*4882a593Smuzhiyun
1660*4882a593Smuzhiyun /**
1661*4882a593Smuzhiyun * n_tty_receive_buf_common - process input
1662*4882a593Smuzhiyun * @tty: device to receive input
1663*4882a593Smuzhiyun * @cp: input chars
1664*4882a593Smuzhiyun * @fp: flags for each char (if NULL, all chars are TTY_NORMAL)
1665*4882a593Smuzhiyun * @count: number of input chars in @cp
1666*4882a593Smuzhiyun *
1667*4882a593Smuzhiyun * Called by the terminal driver when a block of characters has
1668*4882a593Smuzhiyun * been received. This function must be called from soft contexts
1669*4882a593Smuzhiyun * not from interrupt context. The driver is responsible for making
1670*4882a593Smuzhiyun * calls one at a time and in order (or using flush_to_ldisc)
1671*4882a593Smuzhiyun *
1672*4882a593Smuzhiyun * Returns the # of input chars from @cp which were processed.
1673*4882a593Smuzhiyun *
1674*4882a593Smuzhiyun * In canonical mode, the maximum line length is 4096 chars (including
1675*4882a593Smuzhiyun * the line termination char); lines longer than 4096 chars are
1676*4882a593Smuzhiyun * truncated. After 4095 chars, input data is still processed but
1677*4882a593Smuzhiyun * not stored. Overflow processing ensures the tty can always
1678*4882a593Smuzhiyun * receive more input until at least one line can be read.
1679*4882a593Smuzhiyun *
1680*4882a593Smuzhiyun * In non-canonical mode, the read buffer will only accept 4095 chars;
1681*4882a593Smuzhiyun * this provides the necessary space for a newline char if the input
1682*4882a593Smuzhiyun * mode is switched to canonical.
1683*4882a593Smuzhiyun *
1684*4882a593Smuzhiyun * Note it is possible for the read buffer to _contain_ 4096 chars
1685*4882a593Smuzhiyun * in non-canonical mode: the read buffer could already contain the
1686*4882a593Smuzhiyun * maximum canon line of 4096 chars when the mode is switched to
1687*4882a593Smuzhiyun * non-canonical.
1688*4882a593Smuzhiyun *
1689*4882a593Smuzhiyun * n_tty_receive_buf()/producer path:
1690*4882a593Smuzhiyun * claims non-exclusive termios_rwsem
1691*4882a593Smuzhiyun * publishes commit_head or canon_head
1692*4882a593Smuzhiyun */
1693*4882a593Smuzhiyun static int
n_tty_receive_buf_common(struct tty_struct * tty,const unsigned char * cp,char * fp,int count,int flow)1694*4882a593Smuzhiyun n_tty_receive_buf_common(struct tty_struct *tty, const unsigned char *cp,
1695*4882a593Smuzhiyun char *fp, int count, int flow)
1696*4882a593Smuzhiyun {
1697*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
1698*4882a593Smuzhiyun int room, n, rcvd = 0, overflow;
1699*4882a593Smuzhiyun
1700*4882a593Smuzhiyun down_read(&tty->termios_rwsem);
1701*4882a593Smuzhiyun
1702*4882a593Smuzhiyun do {
1703*4882a593Smuzhiyun /*
1704*4882a593Smuzhiyun * When PARMRK is set, each input char may take up to 3 chars
1705*4882a593Smuzhiyun * in the read buf; reduce the buffer space avail by 3x
1706*4882a593Smuzhiyun *
1707*4882a593Smuzhiyun * If we are doing input canonicalization, and there are no
1708*4882a593Smuzhiyun * pending newlines, let characters through without limit, so
1709*4882a593Smuzhiyun * that erase characters will be handled. Other excess
1710*4882a593Smuzhiyun * characters will be beeped.
1711*4882a593Smuzhiyun *
1712*4882a593Smuzhiyun * paired with store in *_copy_from_read_buf() -- guarantees
1713*4882a593Smuzhiyun * the consumer has loaded the data in read_buf up to the new
1714*4882a593Smuzhiyun * read_tail (so this producer will not overwrite unread data)
1715*4882a593Smuzhiyun */
1716*4882a593Smuzhiyun size_t tail = smp_load_acquire(&ldata->read_tail);
1717*4882a593Smuzhiyun
1718*4882a593Smuzhiyun room = N_TTY_BUF_SIZE - (ldata->read_head - tail);
1719*4882a593Smuzhiyun if (I_PARMRK(tty))
1720*4882a593Smuzhiyun room = (room + 2) / 3;
1721*4882a593Smuzhiyun room--;
1722*4882a593Smuzhiyun if (room <= 0) {
1723*4882a593Smuzhiyun overflow = ldata->icanon && ldata->canon_head == tail;
1724*4882a593Smuzhiyun if (overflow && room < 0)
1725*4882a593Smuzhiyun ldata->read_head--;
1726*4882a593Smuzhiyun room = overflow;
1727*4882a593Smuzhiyun ldata->no_room = flow && !room;
1728*4882a593Smuzhiyun } else
1729*4882a593Smuzhiyun overflow = 0;
1730*4882a593Smuzhiyun
1731*4882a593Smuzhiyun n = min(count, room);
1732*4882a593Smuzhiyun if (!n)
1733*4882a593Smuzhiyun break;
1734*4882a593Smuzhiyun
1735*4882a593Smuzhiyun /* ignore parity errors if handling overflow */
1736*4882a593Smuzhiyun if (!overflow || !fp || *fp != TTY_PARITY)
1737*4882a593Smuzhiyun __receive_buf(tty, cp, fp, n);
1738*4882a593Smuzhiyun
1739*4882a593Smuzhiyun cp += n;
1740*4882a593Smuzhiyun if (fp)
1741*4882a593Smuzhiyun fp += n;
1742*4882a593Smuzhiyun count -= n;
1743*4882a593Smuzhiyun rcvd += n;
1744*4882a593Smuzhiyun } while (!test_bit(TTY_LDISC_CHANGING, &tty->flags));
1745*4882a593Smuzhiyun
1746*4882a593Smuzhiyun tty->receive_room = room;
1747*4882a593Smuzhiyun
1748*4882a593Smuzhiyun /* Unthrottle if handling overflow on pty */
1749*4882a593Smuzhiyun if (tty->driver->type == TTY_DRIVER_TYPE_PTY) {
1750*4882a593Smuzhiyun if (overflow) {
1751*4882a593Smuzhiyun tty_set_flow_change(tty, TTY_UNTHROTTLE_SAFE);
1752*4882a593Smuzhiyun tty_unthrottle_safe(tty);
1753*4882a593Smuzhiyun __tty_set_flow_change(tty, 0);
1754*4882a593Smuzhiyun }
1755*4882a593Smuzhiyun } else
1756*4882a593Smuzhiyun n_tty_check_throttle(tty);
1757*4882a593Smuzhiyun
1758*4882a593Smuzhiyun up_read(&tty->termios_rwsem);
1759*4882a593Smuzhiyun
1760*4882a593Smuzhiyun return rcvd;
1761*4882a593Smuzhiyun }
1762*4882a593Smuzhiyun
n_tty_receive_buf(struct tty_struct * tty,const unsigned char * cp,char * fp,int count)1763*4882a593Smuzhiyun static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
1764*4882a593Smuzhiyun char *fp, int count)
1765*4882a593Smuzhiyun {
1766*4882a593Smuzhiyun n_tty_receive_buf_common(tty, cp, fp, count, 0);
1767*4882a593Smuzhiyun }
1768*4882a593Smuzhiyun
n_tty_receive_buf2(struct tty_struct * tty,const unsigned char * cp,char * fp,int count)1769*4882a593Smuzhiyun static int n_tty_receive_buf2(struct tty_struct *tty, const unsigned char *cp,
1770*4882a593Smuzhiyun char *fp, int count)
1771*4882a593Smuzhiyun {
1772*4882a593Smuzhiyun return n_tty_receive_buf_common(tty, cp, fp, count, 1);
1773*4882a593Smuzhiyun }
1774*4882a593Smuzhiyun
1775*4882a593Smuzhiyun /**
1776*4882a593Smuzhiyun * n_tty_set_termios - termios data changed
1777*4882a593Smuzhiyun * @tty: terminal
1778*4882a593Smuzhiyun * @old: previous data
1779*4882a593Smuzhiyun *
1780*4882a593Smuzhiyun * Called by the tty layer when the user changes termios flags so
1781*4882a593Smuzhiyun * that the line discipline can plan ahead. This function cannot sleep
1782*4882a593Smuzhiyun * and is protected from re-entry by the tty layer. The user is
1783*4882a593Smuzhiyun * guaranteed that this function will not be re-entered or in progress
1784*4882a593Smuzhiyun * when the ldisc is closed.
1785*4882a593Smuzhiyun *
1786*4882a593Smuzhiyun * Locking: Caller holds tty->termios_rwsem
1787*4882a593Smuzhiyun */
1788*4882a593Smuzhiyun
n_tty_set_termios(struct tty_struct * tty,struct ktermios * old)1789*4882a593Smuzhiyun static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
1790*4882a593Smuzhiyun {
1791*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
1792*4882a593Smuzhiyun
1793*4882a593Smuzhiyun if (!old || (old->c_lflag ^ tty->termios.c_lflag) & (ICANON | EXTPROC)) {
1794*4882a593Smuzhiyun bitmap_zero(ldata->read_flags, N_TTY_BUF_SIZE);
1795*4882a593Smuzhiyun ldata->line_start = ldata->read_tail;
1796*4882a593Smuzhiyun if (!L_ICANON(tty) || !read_cnt(ldata)) {
1797*4882a593Smuzhiyun ldata->canon_head = ldata->read_tail;
1798*4882a593Smuzhiyun ldata->push = 0;
1799*4882a593Smuzhiyun } else {
1800*4882a593Smuzhiyun set_bit((ldata->read_head - 1) & (N_TTY_BUF_SIZE - 1),
1801*4882a593Smuzhiyun ldata->read_flags);
1802*4882a593Smuzhiyun ldata->canon_head = ldata->read_head;
1803*4882a593Smuzhiyun ldata->push = 1;
1804*4882a593Smuzhiyun }
1805*4882a593Smuzhiyun ldata->commit_head = ldata->read_head;
1806*4882a593Smuzhiyun ldata->erasing = 0;
1807*4882a593Smuzhiyun ldata->lnext = 0;
1808*4882a593Smuzhiyun }
1809*4882a593Smuzhiyun
1810*4882a593Smuzhiyun ldata->icanon = (L_ICANON(tty) != 0);
1811*4882a593Smuzhiyun
1812*4882a593Smuzhiyun if (I_ISTRIP(tty) || I_IUCLC(tty) || I_IGNCR(tty) ||
1813*4882a593Smuzhiyun I_ICRNL(tty) || I_INLCR(tty) || L_ICANON(tty) ||
1814*4882a593Smuzhiyun I_IXON(tty) || L_ISIG(tty) || L_ECHO(tty) ||
1815*4882a593Smuzhiyun I_PARMRK(tty)) {
1816*4882a593Smuzhiyun bitmap_zero(ldata->char_map, 256);
1817*4882a593Smuzhiyun
1818*4882a593Smuzhiyun if (I_IGNCR(tty) || I_ICRNL(tty))
1819*4882a593Smuzhiyun set_bit('\r', ldata->char_map);
1820*4882a593Smuzhiyun if (I_INLCR(tty))
1821*4882a593Smuzhiyun set_bit('\n', ldata->char_map);
1822*4882a593Smuzhiyun
1823*4882a593Smuzhiyun if (L_ICANON(tty)) {
1824*4882a593Smuzhiyun set_bit(ERASE_CHAR(tty), ldata->char_map);
1825*4882a593Smuzhiyun set_bit(KILL_CHAR(tty), ldata->char_map);
1826*4882a593Smuzhiyun set_bit(EOF_CHAR(tty), ldata->char_map);
1827*4882a593Smuzhiyun set_bit('\n', ldata->char_map);
1828*4882a593Smuzhiyun set_bit(EOL_CHAR(tty), ldata->char_map);
1829*4882a593Smuzhiyun if (L_IEXTEN(tty)) {
1830*4882a593Smuzhiyun set_bit(WERASE_CHAR(tty), ldata->char_map);
1831*4882a593Smuzhiyun set_bit(LNEXT_CHAR(tty), ldata->char_map);
1832*4882a593Smuzhiyun set_bit(EOL2_CHAR(tty), ldata->char_map);
1833*4882a593Smuzhiyun if (L_ECHO(tty))
1834*4882a593Smuzhiyun set_bit(REPRINT_CHAR(tty),
1835*4882a593Smuzhiyun ldata->char_map);
1836*4882a593Smuzhiyun }
1837*4882a593Smuzhiyun }
1838*4882a593Smuzhiyun if (I_IXON(tty)) {
1839*4882a593Smuzhiyun set_bit(START_CHAR(tty), ldata->char_map);
1840*4882a593Smuzhiyun set_bit(STOP_CHAR(tty), ldata->char_map);
1841*4882a593Smuzhiyun }
1842*4882a593Smuzhiyun if (L_ISIG(tty)) {
1843*4882a593Smuzhiyun set_bit(INTR_CHAR(tty), ldata->char_map);
1844*4882a593Smuzhiyun set_bit(QUIT_CHAR(tty), ldata->char_map);
1845*4882a593Smuzhiyun set_bit(SUSP_CHAR(tty), ldata->char_map);
1846*4882a593Smuzhiyun }
1847*4882a593Smuzhiyun clear_bit(__DISABLED_CHAR, ldata->char_map);
1848*4882a593Smuzhiyun ldata->raw = 0;
1849*4882a593Smuzhiyun ldata->real_raw = 0;
1850*4882a593Smuzhiyun } else {
1851*4882a593Smuzhiyun ldata->raw = 1;
1852*4882a593Smuzhiyun if ((I_IGNBRK(tty) || (!I_BRKINT(tty) && !I_PARMRK(tty))) &&
1853*4882a593Smuzhiyun (I_IGNPAR(tty) || !I_INPCK(tty)) &&
1854*4882a593Smuzhiyun (tty->driver->flags & TTY_DRIVER_REAL_RAW))
1855*4882a593Smuzhiyun ldata->real_raw = 1;
1856*4882a593Smuzhiyun else
1857*4882a593Smuzhiyun ldata->real_raw = 0;
1858*4882a593Smuzhiyun }
1859*4882a593Smuzhiyun /*
1860*4882a593Smuzhiyun * Fix tty hang when I_IXON(tty) is cleared, but the tty
1861*4882a593Smuzhiyun * been stopped by STOP_CHAR(tty) before it.
1862*4882a593Smuzhiyun */
1863*4882a593Smuzhiyun if (!I_IXON(tty) && old && (old->c_iflag & IXON) && !tty->flow_stopped) {
1864*4882a593Smuzhiyun start_tty(tty);
1865*4882a593Smuzhiyun process_echoes(tty);
1866*4882a593Smuzhiyun }
1867*4882a593Smuzhiyun
1868*4882a593Smuzhiyun /* The termios change make the tty ready for I/O */
1869*4882a593Smuzhiyun wake_up_interruptible(&tty->write_wait);
1870*4882a593Smuzhiyun wake_up_interruptible(&tty->read_wait);
1871*4882a593Smuzhiyun }
1872*4882a593Smuzhiyun
1873*4882a593Smuzhiyun /**
1874*4882a593Smuzhiyun * n_tty_close - close the ldisc for this tty
1875*4882a593Smuzhiyun * @tty: device
1876*4882a593Smuzhiyun *
1877*4882a593Smuzhiyun * Called from the terminal layer when this line discipline is
1878*4882a593Smuzhiyun * being shut down, either because of a close or becsuse of a
1879*4882a593Smuzhiyun * discipline change. The function will not be called while other
1880*4882a593Smuzhiyun * ldisc methods are in progress.
1881*4882a593Smuzhiyun */
1882*4882a593Smuzhiyun
n_tty_close(struct tty_struct * tty)1883*4882a593Smuzhiyun static void n_tty_close(struct tty_struct *tty)
1884*4882a593Smuzhiyun {
1885*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
1886*4882a593Smuzhiyun
1887*4882a593Smuzhiyun if (tty->link)
1888*4882a593Smuzhiyun n_tty_packet_mode_flush(tty);
1889*4882a593Smuzhiyun
1890*4882a593Smuzhiyun vfree(ldata);
1891*4882a593Smuzhiyun tty->disc_data = NULL;
1892*4882a593Smuzhiyun }
1893*4882a593Smuzhiyun
1894*4882a593Smuzhiyun /**
1895*4882a593Smuzhiyun * n_tty_open - open an ldisc
1896*4882a593Smuzhiyun * @tty: terminal to open
1897*4882a593Smuzhiyun *
1898*4882a593Smuzhiyun * Called when this line discipline is being attached to the
1899*4882a593Smuzhiyun * terminal device. Can sleep. Called serialized so that no
1900*4882a593Smuzhiyun * other events will occur in parallel. No further open will occur
1901*4882a593Smuzhiyun * until a close.
1902*4882a593Smuzhiyun */
1903*4882a593Smuzhiyun
n_tty_open(struct tty_struct * tty)1904*4882a593Smuzhiyun static int n_tty_open(struct tty_struct *tty)
1905*4882a593Smuzhiyun {
1906*4882a593Smuzhiyun struct n_tty_data *ldata;
1907*4882a593Smuzhiyun
1908*4882a593Smuzhiyun /* Currently a malloc failure here can panic */
1909*4882a593Smuzhiyun ldata = vzalloc(sizeof(*ldata));
1910*4882a593Smuzhiyun if (!ldata)
1911*4882a593Smuzhiyun return -ENOMEM;
1912*4882a593Smuzhiyun
1913*4882a593Smuzhiyun ldata->overrun_time = jiffies;
1914*4882a593Smuzhiyun mutex_init(&ldata->atomic_read_lock);
1915*4882a593Smuzhiyun mutex_init(&ldata->output_lock);
1916*4882a593Smuzhiyun
1917*4882a593Smuzhiyun tty->disc_data = ldata;
1918*4882a593Smuzhiyun tty->closing = 0;
1919*4882a593Smuzhiyun /* indicate buffer work may resume */
1920*4882a593Smuzhiyun clear_bit(TTY_LDISC_HALTED, &tty->flags);
1921*4882a593Smuzhiyun n_tty_set_termios(tty, NULL);
1922*4882a593Smuzhiyun tty_unthrottle(tty);
1923*4882a593Smuzhiyun return 0;
1924*4882a593Smuzhiyun }
1925*4882a593Smuzhiyun
input_available_p(struct tty_struct * tty,int poll)1926*4882a593Smuzhiyun static inline int input_available_p(struct tty_struct *tty, int poll)
1927*4882a593Smuzhiyun {
1928*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
1929*4882a593Smuzhiyun int amt = poll && !TIME_CHAR(tty) && MIN_CHAR(tty) ? MIN_CHAR(tty) : 1;
1930*4882a593Smuzhiyun
1931*4882a593Smuzhiyun if (ldata->icanon && !L_EXTPROC(tty))
1932*4882a593Smuzhiyun return ldata->canon_head != ldata->read_tail;
1933*4882a593Smuzhiyun else
1934*4882a593Smuzhiyun return ldata->commit_head - ldata->read_tail >= amt;
1935*4882a593Smuzhiyun }
1936*4882a593Smuzhiyun
1937*4882a593Smuzhiyun /**
1938*4882a593Smuzhiyun * copy_from_read_buf - copy read data directly
1939*4882a593Smuzhiyun * @tty: terminal device
1940*4882a593Smuzhiyun * @kbp: data
1941*4882a593Smuzhiyun * @nr: size of data
1942*4882a593Smuzhiyun *
1943*4882a593Smuzhiyun * Helper function to speed up n_tty_read. It is only called when
1944*4882a593Smuzhiyun * ICANON is off; it copies characters straight from the tty queue.
1945*4882a593Smuzhiyun *
1946*4882a593Smuzhiyun * Called under the ldata->atomic_read_lock sem
1947*4882a593Smuzhiyun *
1948*4882a593Smuzhiyun * Returns true if it successfully copied data, but there is still
1949*4882a593Smuzhiyun * more data to be had.
1950*4882a593Smuzhiyun *
1951*4882a593Smuzhiyun * n_tty_read()/consumer path:
1952*4882a593Smuzhiyun * caller holds non-exclusive termios_rwsem
1953*4882a593Smuzhiyun * read_tail published
1954*4882a593Smuzhiyun */
1955*4882a593Smuzhiyun
copy_from_read_buf(struct tty_struct * tty,unsigned char ** kbp,size_t * nr)1956*4882a593Smuzhiyun static bool copy_from_read_buf(struct tty_struct *tty,
1957*4882a593Smuzhiyun unsigned char **kbp,
1958*4882a593Smuzhiyun size_t *nr)
1959*4882a593Smuzhiyun
1960*4882a593Smuzhiyun {
1961*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
1962*4882a593Smuzhiyun size_t n;
1963*4882a593Smuzhiyun bool is_eof;
1964*4882a593Smuzhiyun size_t head = smp_load_acquire(&ldata->commit_head);
1965*4882a593Smuzhiyun size_t tail = ldata->read_tail & (N_TTY_BUF_SIZE - 1);
1966*4882a593Smuzhiyun
1967*4882a593Smuzhiyun n = min(head - ldata->read_tail, N_TTY_BUF_SIZE - tail);
1968*4882a593Smuzhiyun n = min(*nr, n);
1969*4882a593Smuzhiyun if (n) {
1970*4882a593Smuzhiyun unsigned char *from = read_buf_addr(ldata, tail);
1971*4882a593Smuzhiyun memcpy(*kbp, from, n);
1972*4882a593Smuzhiyun is_eof = n == 1 && *from == EOF_CHAR(tty);
1973*4882a593Smuzhiyun tty_audit_add_data(tty, from, n);
1974*4882a593Smuzhiyun zero_buffer(tty, from, n);
1975*4882a593Smuzhiyun smp_store_release(&ldata->read_tail, ldata->read_tail + n);
1976*4882a593Smuzhiyun /* Turn single EOF into zero-length read */
1977*4882a593Smuzhiyun if (L_EXTPROC(tty) && ldata->icanon && is_eof &&
1978*4882a593Smuzhiyun (head == ldata->read_tail))
1979*4882a593Smuzhiyun return false;
1980*4882a593Smuzhiyun *kbp += n;
1981*4882a593Smuzhiyun *nr -= n;
1982*4882a593Smuzhiyun
1983*4882a593Smuzhiyun /* If we have more to copy, let the caller know */
1984*4882a593Smuzhiyun return head != ldata->read_tail;
1985*4882a593Smuzhiyun }
1986*4882a593Smuzhiyun return false;
1987*4882a593Smuzhiyun }
1988*4882a593Smuzhiyun
1989*4882a593Smuzhiyun /**
1990*4882a593Smuzhiyun * canon_copy_from_read_buf - copy read data in canonical mode
1991*4882a593Smuzhiyun * @tty: terminal device
1992*4882a593Smuzhiyun * @kbp: data
1993*4882a593Smuzhiyun * @nr: size of data
1994*4882a593Smuzhiyun *
1995*4882a593Smuzhiyun * Helper function for n_tty_read. It is only called when ICANON is on;
1996*4882a593Smuzhiyun * it copies one line of input up to and including the line-delimiting
1997*4882a593Smuzhiyun * character into the result buffer.
1998*4882a593Smuzhiyun *
1999*4882a593Smuzhiyun * NB: When termios is changed from non-canonical to canonical mode and
2000*4882a593Smuzhiyun * the read buffer contains data, n_tty_set_termios() simulates an EOF
2001*4882a593Smuzhiyun * push (as if C-d were input) _without_ the DISABLED_CHAR in the buffer.
2002*4882a593Smuzhiyun * This causes data already processed as input to be immediately available
2003*4882a593Smuzhiyun * as input although a newline has not been received.
2004*4882a593Smuzhiyun *
2005*4882a593Smuzhiyun * Called under the atomic_read_lock mutex
2006*4882a593Smuzhiyun *
2007*4882a593Smuzhiyun * n_tty_read()/consumer path:
2008*4882a593Smuzhiyun * caller holds non-exclusive termios_rwsem
2009*4882a593Smuzhiyun * read_tail published
2010*4882a593Smuzhiyun */
2011*4882a593Smuzhiyun
canon_copy_from_read_buf(struct tty_struct * tty,unsigned char ** kbp,size_t * nr)2012*4882a593Smuzhiyun static bool canon_copy_from_read_buf(struct tty_struct *tty,
2013*4882a593Smuzhiyun unsigned char **kbp,
2014*4882a593Smuzhiyun size_t *nr)
2015*4882a593Smuzhiyun {
2016*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
2017*4882a593Smuzhiyun size_t n, size, more, c;
2018*4882a593Smuzhiyun size_t eol;
2019*4882a593Smuzhiyun size_t tail, canon_head;
2020*4882a593Smuzhiyun int found = 0;
2021*4882a593Smuzhiyun
2022*4882a593Smuzhiyun /* N.B. avoid overrun if nr == 0 */
2023*4882a593Smuzhiyun if (!*nr)
2024*4882a593Smuzhiyun return false;
2025*4882a593Smuzhiyun
2026*4882a593Smuzhiyun canon_head = smp_load_acquire(&ldata->canon_head);
2027*4882a593Smuzhiyun n = min(*nr, canon_head - ldata->read_tail);
2028*4882a593Smuzhiyun
2029*4882a593Smuzhiyun tail = ldata->read_tail & (N_TTY_BUF_SIZE - 1);
2030*4882a593Smuzhiyun size = min_t(size_t, tail + n, N_TTY_BUF_SIZE);
2031*4882a593Smuzhiyun
2032*4882a593Smuzhiyun n_tty_trace("%s: nr:%zu tail:%zu n:%zu size:%zu\n",
2033*4882a593Smuzhiyun __func__, *nr, tail, n, size);
2034*4882a593Smuzhiyun
2035*4882a593Smuzhiyun eol = find_next_bit(ldata->read_flags, size, tail);
2036*4882a593Smuzhiyun more = n - (size - tail);
2037*4882a593Smuzhiyun if (eol == N_TTY_BUF_SIZE && more) {
2038*4882a593Smuzhiyun /* scan wrapped without finding set bit */
2039*4882a593Smuzhiyun eol = find_next_bit(ldata->read_flags, more, 0);
2040*4882a593Smuzhiyun found = eol != more;
2041*4882a593Smuzhiyun } else
2042*4882a593Smuzhiyun found = eol != size;
2043*4882a593Smuzhiyun
2044*4882a593Smuzhiyun n = eol - tail;
2045*4882a593Smuzhiyun if (n > N_TTY_BUF_SIZE)
2046*4882a593Smuzhiyun n += N_TTY_BUF_SIZE;
2047*4882a593Smuzhiyun c = n + found;
2048*4882a593Smuzhiyun
2049*4882a593Smuzhiyun if (!found || read_buf(ldata, eol) != __DISABLED_CHAR)
2050*4882a593Smuzhiyun n = c;
2051*4882a593Smuzhiyun
2052*4882a593Smuzhiyun n_tty_trace("%s: eol:%zu found:%d n:%zu c:%zu tail:%zu more:%zu\n",
2053*4882a593Smuzhiyun __func__, eol, found, n, c, tail, more);
2054*4882a593Smuzhiyun
2055*4882a593Smuzhiyun tty_copy(tty, *kbp, tail, n);
2056*4882a593Smuzhiyun *kbp += n;
2057*4882a593Smuzhiyun *nr -= n;
2058*4882a593Smuzhiyun
2059*4882a593Smuzhiyun if (found)
2060*4882a593Smuzhiyun clear_bit(eol, ldata->read_flags);
2061*4882a593Smuzhiyun smp_store_release(&ldata->read_tail, ldata->read_tail + c);
2062*4882a593Smuzhiyun
2063*4882a593Smuzhiyun if (found) {
2064*4882a593Smuzhiyun if (!ldata->push)
2065*4882a593Smuzhiyun ldata->line_start = ldata->read_tail;
2066*4882a593Smuzhiyun else
2067*4882a593Smuzhiyun ldata->push = 0;
2068*4882a593Smuzhiyun tty_audit_push();
2069*4882a593Smuzhiyun return false;
2070*4882a593Smuzhiyun }
2071*4882a593Smuzhiyun
2072*4882a593Smuzhiyun /* No EOL found - do a continuation retry if there is more data */
2073*4882a593Smuzhiyun return ldata->read_tail != canon_head;
2074*4882a593Smuzhiyun }
2075*4882a593Smuzhiyun
2076*4882a593Smuzhiyun /*
2077*4882a593Smuzhiyun * If we finished a read at the exact location of an
2078*4882a593Smuzhiyun * EOF (special EOL character that's a __DISABLED_CHAR)
2079*4882a593Smuzhiyun * in the stream, silently eat the EOF.
2080*4882a593Smuzhiyun */
canon_skip_eof(struct tty_struct * tty)2081*4882a593Smuzhiyun static void canon_skip_eof(struct tty_struct *tty)
2082*4882a593Smuzhiyun {
2083*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
2084*4882a593Smuzhiyun size_t tail, canon_head;
2085*4882a593Smuzhiyun
2086*4882a593Smuzhiyun canon_head = smp_load_acquire(&ldata->canon_head);
2087*4882a593Smuzhiyun tail = ldata->read_tail;
2088*4882a593Smuzhiyun
2089*4882a593Smuzhiyun // No data?
2090*4882a593Smuzhiyun if (tail == canon_head)
2091*4882a593Smuzhiyun return;
2092*4882a593Smuzhiyun
2093*4882a593Smuzhiyun // See if the tail position is EOF in the circular buffer
2094*4882a593Smuzhiyun tail &= (N_TTY_BUF_SIZE - 1);
2095*4882a593Smuzhiyun if (!test_bit(tail, ldata->read_flags))
2096*4882a593Smuzhiyun return;
2097*4882a593Smuzhiyun if (read_buf(ldata, tail) != __DISABLED_CHAR)
2098*4882a593Smuzhiyun return;
2099*4882a593Smuzhiyun
2100*4882a593Smuzhiyun // Clear the EOL bit, skip the EOF char.
2101*4882a593Smuzhiyun clear_bit(tail, ldata->read_flags);
2102*4882a593Smuzhiyun smp_store_release(&ldata->read_tail, ldata->read_tail + 1);
2103*4882a593Smuzhiyun }
2104*4882a593Smuzhiyun
2105*4882a593Smuzhiyun /**
2106*4882a593Smuzhiyun * job_control - check job control
2107*4882a593Smuzhiyun * @tty: tty
2108*4882a593Smuzhiyun * @file: file handle
2109*4882a593Smuzhiyun *
2110*4882a593Smuzhiyun * Perform job control management checks on this file/tty descriptor
2111*4882a593Smuzhiyun * and if appropriate send any needed signals and return a negative
2112*4882a593Smuzhiyun * error code if action should be taken.
2113*4882a593Smuzhiyun *
2114*4882a593Smuzhiyun * Locking: redirected write test is safe
2115*4882a593Smuzhiyun * current->signal->tty check is safe
2116*4882a593Smuzhiyun * ctrl_lock to safely reference tty->pgrp
2117*4882a593Smuzhiyun */
2118*4882a593Smuzhiyun
job_control(struct tty_struct * tty,struct file * file)2119*4882a593Smuzhiyun static int job_control(struct tty_struct *tty, struct file *file)
2120*4882a593Smuzhiyun {
2121*4882a593Smuzhiyun /* Job control check -- must be done at start and after
2122*4882a593Smuzhiyun every sleep (POSIX.1 7.1.1.4). */
2123*4882a593Smuzhiyun /* NOTE: not yet done after every sleep pending a thorough
2124*4882a593Smuzhiyun check of the logic of this change. -- jlc */
2125*4882a593Smuzhiyun /* don't stop on /dev/console */
2126*4882a593Smuzhiyun if (file->f_op->write_iter == redirected_tty_write)
2127*4882a593Smuzhiyun return 0;
2128*4882a593Smuzhiyun
2129*4882a593Smuzhiyun return __tty_check_change(tty, SIGTTIN);
2130*4882a593Smuzhiyun }
2131*4882a593Smuzhiyun
2132*4882a593Smuzhiyun
2133*4882a593Smuzhiyun /**
2134*4882a593Smuzhiyun * n_tty_read - read function for tty
2135*4882a593Smuzhiyun * @tty: tty device
2136*4882a593Smuzhiyun * @file: file object
2137*4882a593Smuzhiyun * @buf: userspace buffer pointer
2138*4882a593Smuzhiyun * @nr: size of I/O
2139*4882a593Smuzhiyun *
2140*4882a593Smuzhiyun * Perform reads for the line discipline. We are guaranteed that the
2141*4882a593Smuzhiyun * line discipline will not be closed under us but we may get multiple
2142*4882a593Smuzhiyun * parallel readers and must handle this ourselves. We may also get
2143*4882a593Smuzhiyun * a hangup. Always called in user context, may sleep.
2144*4882a593Smuzhiyun *
2145*4882a593Smuzhiyun * This code must be sure never to sleep through a hangup.
2146*4882a593Smuzhiyun *
2147*4882a593Smuzhiyun * n_tty_read()/consumer path:
2148*4882a593Smuzhiyun * claims non-exclusive termios_rwsem
2149*4882a593Smuzhiyun * publishes read_tail
2150*4882a593Smuzhiyun */
2151*4882a593Smuzhiyun
n_tty_read(struct tty_struct * tty,struct file * file,unsigned char * kbuf,size_t nr,void ** cookie,unsigned long offset)2152*4882a593Smuzhiyun static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
2153*4882a593Smuzhiyun unsigned char *kbuf, size_t nr,
2154*4882a593Smuzhiyun void **cookie, unsigned long offset)
2155*4882a593Smuzhiyun {
2156*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
2157*4882a593Smuzhiyun unsigned char *kb = kbuf;
2158*4882a593Smuzhiyun DEFINE_WAIT_FUNC(wait, woken_wake_function);
2159*4882a593Smuzhiyun int c;
2160*4882a593Smuzhiyun int minimum, time;
2161*4882a593Smuzhiyun ssize_t retval = 0;
2162*4882a593Smuzhiyun long timeout;
2163*4882a593Smuzhiyun int packet;
2164*4882a593Smuzhiyun size_t tail;
2165*4882a593Smuzhiyun
2166*4882a593Smuzhiyun /*
2167*4882a593Smuzhiyun * Is this a continuation of a read started earler?
2168*4882a593Smuzhiyun *
2169*4882a593Smuzhiyun * If so, we still hold the atomic_read_lock and the
2170*4882a593Smuzhiyun * termios_rwsem, and can just continue to copy data.
2171*4882a593Smuzhiyun */
2172*4882a593Smuzhiyun if (*cookie) {
2173*4882a593Smuzhiyun if (ldata->icanon && !L_EXTPROC(tty)) {
2174*4882a593Smuzhiyun /*
2175*4882a593Smuzhiyun * If we have filled the user buffer, see
2176*4882a593Smuzhiyun * if we should skip an EOF character before
2177*4882a593Smuzhiyun * releasing the lock and returning done.
2178*4882a593Smuzhiyun */
2179*4882a593Smuzhiyun if (!nr)
2180*4882a593Smuzhiyun canon_skip_eof(tty);
2181*4882a593Smuzhiyun else if (canon_copy_from_read_buf(tty, &kb, &nr))
2182*4882a593Smuzhiyun return kb - kbuf;
2183*4882a593Smuzhiyun } else {
2184*4882a593Smuzhiyun if (copy_from_read_buf(tty, &kb, &nr))
2185*4882a593Smuzhiyun return kb - kbuf;
2186*4882a593Smuzhiyun }
2187*4882a593Smuzhiyun
2188*4882a593Smuzhiyun /* No more data - release locks and stop retries */
2189*4882a593Smuzhiyun n_tty_kick_worker(tty);
2190*4882a593Smuzhiyun n_tty_check_unthrottle(tty);
2191*4882a593Smuzhiyun up_read(&tty->termios_rwsem);
2192*4882a593Smuzhiyun mutex_unlock(&ldata->atomic_read_lock);
2193*4882a593Smuzhiyun *cookie = NULL;
2194*4882a593Smuzhiyun return kb - kbuf;
2195*4882a593Smuzhiyun }
2196*4882a593Smuzhiyun
2197*4882a593Smuzhiyun c = job_control(tty, file);
2198*4882a593Smuzhiyun if (c < 0)
2199*4882a593Smuzhiyun return c;
2200*4882a593Smuzhiyun
2201*4882a593Smuzhiyun /*
2202*4882a593Smuzhiyun * Internal serialization of reads.
2203*4882a593Smuzhiyun */
2204*4882a593Smuzhiyun if (file->f_flags & O_NONBLOCK) {
2205*4882a593Smuzhiyun if (!mutex_trylock(&ldata->atomic_read_lock))
2206*4882a593Smuzhiyun return -EAGAIN;
2207*4882a593Smuzhiyun } else {
2208*4882a593Smuzhiyun if (mutex_lock_interruptible(&ldata->atomic_read_lock))
2209*4882a593Smuzhiyun return -ERESTARTSYS;
2210*4882a593Smuzhiyun }
2211*4882a593Smuzhiyun
2212*4882a593Smuzhiyun down_read(&tty->termios_rwsem);
2213*4882a593Smuzhiyun
2214*4882a593Smuzhiyun minimum = time = 0;
2215*4882a593Smuzhiyun timeout = MAX_SCHEDULE_TIMEOUT;
2216*4882a593Smuzhiyun if (!ldata->icanon) {
2217*4882a593Smuzhiyun minimum = MIN_CHAR(tty);
2218*4882a593Smuzhiyun if (minimum) {
2219*4882a593Smuzhiyun time = (HZ / 10) * TIME_CHAR(tty);
2220*4882a593Smuzhiyun } else {
2221*4882a593Smuzhiyun timeout = (HZ / 10) * TIME_CHAR(tty);
2222*4882a593Smuzhiyun minimum = 1;
2223*4882a593Smuzhiyun }
2224*4882a593Smuzhiyun }
2225*4882a593Smuzhiyun
2226*4882a593Smuzhiyun packet = tty->packet;
2227*4882a593Smuzhiyun tail = ldata->read_tail;
2228*4882a593Smuzhiyun
2229*4882a593Smuzhiyun add_wait_queue(&tty->read_wait, &wait);
2230*4882a593Smuzhiyun while (nr) {
2231*4882a593Smuzhiyun /* First test for status change. */
2232*4882a593Smuzhiyun if (packet && tty->link->ctrl_status) {
2233*4882a593Smuzhiyun unsigned char cs;
2234*4882a593Smuzhiyun if (kb != kbuf)
2235*4882a593Smuzhiyun break;
2236*4882a593Smuzhiyun spin_lock_irq(&tty->link->ctrl_lock);
2237*4882a593Smuzhiyun cs = tty->link->ctrl_status;
2238*4882a593Smuzhiyun tty->link->ctrl_status = 0;
2239*4882a593Smuzhiyun spin_unlock_irq(&tty->link->ctrl_lock);
2240*4882a593Smuzhiyun *kb++ = cs;
2241*4882a593Smuzhiyun nr--;
2242*4882a593Smuzhiyun break;
2243*4882a593Smuzhiyun }
2244*4882a593Smuzhiyun
2245*4882a593Smuzhiyun if (!input_available_p(tty, 0)) {
2246*4882a593Smuzhiyun up_read(&tty->termios_rwsem);
2247*4882a593Smuzhiyun tty_buffer_flush_work(tty->port);
2248*4882a593Smuzhiyun down_read(&tty->termios_rwsem);
2249*4882a593Smuzhiyun if (!input_available_p(tty, 0)) {
2250*4882a593Smuzhiyun if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
2251*4882a593Smuzhiyun retval = -EIO;
2252*4882a593Smuzhiyun break;
2253*4882a593Smuzhiyun }
2254*4882a593Smuzhiyun if (tty_hung_up_p(file))
2255*4882a593Smuzhiyun break;
2256*4882a593Smuzhiyun /*
2257*4882a593Smuzhiyun * Abort readers for ttys which never actually
2258*4882a593Smuzhiyun * get hung up. See __tty_hangup().
2259*4882a593Smuzhiyun */
2260*4882a593Smuzhiyun if (test_bit(TTY_HUPPING, &tty->flags))
2261*4882a593Smuzhiyun break;
2262*4882a593Smuzhiyun if (!timeout)
2263*4882a593Smuzhiyun break;
2264*4882a593Smuzhiyun if (tty_io_nonblock(tty, file)) {
2265*4882a593Smuzhiyun retval = -EAGAIN;
2266*4882a593Smuzhiyun break;
2267*4882a593Smuzhiyun }
2268*4882a593Smuzhiyun if (signal_pending(current)) {
2269*4882a593Smuzhiyun retval = -ERESTARTSYS;
2270*4882a593Smuzhiyun break;
2271*4882a593Smuzhiyun }
2272*4882a593Smuzhiyun up_read(&tty->termios_rwsem);
2273*4882a593Smuzhiyun
2274*4882a593Smuzhiyun timeout = wait_woken(&wait, TASK_INTERRUPTIBLE,
2275*4882a593Smuzhiyun timeout);
2276*4882a593Smuzhiyun
2277*4882a593Smuzhiyun down_read(&tty->termios_rwsem);
2278*4882a593Smuzhiyun continue;
2279*4882a593Smuzhiyun }
2280*4882a593Smuzhiyun }
2281*4882a593Smuzhiyun
2282*4882a593Smuzhiyun if (ldata->icanon && !L_EXTPROC(tty)) {
2283*4882a593Smuzhiyun if (canon_copy_from_read_buf(tty, &kb, &nr))
2284*4882a593Smuzhiyun goto more_to_be_read;
2285*4882a593Smuzhiyun } else {
2286*4882a593Smuzhiyun /* Deal with packet mode. */
2287*4882a593Smuzhiyun if (packet && kb == kbuf) {
2288*4882a593Smuzhiyun *kb++ = TIOCPKT_DATA;
2289*4882a593Smuzhiyun nr--;
2290*4882a593Smuzhiyun }
2291*4882a593Smuzhiyun
2292*4882a593Smuzhiyun /*
2293*4882a593Smuzhiyun * Copy data, and if there is more to be had
2294*4882a593Smuzhiyun * and we have nothing more to wait for, then
2295*4882a593Smuzhiyun * let's mark us for retries.
2296*4882a593Smuzhiyun *
2297*4882a593Smuzhiyun * NOTE! We return here with both the termios_sem
2298*4882a593Smuzhiyun * and atomic_read_lock still held, the retries
2299*4882a593Smuzhiyun * will release them when done.
2300*4882a593Smuzhiyun */
2301*4882a593Smuzhiyun if (copy_from_read_buf(tty, &kb, &nr) && kb - kbuf >= minimum) {
2302*4882a593Smuzhiyun more_to_be_read:
2303*4882a593Smuzhiyun remove_wait_queue(&tty->read_wait, &wait);
2304*4882a593Smuzhiyun *cookie = cookie;
2305*4882a593Smuzhiyun return kb - kbuf;
2306*4882a593Smuzhiyun }
2307*4882a593Smuzhiyun }
2308*4882a593Smuzhiyun
2309*4882a593Smuzhiyun n_tty_check_unthrottle(tty);
2310*4882a593Smuzhiyun
2311*4882a593Smuzhiyun if (kb - kbuf >= minimum)
2312*4882a593Smuzhiyun break;
2313*4882a593Smuzhiyun if (time)
2314*4882a593Smuzhiyun timeout = time;
2315*4882a593Smuzhiyun }
2316*4882a593Smuzhiyun if (tail != ldata->read_tail)
2317*4882a593Smuzhiyun n_tty_kick_worker(tty);
2318*4882a593Smuzhiyun up_read(&tty->termios_rwsem);
2319*4882a593Smuzhiyun
2320*4882a593Smuzhiyun remove_wait_queue(&tty->read_wait, &wait);
2321*4882a593Smuzhiyun mutex_unlock(&ldata->atomic_read_lock);
2322*4882a593Smuzhiyun
2323*4882a593Smuzhiyun if (kb - kbuf)
2324*4882a593Smuzhiyun retval = kb - kbuf;
2325*4882a593Smuzhiyun
2326*4882a593Smuzhiyun return retval;
2327*4882a593Smuzhiyun }
2328*4882a593Smuzhiyun
2329*4882a593Smuzhiyun /**
2330*4882a593Smuzhiyun * n_tty_write - write function for tty
2331*4882a593Smuzhiyun * @tty: tty device
2332*4882a593Smuzhiyun * @file: file object
2333*4882a593Smuzhiyun * @buf: userspace buffer pointer
2334*4882a593Smuzhiyun * @nr: size of I/O
2335*4882a593Smuzhiyun *
2336*4882a593Smuzhiyun * Write function of the terminal device. This is serialized with
2337*4882a593Smuzhiyun * respect to other write callers but not to termios changes, reads
2338*4882a593Smuzhiyun * and other such events. Since the receive code will echo characters,
2339*4882a593Smuzhiyun * thus calling driver write methods, the output_lock is used in
2340*4882a593Smuzhiyun * the output processing functions called here as well as in the
2341*4882a593Smuzhiyun * echo processing function to protect the column state and space
2342*4882a593Smuzhiyun * left in the buffer.
2343*4882a593Smuzhiyun *
2344*4882a593Smuzhiyun * This code must be sure never to sleep through a hangup.
2345*4882a593Smuzhiyun *
2346*4882a593Smuzhiyun * Locking: output_lock to protect column state and space left
2347*4882a593Smuzhiyun * (note that the process_output*() functions take this
2348*4882a593Smuzhiyun * lock themselves)
2349*4882a593Smuzhiyun */
2350*4882a593Smuzhiyun
n_tty_write(struct tty_struct * tty,struct file * file,const unsigned char * buf,size_t nr)2351*4882a593Smuzhiyun static ssize_t n_tty_write(struct tty_struct *tty, struct file *file,
2352*4882a593Smuzhiyun const unsigned char *buf, size_t nr)
2353*4882a593Smuzhiyun {
2354*4882a593Smuzhiyun const unsigned char *b = buf;
2355*4882a593Smuzhiyun DEFINE_WAIT_FUNC(wait, woken_wake_function);
2356*4882a593Smuzhiyun int c;
2357*4882a593Smuzhiyun ssize_t retval = 0;
2358*4882a593Smuzhiyun
2359*4882a593Smuzhiyun /* Job control check -- must be done at start (POSIX.1 7.1.1.4). */
2360*4882a593Smuzhiyun if (L_TOSTOP(tty) && file->f_op->write_iter != redirected_tty_write) {
2361*4882a593Smuzhiyun retval = tty_check_change(tty);
2362*4882a593Smuzhiyun if (retval)
2363*4882a593Smuzhiyun return retval;
2364*4882a593Smuzhiyun }
2365*4882a593Smuzhiyun
2366*4882a593Smuzhiyun down_read(&tty->termios_rwsem);
2367*4882a593Smuzhiyun
2368*4882a593Smuzhiyun /* Write out any echoed characters that are still pending */
2369*4882a593Smuzhiyun process_echoes(tty);
2370*4882a593Smuzhiyun
2371*4882a593Smuzhiyun add_wait_queue(&tty->write_wait, &wait);
2372*4882a593Smuzhiyun while (1) {
2373*4882a593Smuzhiyun if (signal_pending(current)) {
2374*4882a593Smuzhiyun retval = -ERESTARTSYS;
2375*4882a593Smuzhiyun break;
2376*4882a593Smuzhiyun }
2377*4882a593Smuzhiyun if (tty_hung_up_p(file) || (tty->link && !tty->link->count)) {
2378*4882a593Smuzhiyun retval = -EIO;
2379*4882a593Smuzhiyun break;
2380*4882a593Smuzhiyun }
2381*4882a593Smuzhiyun if (O_OPOST(tty)) {
2382*4882a593Smuzhiyun while (nr > 0) {
2383*4882a593Smuzhiyun ssize_t num = process_output_block(tty, b, nr);
2384*4882a593Smuzhiyun if (num < 0) {
2385*4882a593Smuzhiyun if (num == -EAGAIN)
2386*4882a593Smuzhiyun break;
2387*4882a593Smuzhiyun retval = num;
2388*4882a593Smuzhiyun goto break_out;
2389*4882a593Smuzhiyun }
2390*4882a593Smuzhiyun b += num;
2391*4882a593Smuzhiyun nr -= num;
2392*4882a593Smuzhiyun if (nr == 0)
2393*4882a593Smuzhiyun break;
2394*4882a593Smuzhiyun c = *b;
2395*4882a593Smuzhiyun if (process_output(c, tty) < 0)
2396*4882a593Smuzhiyun break;
2397*4882a593Smuzhiyun b++; nr--;
2398*4882a593Smuzhiyun }
2399*4882a593Smuzhiyun if (tty->ops->flush_chars)
2400*4882a593Smuzhiyun tty->ops->flush_chars(tty);
2401*4882a593Smuzhiyun } else {
2402*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
2403*4882a593Smuzhiyun
2404*4882a593Smuzhiyun while (nr > 0) {
2405*4882a593Smuzhiyun mutex_lock(&ldata->output_lock);
2406*4882a593Smuzhiyun c = tty->ops->write(tty, b, nr);
2407*4882a593Smuzhiyun mutex_unlock(&ldata->output_lock);
2408*4882a593Smuzhiyun if (c < 0) {
2409*4882a593Smuzhiyun retval = c;
2410*4882a593Smuzhiyun goto break_out;
2411*4882a593Smuzhiyun }
2412*4882a593Smuzhiyun if (!c)
2413*4882a593Smuzhiyun break;
2414*4882a593Smuzhiyun b += c;
2415*4882a593Smuzhiyun nr -= c;
2416*4882a593Smuzhiyun }
2417*4882a593Smuzhiyun }
2418*4882a593Smuzhiyun if (!nr)
2419*4882a593Smuzhiyun break;
2420*4882a593Smuzhiyun if (tty_io_nonblock(tty, file)) {
2421*4882a593Smuzhiyun retval = -EAGAIN;
2422*4882a593Smuzhiyun break;
2423*4882a593Smuzhiyun }
2424*4882a593Smuzhiyun up_read(&tty->termios_rwsem);
2425*4882a593Smuzhiyun
2426*4882a593Smuzhiyun wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT);
2427*4882a593Smuzhiyun
2428*4882a593Smuzhiyun down_read(&tty->termios_rwsem);
2429*4882a593Smuzhiyun }
2430*4882a593Smuzhiyun break_out:
2431*4882a593Smuzhiyun remove_wait_queue(&tty->write_wait, &wait);
2432*4882a593Smuzhiyun if (nr && tty->fasync)
2433*4882a593Smuzhiyun set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
2434*4882a593Smuzhiyun up_read(&tty->termios_rwsem);
2435*4882a593Smuzhiyun return (b - buf) ? b - buf : retval;
2436*4882a593Smuzhiyun }
2437*4882a593Smuzhiyun
2438*4882a593Smuzhiyun /**
2439*4882a593Smuzhiyun * n_tty_poll - poll method for N_TTY
2440*4882a593Smuzhiyun * @tty: terminal device
2441*4882a593Smuzhiyun * @file: file accessing it
2442*4882a593Smuzhiyun * @wait: poll table
2443*4882a593Smuzhiyun *
2444*4882a593Smuzhiyun * Called when the line discipline is asked to poll() for data or
2445*4882a593Smuzhiyun * for special events. This code is not serialized with respect to
2446*4882a593Smuzhiyun * other events save open/close.
2447*4882a593Smuzhiyun *
2448*4882a593Smuzhiyun * This code must be sure never to sleep through a hangup.
2449*4882a593Smuzhiyun * Called without the kernel lock held - fine
2450*4882a593Smuzhiyun */
2451*4882a593Smuzhiyun
n_tty_poll(struct tty_struct * tty,struct file * file,poll_table * wait)2452*4882a593Smuzhiyun static __poll_t n_tty_poll(struct tty_struct *tty, struct file *file,
2453*4882a593Smuzhiyun poll_table *wait)
2454*4882a593Smuzhiyun {
2455*4882a593Smuzhiyun __poll_t mask = 0;
2456*4882a593Smuzhiyun
2457*4882a593Smuzhiyun poll_wait(file, &tty->read_wait, wait);
2458*4882a593Smuzhiyun poll_wait(file, &tty->write_wait, wait);
2459*4882a593Smuzhiyun if (input_available_p(tty, 1))
2460*4882a593Smuzhiyun mask |= EPOLLIN | EPOLLRDNORM;
2461*4882a593Smuzhiyun else {
2462*4882a593Smuzhiyun tty_buffer_flush_work(tty->port);
2463*4882a593Smuzhiyun if (input_available_p(tty, 1))
2464*4882a593Smuzhiyun mask |= EPOLLIN | EPOLLRDNORM;
2465*4882a593Smuzhiyun }
2466*4882a593Smuzhiyun if (tty->packet && tty->link->ctrl_status)
2467*4882a593Smuzhiyun mask |= EPOLLPRI | EPOLLIN | EPOLLRDNORM;
2468*4882a593Smuzhiyun if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
2469*4882a593Smuzhiyun mask |= EPOLLHUP;
2470*4882a593Smuzhiyun if (tty_hung_up_p(file))
2471*4882a593Smuzhiyun mask |= EPOLLHUP;
2472*4882a593Smuzhiyun if (tty->ops->write && !tty_is_writelocked(tty) &&
2473*4882a593Smuzhiyun tty_chars_in_buffer(tty) < WAKEUP_CHARS &&
2474*4882a593Smuzhiyun tty_write_room(tty) > 0)
2475*4882a593Smuzhiyun mask |= EPOLLOUT | EPOLLWRNORM;
2476*4882a593Smuzhiyun return mask;
2477*4882a593Smuzhiyun }
2478*4882a593Smuzhiyun
inq_canon(struct n_tty_data * ldata)2479*4882a593Smuzhiyun static unsigned long inq_canon(struct n_tty_data *ldata)
2480*4882a593Smuzhiyun {
2481*4882a593Smuzhiyun size_t nr, head, tail;
2482*4882a593Smuzhiyun
2483*4882a593Smuzhiyun if (ldata->canon_head == ldata->read_tail)
2484*4882a593Smuzhiyun return 0;
2485*4882a593Smuzhiyun head = ldata->canon_head;
2486*4882a593Smuzhiyun tail = ldata->read_tail;
2487*4882a593Smuzhiyun nr = head - tail;
2488*4882a593Smuzhiyun /* Skip EOF-chars.. */
2489*4882a593Smuzhiyun while (MASK(head) != MASK(tail)) {
2490*4882a593Smuzhiyun if (test_bit(tail & (N_TTY_BUF_SIZE - 1), ldata->read_flags) &&
2491*4882a593Smuzhiyun read_buf(ldata, tail) == __DISABLED_CHAR)
2492*4882a593Smuzhiyun nr--;
2493*4882a593Smuzhiyun tail++;
2494*4882a593Smuzhiyun }
2495*4882a593Smuzhiyun return nr;
2496*4882a593Smuzhiyun }
2497*4882a593Smuzhiyun
n_tty_ioctl(struct tty_struct * tty,struct file * file,unsigned int cmd,unsigned long arg)2498*4882a593Smuzhiyun static int n_tty_ioctl(struct tty_struct *tty, struct file *file,
2499*4882a593Smuzhiyun unsigned int cmd, unsigned long arg)
2500*4882a593Smuzhiyun {
2501*4882a593Smuzhiyun struct n_tty_data *ldata = tty->disc_data;
2502*4882a593Smuzhiyun int retval;
2503*4882a593Smuzhiyun
2504*4882a593Smuzhiyun switch (cmd) {
2505*4882a593Smuzhiyun case TIOCOUTQ:
2506*4882a593Smuzhiyun return put_user(tty_chars_in_buffer(tty), (int __user *) arg);
2507*4882a593Smuzhiyun case TIOCINQ:
2508*4882a593Smuzhiyun down_write(&tty->termios_rwsem);
2509*4882a593Smuzhiyun if (L_ICANON(tty) && !L_EXTPROC(tty))
2510*4882a593Smuzhiyun retval = inq_canon(ldata);
2511*4882a593Smuzhiyun else
2512*4882a593Smuzhiyun retval = read_cnt(ldata);
2513*4882a593Smuzhiyun up_write(&tty->termios_rwsem);
2514*4882a593Smuzhiyun return put_user(retval, (unsigned int __user *) arg);
2515*4882a593Smuzhiyun default:
2516*4882a593Smuzhiyun return n_tty_ioctl_helper(tty, file, cmd, arg);
2517*4882a593Smuzhiyun }
2518*4882a593Smuzhiyun }
2519*4882a593Smuzhiyun
2520*4882a593Smuzhiyun static struct tty_ldisc_ops n_tty_ops = {
2521*4882a593Smuzhiyun .magic = TTY_LDISC_MAGIC,
2522*4882a593Smuzhiyun .name = "n_tty",
2523*4882a593Smuzhiyun .open = n_tty_open,
2524*4882a593Smuzhiyun .close = n_tty_close,
2525*4882a593Smuzhiyun .flush_buffer = n_tty_flush_buffer,
2526*4882a593Smuzhiyun .read = n_tty_read,
2527*4882a593Smuzhiyun .write = n_tty_write,
2528*4882a593Smuzhiyun .ioctl = n_tty_ioctl,
2529*4882a593Smuzhiyun .set_termios = n_tty_set_termios,
2530*4882a593Smuzhiyun .poll = n_tty_poll,
2531*4882a593Smuzhiyun .receive_buf = n_tty_receive_buf,
2532*4882a593Smuzhiyun .write_wakeup = n_tty_write_wakeup,
2533*4882a593Smuzhiyun .receive_buf2 = n_tty_receive_buf2,
2534*4882a593Smuzhiyun };
2535*4882a593Smuzhiyun
2536*4882a593Smuzhiyun /**
2537*4882a593Smuzhiyun * n_tty_inherit_ops - inherit N_TTY methods
2538*4882a593Smuzhiyun * @ops: struct tty_ldisc_ops where to save N_TTY methods
2539*4882a593Smuzhiyun *
2540*4882a593Smuzhiyun * Enables a 'subclass' line discipline to 'inherit' N_TTY methods.
2541*4882a593Smuzhiyun */
2542*4882a593Smuzhiyun
n_tty_inherit_ops(struct tty_ldisc_ops * ops)2543*4882a593Smuzhiyun void n_tty_inherit_ops(struct tty_ldisc_ops *ops)
2544*4882a593Smuzhiyun {
2545*4882a593Smuzhiyun *ops = n_tty_ops;
2546*4882a593Smuzhiyun ops->owner = NULL;
2547*4882a593Smuzhiyun ops->refcount = ops->flags = 0;
2548*4882a593Smuzhiyun }
2549*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(n_tty_inherit_ops);
2550*4882a593Smuzhiyun
n_tty_init(void)2551*4882a593Smuzhiyun void __init n_tty_init(void)
2552*4882a593Smuzhiyun {
2553*4882a593Smuzhiyun tty_register_ldisc(N_TTY, &n_tty_ops);
2554*4882a593Smuzhiyun }
2555