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