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