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