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