xref: /linux/drivers/accessibility/speakup/spk_ttyio.c (revision ed4bc1890b4984d0af447ad3cc1f93541623f8f3)
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 
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 
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 
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(*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 
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 
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 static int spk_ttyio_wait_for_xmitr(struct spk_synth *in_synth);
120 
121 struct spk_io_ops spk_ttyio_ops = {
122 	.synth_out = spk_ttyio_out,
123 	.synth_out_unicode = spk_ttyio_out_unicode,
124 	.send_xchar = spk_ttyio_send_xchar,
125 	.tiocmset = spk_ttyio_tiocmset,
126 	.synth_in = spk_ttyio_in,
127 	.synth_in_nowait = spk_ttyio_in_nowait,
128 	.flush_buffer = spk_ttyio_flush_buffer,
129 	.wait_for_xmitr = spk_ttyio_wait_for_xmitr,
130 };
131 EXPORT_SYMBOL_GPL(spk_ttyio_ops);
132 
133 static inline void get_termios(struct tty_struct *tty,
134 			       struct ktermios *out_termios)
135 {
136 	down_read(&tty->termios_rwsem);
137 	*out_termios = tty->termios;
138 	up_read(&tty->termios_rwsem);
139 }
140 
141 static int spk_ttyio_initialise_ldisc(struct spk_synth *synth)
142 {
143 	int ret = 0;
144 	struct tty_struct *tty;
145 	struct ktermios tmp_termios;
146 	dev_t dev;
147 
148 	ret = get_dev_to_use(synth, &dev);
149 	if (ret)
150 		return ret;
151 
152 	tty = tty_kopen(dev);
153 	if (IS_ERR(tty))
154 		return PTR_ERR(tty);
155 
156 	if (tty->ops->open)
157 		ret = tty->ops->open(tty, NULL);
158 	else
159 		ret = -ENODEV;
160 
161 	if (ret) {
162 		tty_unlock(tty);
163 		return ret;
164 	}
165 
166 	clear_bit(TTY_HUPPED, &tty->flags);
167 	/* ensure hardware flow control is enabled */
168 	get_termios(tty, &tmp_termios);
169 	if (!(tmp_termios.c_cflag & CRTSCTS)) {
170 		tmp_termios.c_cflag |= CRTSCTS;
171 		tty_set_termios(tty, &tmp_termios);
172 		/*
173 		 * check c_cflag to see if it's updated as tty_set_termios
174 		 * may not return error even when no tty bits are
175 		 * changed by the request.
176 		 */
177 		get_termios(tty, &tmp_termios);
178 		if (!(tmp_termios.c_cflag & CRTSCTS))
179 			pr_warn("speakup: Failed to set hardware flow control\n");
180 	}
181 
182 	tty_unlock(tty);
183 
184 	ret = tty_set_ldisc(tty, N_SPEAKUP);
185 	if (ret)
186 		pr_err("speakup: Failed to set N_SPEAKUP on tty\n");
187 
188 	return ret;
189 }
190 
191 void spk_ttyio_register_ldisc(void)
192 {
193 	if (tty_register_ldisc(N_SPEAKUP, &spk_ttyio_ldisc_ops))
194 		pr_warn("speakup: Error registering line discipline. Most synths won't work.\n");
195 }
196 
197 void spk_ttyio_unregister_ldisc(void)
198 {
199 	if (tty_unregister_ldisc(N_SPEAKUP))
200 		pr_warn("speakup: Couldn't unregister ldisc\n");
201 }
202 
203 static int spk_ttyio_out(struct spk_synth *in_synth, const char ch)
204 {
205 	mutex_lock(&speakup_tty_mutex);
206 	if (in_synth->alive && speakup_tty && speakup_tty->ops->write) {
207 		int ret = speakup_tty->ops->write(speakup_tty, &ch, 1);
208 
209 		mutex_unlock(&speakup_tty_mutex);
210 		if (ret == 0)
211 			/* No room */
212 			return 0;
213 		if (ret < 0) {
214 			pr_warn("%s: I/O error, deactivating speakup\n",
215 				in_synth->long_name);
216 			/* No synth any more, so nobody will restart TTYs,
217 			 * and we thus need to do it ourselves.  Now that there
218 			 * is no synth we can let application flood anyway
219 			 */
220 			in_synth->alive = 0;
221 			speakup_start_ttys();
222 			return 0;
223 		}
224 		return 1;
225 	}
226 
227 	mutex_unlock(&speakup_tty_mutex);
228 	return 0;
229 }
230 
231 static int spk_ttyio_out_unicode(struct spk_synth *in_synth, u16 ch)
232 {
233 	int ret;
234 
235 	if (ch < 0x80) {
236 		ret = spk_ttyio_out(in_synth, ch);
237 	} else if (ch < 0x800) {
238 		ret  = spk_ttyio_out(in_synth, 0xc0 | (ch >> 6));
239 		ret &= spk_ttyio_out(in_synth, 0x80 | (ch & 0x3f));
240 	} else {
241 		ret  = spk_ttyio_out(in_synth, 0xe0 | (ch >> 12));
242 		ret &= spk_ttyio_out(in_synth, 0x80 | ((ch >> 6) & 0x3f));
243 		ret &= spk_ttyio_out(in_synth, 0x80 | (ch & 0x3f));
244 	}
245 	return ret;
246 }
247 
248 static int check_tty(struct tty_struct *tty)
249 {
250 	if (!tty) {
251 		pr_warn("%s: I/O error, deactivating speakup\n",
252 			spk_ttyio_synth->long_name);
253 		/* No synth any more, so nobody will restart TTYs, and we thus
254 		 * need to do it ourselves.  Now that there is no synth we can
255 		 * let application flood anyway
256 		 */
257 		spk_ttyio_synth->alive = 0;
258 		speakup_start_ttys();
259 		return 1;
260 	}
261 
262 	return 0;
263 }
264 
265 static void spk_ttyio_send_xchar(char ch)
266 {
267 	mutex_lock(&speakup_tty_mutex);
268 	if (check_tty(speakup_tty)) {
269 		mutex_unlock(&speakup_tty_mutex);
270 		return;
271 	}
272 
273 	if (speakup_tty->ops->send_xchar)
274 		speakup_tty->ops->send_xchar(speakup_tty, ch);
275 	mutex_unlock(&speakup_tty_mutex);
276 }
277 
278 static void spk_ttyio_tiocmset(unsigned int set, unsigned int clear)
279 {
280 	mutex_lock(&speakup_tty_mutex);
281 	if (check_tty(speakup_tty)) {
282 		mutex_unlock(&speakup_tty_mutex);
283 		return;
284 	}
285 
286 	if (speakup_tty->ops->tiocmset)
287 		speakup_tty->ops->tiocmset(speakup_tty, set, clear);
288 	mutex_unlock(&speakup_tty_mutex);
289 }
290 
291 static int spk_ttyio_wait_for_xmitr(struct spk_synth *in_synth)
292 {
293 	return 1;
294 }
295 
296 static unsigned char ttyio_in(int timeout)
297 {
298 	struct spk_ldisc_data *ldisc_data = speakup_tty->disc_data;
299 	char rv;
300 
301 	if (wait_for_completion_timeout(&ldisc_data->completion,
302 					usecs_to_jiffies(timeout)) == 0) {
303 		if (timeout)
304 			pr_warn("spk_ttyio: timeout (%d)  while waiting for input\n",
305 				timeout);
306 		return 0xff;
307 	}
308 
309 	rv = ldisc_data->buf;
310 	/* Make sure we have read buf before we set buf_free to let
311 	 * the producer overwrite it
312 	 */
313 	mb();
314 	ldisc_data->buf_free = true;
315 	/* Let TTY push more characters */
316 	tty_schedule_flip(speakup_tty->port);
317 
318 	return rv;
319 }
320 
321 static unsigned char spk_ttyio_in(void)
322 {
323 	return ttyio_in(SPK_SYNTH_TIMEOUT);
324 }
325 
326 static unsigned char spk_ttyio_in_nowait(void)
327 {
328 	u8 rv = ttyio_in(0);
329 
330 	return (rv == 0xff) ? 0 : rv;
331 }
332 
333 static void spk_ttyio_flush_buffer(void)
334 {
335 	mutex_lock(&speakup_tty_mutex);
336 	if (check_tty(speakup_tty)) {
337 		mutex_unlock(&speakup_tty_mutex);
338 		return;
339 	}
340 
341 	if (speakup_tty->ops->flush_buffer)
342 		speakup_tty->ops->flush_buffer(speakup_tty);
343 
344 	mutex_unlock(&speakup_tty_mutex);
345 }
346 
347 int spk_ttyio_synth_probe(struct spk_synth *synth)
348 {
349 	int rv = spk_ttyio_initialise_ldisc(synth);
350 
351 	if (rv)
352 		return rv;
353 
354 	synth->alive = 1;
355 	spk_ttyio_synth = synth;
356 
357 	return 0;
358 }
359 EXPORT_SYMBOL_GPL(spk_ttyio_synth_probe);
360 
361 void spk_ttyio_release(void)
362 {
363 	if (!speakup_tty)
364 		return;
365 
366 	tty_lock(speakup_tty);
367 
368 	if (speakup_tty->ops->close)
369 		speakup_tty->ops->close(speakup_tty, NULL);
370 
371 	tty_ldisc_flush(speakup_tty);
372 	tty_unlock(speakup_tty);
373 	tty_kclose(speakup_tty);
374 }
375 EXPORT_SYMBOL_GPL(spk_ttyio_release);
376 
377 const char *spk_ttyio_synth_immediate(struct spk_synth *synth, const char *buff)
378 {
379 	u_char ch;
380 
381 	while ((ch = *buff)) {
382 		if (ch == '\n')
383 			ch = synth->procspeech;
384 		if (tty_write_room(speakup_tty) < 1 ||
385 		    !synth->io_ops->synth_out(synth, ch))
386 			return buff;
387 		buff++;
388 	}
389 	return NULL;
390 }
391 EXPORT_SYMBOL_GPL(spk_ttyio_synth_immediate);
392