1// SPDX-License-Identifier: GPL-2.0
2#include <linux/types.h>
3#include <linux/tty.h>
4#include <linux/tty_flip.h>
5#include <linux/slab.h>
6
7#include "speakup.h"
8#include "spk_types.h"
9#include "spk_priv.h"
10
11struct spk_ldisc_data {
12	char buf;
13	struct completion completion;
14	bool buf_free;
15};
16
17static struct spk_synth *spk_ttyio_synth;
18static struct tty_struct *speakup_tty;
19/* mutex to protect against speakup_tty disappearing from underneath us while
20 * we are using it. this can happen when the device physically unplugged,
21 * while in use. it also serialises access to speakup_tty.
22 */
23static DEFINE_MUTEX(speakup_tty_mutex);
24
25static int ser_to_dev(int ser, dev_t *dev_no)
26{
27	if (ser < 0 || ser > (255 - 64)) {
28		pr_err("speakup: Invalid ser param. Must be between 0 and 191 inclusive.\n");
29		return -EINVAL;
30	}
31
32	*dev_no = MKDEV(4, (64 + ser));
33	return 0;
34}
35
36static int get_dev_to_use(struct spk_synth *synth, dev_t *dev_no)
37{
38	/* use ser only when dev is not specified */
39	if (strcmp(synth->dev_name, SYNTH_DEFAULT_DEV) ||
40	    synth->ser == SYNTH_DEFAULT_SER)
41		return tty_dev_name_to_number(synth->dev_name, dev_no);
42
43	return ser_to_dev(synth->ser, dev_no);
44}
45
46static int spk_ttyio_ldisc_open(struct tty_struct *tty)
47{
48	struct spk_ldisc_data *ldisc_data;
49
50	if (tty != speakup_tty)
51		/* Somebody tried to use this line discipline outside speakup */
52		return -ENODEV;
53
54	if (!tty->ops->write)
55		return -EOPNOTSUPP;
56
57	ldisc_data = kmalloc(sizeof(*ldisc_data), GFP_KERNEL);
58	if (!ldisc_data)
59		return -ENOMEM;
60
61	init_completion(&ldisc_data->completion);
62	ldisc_data->buf_free = true;
63	tty->disc_data = ldisc_data;
64
65	return 0;
66}
67
68static void spk_ttyio_ldisc_close(struct tty_struct *tty)
69{
70	mutex_lock(&speakup_tty_mutex);
71	kfree(speakup_tty->disc_data);
72	speakup_tty = NULL;
73	mutex_unlock(&speakup_tty_mutex);
74}
75
76static int spk_ttyio_receive_buf2(struct tty_struct *tty,
77				  const unsigned char *cp, char *fp, int count)
78{
79	struct spk_ldisc_data *ldisc_data = tty->disc_data;
80
81	if (spk_ttyio_synth->read_buff_add) {
82		int i;
83
84		for (i = 0; i < count; i++)
85			spk_ttyio_synth->read_buff_add(cp[i]);
86
87		return count;
88	}
89
90	if (!ldisc_data->buf_free)
91		/* ttyio_in will tty_flip_buffer_push */
92		return 0;
93
94	/* Make sure the consumer has read buf before we have seen
95	 * buf_free == true and overwrite buf
96	 */
97	mb();
98
99	ldisc_data->buf = cp[0];
100	ldisc_data->buf_free = false;
101	complete(&ldisc_data->completion);
102
103	return 1;
104}
105
106static struct tty_ldisc_ops spk_ttyio_ldisc_ops = {
107	.owner          = THIS_MODULE,
108	.magic          = TTY_LDISC_MAGIC,
109	.name           = "speakup_ldisc",
110	.open           = spk_ttyio_ldisc_open,
111	.close          = spk_ttyio_ldisc_close,
112	.receive_buf2	= spk_ttyio_receive_buf2,
113};
114
115static int spk_ttyio_out(struct spk_synth *in_synth, const char ch);
116static int spk_ttyio_out_unicode(struct spk_synth *in_synth, u16 ch);
117static void spk_ttyio_send_xchar(char ch);
118static void spk_ttyio_tiocmset(unsigned int set, unsigned int clear);
119static unsigned char spk_ttyio_in(void);
120static unsigned char spk_ttyio_in_nowait(void);
121static void spk_ttyio_flush_buffer(void);
122static int spk_ttyio_wait_for_xmitr(struct spk_synth *in_synth);
123
124struct spk_io_ops spk_ttyio_ops = {
125	.synth_out = spk_ttyio_out,
126	.synth_out_unicode = spk_ttyio_out_unicode,
127	.send_xchar = spk_ttyio_send_xchar,
128	.tiocmset = spk_ttyio_tiocmset,
129	.synth_in = spk_ttyio_in,
130	.synth_in_nowait = spk_ttyio_in_nowait,
131	.flush_buffer = spk_ttyio_flush_buffer,
132	.wait_for_xmitr = spk_ttyio_wait_for_xmitr,
133};
134EXPORT_SYMBOL_GPL(spk_ttyio_ops);
135
136static inline void get_termios(struct tty_struct *tty,
137			       struct ktermios *out_termios)
138{
139	down_read(&tty->termios_rwsem);
140	*out_termios = tty->termios;
141	up_read(&tty->termios_rwsem);
142}
143
144static int spk_ttyio_initialise_ldisc(struct spk_synth *synth)
145{
146	int ret = 0;
147	struct tty_struct *tty;
148	struct ktermios tmp_termios;
149	dev_t dev;
150
151	ret = get_dev_to_use(synth, &dev);
152	if (ret)
153		return ret;
154
155	tty = tty_kopen(dev);
156	if (IS_ERR(tty))
157		return PTR_ERR(tty);
158
159	if (tty->ops->open)
160		ret = tty->ops->open(tty, NULL);
161	else
162		ret = -ENODEV;
163
164	if (ret) {
165		tty_unlock(tty);
166		return ret;
167	}
168
169	clear_bit(TTY_HUPPED, &tty->flags);
170	/* ensure hardware flow control is enabled */
171	get_termios(tty, &tmp_termios);
172	if (!(tmp_termios.c_cflag & CRTSCTS)) {
173		tmp_termios.c_cflag |= CRTSCTS;
174		tty_set_termios(tty, &tmp_termios);
175		/*
176		 * check c_cflag to see if it's updated as tty_set_termios
177		 * may not return error even when no tty bits are
178		 * changed by the request.
179		 */
180		get_termios(tty, &tmp_termios);
181		if (!(tmp_termios.c_cflag & CRTSCTS))
182			pr_warn("speakup: Failed to set hardware flow control\n");
183	}
184
185	tty_unlock(tty);
186
187	mutex_lock(&speakup_tty_mutex);
188	speakup_tty = tty;
189	ret = tty_set_ldisc(tty, N_SPEAKUP);
190	if (ret)
191		speakup_tty = NULL;
192	mutex_unlock(&speakup_tty_mutex);
193
194	if (!ret)
195		/* Success */
196		return 0;
197
198	pr_err("speakup: Failed to set N_SPEAKUP on tty\n");
199
200	tty_lock(tty);
201	if (tty->ops->close)
202		tty->ops->close(tty, NULL);
203	tty_unlock(tty);
204
205	tty_kclose(tty);
206
207	return ret;
208}
209
210void spk_ttyio_register_ldisc(void)
211{
212	if (tty_register_ldisc(N_SPEAKUP, &spk_ttyio_ldisc_ops))
213		pr_warn("speakup: Error registering line discipline. Most synths won't work.\n");
214}
215
216void spk_ttyio_unregister_ldisc(void)
217{
218	if (tty_unregister_ldisc(N_SPEAKUP))
219		pr_warn("speakup: Couldn't unregister ldisc\n");
220}
221
222static int spk_ttyio_out(struct spk_synth *in_synth, const char ch)
223{
224	mutex_lock(&speakup_tty_mutex);
225	if (in_synth->alive && speakup_tty && speakup_tty->ops->write) {
226		int ret = speakup_tty->ops->write(speakup_tty, &ch, 1);
227
228		mutex_unlock(&speakup_tty_mutex);
229		if (ret == 0)
230			/* No room */
231			return 0;
232		if (ret < 0) {
233			pr_warn("%s: I/O error, deactivating speakup\n",
234				in_synth->long_name);
235			/* No synth any more, so nobody will restart TTYs,
236			 * and we thus need to do it ourselves.  Now that there
237			 * is no synth we can let application flood anyway
238			 */
239			in_synth->alive = 0;
240			speakup_start_ttys();
241			return 0;
242		}
243		return 1;
244	}
245
246	mutex_unlock(&speakup_tty_mutex);
247	return 0;
248}
249
250static int spk_ttyio_out_unicode(struct spk_synth *in_synth, u16 ch)
251{
252	int ret;
253
254	if (ch < 0x80) {
255		ret = spk_ttyio_out(in_synth, ch);
256	} else if (ch < 0x800) {
257		ret  = spk_ttyio_out(in_synth, 0xc0 | (ch >> 6));
258		ret &= spk_ttyio_out(in_synth, 0x80 | (ch & 0x3f));
259	} else {
260		ret  = spk_ttyio_out(in_synth, 0xe0 | (ch >> 12));
261		ret &= spk_ttyio_out(in_synth, 0x80 | ((ch >> 6) & 0x3f));
262		ret &= spk_ttyio_out(in_synth, 0x80 | (ch & 0x3f));
263	}
264	return ret;
265}
266
267static int check_tty(struct tty_struct *tty)
268{
269	if (!tty) {
270		pr_warn("%s: I/O error, deactivating speakup\n",
271			spk_ttyio_synth->long_name);
272		/* No synth any more, so nobody will restart TTYs, and we thus
273		 * need to do it ourselves.  Now that there is no synth we can
274		 * let application flood anyway
275		 */
276		spk_ttyio_synth->alive = 0;
277		speakup_start_ttys();
278		return 1;
279	}
280
281	return 0;
282}
283
284static void spk_ttyio_send_xchar(char ch)
285{
286	mutex_lock(&speakup_tty_mutex);
287	if (check_tty(speakup_tty)) {
288		mutex_unlock(&speakup_tty_mutex);
289		return;
290	}
291
292	if (speakup_tty->ops->send_xchar)
293		speakup_tty->ops->send_xchar(speakup_tty, ch);
294	mutex_unlock(&speakup_tty_mutex);
295}
296
297static void spk_ttyio_tiocmset(unsigned int set, unsigned int clear)
298{
299	mutex_lock(&speakup_tty_mutex);
300	if (check_tty(speakup_tty)) {
301		mutex_unlock(&speakup_tty_mutex);
302		return;
303	}
304
305	if (speakup_tty->ops->tiocmset)
306		speakup_tty->ops->tiocmset(speakup_tty, set, clear);
307	mutex_unlock(&speakup_tty_mutex);
308}
309
310static int spk_ttyio_wait_for_xmitr(struct spk_synth *in_synth)
311{
312	return 1;
313}
314
315static unsigned char ttyio_in(int timeout)
316{
317	struct spk_ldisc_data *ldisc_data = speakup_tty->disc_data;
318	char rv;
319
320	if (!timeout) {
321		if (!try_wait_for_completion(&ldisc_data->completion))
322			return 0xff;
323	} else if (wait_for_completion_timeout(&ldisc_data->completion,
324					usecs_to_jiffies(timeout)) == 0) {
325		pr_warn("spk_ttyio: timeout (%d)  while waiting for input\n",
326			timeout);
327		return 0xff;
328	}
329
330	rv = ldisc_data->buf;
331	/* Make sure we have read buf before we set buf_free to let
332	 * the producer overwrite it
333	 */
334	mb();
335	ldisc_data->buf_free = true;
336	/* Let TTY push more characters */
337	tty_flip_buffer_push(speakup_tty->port);
338
339	return rv;
340}
341
342static unsigned char spk_ttyio_in(void)
343{
344	return ttyio_in(SPK_SYNTH_TIMEOUT);
345}
346
347static unsigned char spk_ttyio_in_nowait(void)
348{
349	u8 rv = ttyio_in(0);
350
351	return (rv == 0xff) ? 0 : rv;
352}
353
354static void spk_ttyio_flush_buffer(void)
355{
356	mutex_lock(&speakup_tty_mutex);
357	if (check_tty(speakup_tty)) {
358		mutex_unlock(&speakup_tty_mutex);
359		return;
360	}
361
362	if (speakup_tty->ops->flush_buffer)
363		speakup_tty->ops->flush_buffer(speakup_tty);
364
365	mutex_unlock(&speakup_tty_mutex);
366}
367
368int spk_ttyio_synth_probe(struct spk_synth *synth)
369{
370	int rv = spk_ttyio_initialise_ldisc(synth);
371
372	if (rv)
373		return rv;
374
375	synth->alive = 1;
376	spk_ttyio_synth = synth;
377
378	return 0;
379}
380EXPORT_SYMBOL_GPL(spk_ttyio_synth_probe);
381
382void spk_ttyio_release(void)
383{
384	if (!speakup_tty)
385		return;
386
387	tty_lock(speakup_tty);
388
389	if (speakup_tty->ops->close)
390		speakup_tty->ops->close(speakup_tty, NULL);
391
392	tty_ldisc_flush(speakup_tty);
393	tty_unlock(speakup_tty);
394	tty_kclose(speakup_tty);
395}
396EXPORT_SYMBOL_GPL(spk_ttyio_release);
397
398const char *spk_ttyio_synth_immediate(struct spk_synth *synth, const char *buff)
399{
400	u_char ch;
401
402	while ((ch = *buff)) {
403		if (ch == '\n')
404			ch = synth->procspeech;
405		if (tty_write_room(speakup_tty) < 1 ||
406		    !synth->io_ops->synth_out(synth, ch))
407			return buff;
408		buff++;
409	}
410	return NULL;
411}
412EXPORT_SYMBOL_GPL(spk_ttyio_synth_immediate);
413