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