0001
0002 #include <linux/types.h>
0003 #include <linux/tty.h>
0004 #include <linux/tty_flip.h>
0005 #include <linux/slab.h>
0006
0007 #include "speakup.h"
0008 #include "spk_types.h"
0009 #include "spk_priv.h"
0010
0011 struct spk_ldisc_data {
0012 char buf;
0013 struct completion completion;
0014 bool buf_free;
0015 struct spk_synth *synth;
0016 };
0017
0018
0019
0020
0021
0022 static struct tty_struct *speakup_tty;
0023
0024 static DEFINE_MUTEX(speakup_tty_mutex);
0025
0026 static int ser_to_dev(int ser, dev_t *dev_no)
0027 {
0028 if (ser < 0 || ser > (255 - 64)) {
0029 pr_err("speakup: Invalid ser param. Must be between 0 and 191 inclusive.\n");
0030 return -EINVAL;
0031 }
0032
0033 *dev_no = MKDEV(4, (64 + ser));
0034 return 0;
0035 }
0036
0037 static int get_dev_to_use(struct spk_synth *synth, dev_t *dev_no)
0038 {
0039
0040 if (strcmp(synth->dev_name, SYNTH_DEFAULT_DEV) ||
0041 synth->ser == SYNTH_DEFAULT_SER)
0042 return tty_dev_name_to_number(synth->dev_name, dev_no);
0043
0044 return ser_to_dev(synth->ser, dev_no);
0045 }
0046
0047 static int spk_ttyio_ldisc_open(struct tty_struct *tty)
0048 {
0049 struct spk_ldisc_data *ldisc_data;
0050
0051 if (tty != speakup_tty)
0052
0053 return -ENODEV;
0054
0055 if (!tty->ops->write)
0056 return -EOPNOTSUPP;
0057
0058 ldisc_data = kmalloc(sizeof(*ldisc_data), GFP_KERNEL);
0059 if (!ldisc_data)
0060 return -ENOMEM;
0061
0062 init_completion(&ldisc_data->completion);
0063 ldisc_data->buf_free = true;
0064 tty->disc_data = ldisc_data;
0065
0066 return 0;
0067 }
0068
0069 static void spk_ttyio_ldisc_close(struct tty_struct *tty)
0070 {
0071 kfree(tty->disc_data);
0072 }
0073
0074 static int spk_ttyio_receive_buf2(struct tty_struct *tty,
0075 const unsigned char *cp,
0076 const char *fp, int count)
0077 {
0078 struct spk_ldisc_data *ldisc_data = tty->disc_data;
0079 struct spk_synth *synth = ldisc_data->synth;
0080
0081 if (synth->read_buff_add) {
0082 int i;
0083
0084 for (i = 0; i < count; i++)
0085 synth->read_buff_add(cp[i]);
0086
0087 return count;
0088 }
0089
0090 if (!ldisc_data->buf_free)
0091
0092 return 0;
0093
0094
0095
0096
0097 mb();
0098
0099 ldisc_data->buf = cp[0];
0100 ldisc_data->buf_free = false;
0101 complete(&ldisc_data->completion);
0102
0103 return 1;
0104 }
0105
0106 static struct tty_ldisc_ops spk_ttyio_ldisc_ops = {
0107 .owner = THIS_MODULE,
0108 .num = N_SPEAKUP,
0109 .name = "speakup_ldisc",
0110 .open = spk_ttyio_ldisc_open,
0111 .close = spk_ttyio_ldisc_close,
0112 .receive_buf2 = spk_ttyio_receive_buf2,
0113 };
0114
0115 static int spk_ttyio_out(struct spk_synth *in_synth, const char ch);
0116 static int spk_ttyio_out_unicode(struct spk_synth *in_synth, u16 ch);
0117 static void spk_ttyio_send_xchar(struct spk_synth *in_synth, char ch);
0118 static void spk_ttyio_tiocmset(struct spk_synth *in_synth, unsigned int set, unsigned int clear);
0119 static unsigned char spk_ttyio_in(struct spk_synth *in_synth);
0120 static unsigned char spk_ttyio_in_nowait(struct spk_synth *in_synth);
0121 static void spk_ttyio_flush_buffer(struct spk_synth *in_synth);
0122 static int spk_ttyio_wait_for_xmitr(struct spk_synth *in_synth);
0123
0124 struct spk_io_ops spk_ttyio_ops = {
0125 .synth_out = spk_ttyio_out,
0126 .synth_out_unicode = spk_ttyio_out_unicode,
0127 .send_xchar = spk_ttyio_send_xchar,
0128 .tiocmset = spk_ttyio_tiocmset,
0129 .synth_in = spk_ttyio_in,
0130 .synth_in_nowait = spk_ttyio_in_nowait,
0131 .flush_buffer = spk_ttyio_flush_buffer,
0132 .wait_for_xmitr = spk_ttyio_wait_for_xmitr,
0133 };
0134 EXPORT_SYMBOL_GPL(spk_ttyio_ops);
0135
0136 static inline void get_termios(struct tty_struct *tty,
0137 struct ktermios *out_termios)
0138 {
0139 down_read(&tty->termios_rwsem);
0140 *out_termios = tty->termios;
0141 up_read(&tty->termios_rwsem);
0142 }
0143
0144 static int spk_ttyio_initialise_ldisc(struct spk_synth *synth)
0145 {
0146 int ret = 0;
0147 struct tty_struct *tty;
0148 struct ktermios tmp_termios;
0149 dev_t dev;
0150
0151 ret = get_dev_to_use(synth, &dev);
0152 if (ret)
0153 return ret;
0154
0155 tty = tty_kopen_exclusive(dev);
0156 if (IS_ERR(tty))
0157 return PTR_ERR(tty);
0158
0159 if (tty->ops->open)
0160 ret = tty->ops->open(tty, NULL);
0161 else
0162 ret = -ENODEV;
0163
0164 if (ret) {
0165 tty_unlock(tty);
0166 return ret;
0167 }
0168
0169 clear_bit(TTY_HUPPED, &tty->flags);
0170
0171 get_termios(tty, &tmp_termios);
0172 if (!(tmp_termios.c_cflag & CRTSCTS)) {
0173 tmp_termios.c_cflag |= CRTSCTS;
0174 tty_set_termios(tty, &tmp_termios);
0175
0176
0177
0178
0179
0180 get_termios(tty, &tmp_termios);
0181 if (!(tmp_termios.c_cflag & CRTSCTS))
0182 pr_warn("speakup: Failed to set hardware flow control\n");
0183 }
0184
0185 tty_unlock(tty);
0186
0187 mutex_lock(&speakup_tty_mutex);
0188 speakup_tty = tty;
0189 ret = tty_set_ldisc(tty, N_SPEAKUP);
0190 speakup_tty = NULL;
0191 mutex_unlock(&speakup_tty_mutex);
0192
0193 if (!ret) {
0194
0195 struct spk_ldisc_data *ldisc_data = tty->disc_data;
0196
0197 ldisc_data->synth = synth;
0198 synth->dev = tty;
0199 return 0;
0200 }
0201
0202 pr_err("speakup: Failed to set N_SPEAKUP on tty\n");
0203
0204 tty_lock(tty);
0205 if (tty->ops->close)
0206 tty->ops->close(tty, NULL);
0207 tty_unlock(tty);
0208
0209 tty_kclose(tty);
0210
0211 return ret;
0212 }
0213
0214 void spk_ttyio_register_ldisc(void)
0215 {
0216 if (tty_register_ldisc(&spk_ttyio_ldisc_ops))
0217 pr_warn("speakup: Error registering line discipline. Most synths won't work.\n");
0218 }
0219
0220 void spk_ttyio_unregister_ldisc(void)
0221 {
0222 tty_unregister_ldisc(&spk_ttyio_ldisc_ops);
0223 }
0224
0225 static int spk_ttyio_out(struct spk_synth *in_synth, const char ch)
0226 {
0227 struct tty_struct *tty = in_synth->dev;
0228 int ret;
0229
0230 if (!in_synth->alive || !tty->ops->write)
0231 return 0;
0232
0233 ret = tty->ops->write(tty, &ch, 1);
0234
0235 if (ret == 0)
0236
0237 return 0;
0238
0239 if (ret > 0)
0240
0241 return 1;
0242
0243 pr_warn("%s: I/O error, deactivating speakup\n",
0244 in_synth->long_name);
0245
0246
0247
0248
0249 in_synth->alive = 0;
0250 speakup_start_ttys();
0251 return 0;
0252 }
0253
0254 static int spk_ttyio_out_unicode(struct spk_synth *in_synth, u16 ch)
0255 {
0256 int ret;
0257
0258 if (ch < 0x80) {
0259 ret = spk_ttyio_out(in_synth, ch);
0260 } else if (ch < 0x800) {
0261 ret = spk_ttyio_out(in_synth, 0xc0 | (ch >> 6));
0262 ret &= spk_ttyio_out(in_synth, 0x80 | (ch & 0x3f));
0263 } else {
0264 ret = spk_ttyio_out(in_synth, 0xe0 | (ch >> 12));
0265 ret &= spk_ttyio_out(in_synth, 0x80 | ((ch >> 6) & 0x3f));
0266 ret &= spk_ttyio_out(in_synth, 0x80 | (ch & 0x3f));
0267 }
0268 return ret;
0269 }
0270
0271 static void spk_ttyio_send_xchar(struct spk_synth *in_synth, char ch)
0272 {
0273 struct tty_struct *tty = in_synth->dev;
0274
0275 if (tty->ops->send_xchar)
0276 tty->ops->send_xchar(tty, ch);
0277 }
0278
0279 static void spk_ttyio_tiocmset(struct spk_synth *in_synth, unsigned int set, unsigned int clear)
0280 {
0281 struct tty_struct *tty = in_synth->dev;
0282
0283 if (tty->ops->tiocmset)
0284 tty->ops->tiocmset(tty, set, clear);
0285 }
0286
0287 static int spk_ttyio_wait_for_xmitr(struct spk_synth *in_synth)
0288 {
0289 return 1;
0290 }
0291
0292 static unsigned char ttyio_in(struct spk_synth *in_synth, int timeout)
0293 {
0294 struct tty_struct *tty = in_synth->dev;
0295 struct spk_ldisc_data *ldisc_data = tty->disc_data;
0296 char rv;
0297
0298 if (!timeout) {
0299 if (!try_wait_for_completion(&ldisc_data->completion))
0300 return 0xff;
0301 } else if (wait_for_completion_timeout(&ldisc_data->completion,
0302 usecs_to_jiffies(timeout)) == 0) {
0303 pr_warn("spk_ttyio: timeout (%d) while waiting for input\n",
0304 timeout);
0305 return 0xff;
0306 }
0307
0308 rv = ldisc_data->buf;
0309
0310
0311
0312 mb();
0313 ldisc_data->buf_free = true;
0314
0315 tty_flip_buffer_push(tty->port);
0316
0317 return rv;
0318 }
0319
0320 static unsigned char spk_ttyio_in(struct spk_synth *in_synth)
0321 {
0322 return ttyio_in(in_synth, SPK_SYNTH_TIMEOUT);
0323 }
0324
0325 static unsigned char spk_ttyio_in_nowait(struct spk_synth *in_synth)
0326 {
0327 u8 rv = ttyio_in(in_synth, 0);
0328
0329 return (rv == 0xff) ? 0 : rv;
0330 }
0331
0332 static void spk_ttyio_flush_buffer(struct spk_synth *in_synth)
0333 {
0334 struct tty_struct *tty = in_synth->dev;
0335
0336 if (tty->ops->flush_buffer)
0337 tty->ops->flush_buffer(tty);
0338 }
0339
0340 int spk_ttyio_synth_probe(struct spk_synth *synth)
0341 {
0342 int rv = spk_ttyio_initialise_ldisc(synth);
0343
0344 if (rv)
0345 return rv;
0346
0347 synth->alive = 1;
0348
0349 return 0;
0350 }
0351 EXPORT_SYMBOL_GPL(spk_ttyio_synth_probe);
0352
0353 void spk_ttyio_release(struct spk_synth *in_synth)
0354 {
0355 struct tty_struct *tty = in_synth->dev;
0356
0357 tty_lock(tty);
0358
0359 if (tty->ops->close)
0360 tty->ops->close(tty, NULL);
0361
0362 tty_ldisc_flush(tty);
0363 tty_unlock(tty);
0364 tty_kclose(tty);
0365
0366 in_synth->dev = NULL;
0367 }
0368 EXPORT_SYMBOL_GPL(spk_ttyio_release);
0369
0370 const char *spk_ttyio_synth_immediate(struct spk_synth *in_synth, const char *buff)
0371 {
0372 struct tty_struct *tty = in_synth->dev;
0373 u_char ch;
0374
0375 while ((ch = *buff)) {
0376 if (ch == '\n')
0377 ch = in_synth->procspeech;
0378 if (tty_write_room(tty) < 1 ||
0379 !in_synth->io_ops->synth_out(in_synth, ch))
0380 return buff;
0381 buff++;
0382 }
0383 return NULL;
0384 }
0385 EXPORT_SYMBOL_GPL(spk_ttyio_synth_immediate);