From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by befuddled.reisers.ca (Postfix, from userid 65534) id 1C3DB1F021C; Sat, 29 Apr 2017 15:54:52 -0400 (EDT) Received: from mail-wr0-x243.google.com (mail-wr0-x243.google.com [IPv6:2a00:1450:400c:c0c::243]) by befuddled.reisers.ca (Postfix) with ESMTPS id 536B51F0228 for ; Sat, 29 Apr 2017 15:54:14 -0400 (EDT) Received: by mail-wr0-x243.google.com with SMTP id 6so10322324wrb.1 for ; Sat, 29 Apr 2017 12:54:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=message-id:user-agent:date:from:to:cc:subject:references :mime-version:content-disposition; bh=9bnp1mTZx+VxatmeNSHc/b45quKcsVDe0nqYfD3wnOI=; b=OEhz69Hix0Br6lYi4Xlq44AvtDhYL5hxn+w7E3yfC9o1YtZ6nkjEoB116rn8ja90wa mODkTLrrvgcrilwokLz0fVZjiVzek+PTYlxdMUtXQVrg6HsQszfEQYHurtp1QSYEXvd4 jWAJR2VjhYizIME63RIp+ZRGqHz+IL5nyJA+U7/79/uSt1ii3tXPxKOcocMI64I1LuO/ X2LFxiZZd0Q1QdhiHffAj+kXasJk7OB1glylilvi3gVmdPSd1v1cQO8xlh91A1KwexTw TpY9kJi69FRFdbG3NW8bE02MCNha5Iy7bfmxiDEBNsaCej/K5dG0yoEMAvWNusxL8sti uzdA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:user-agent:date:from:to:cc:subject :references:mime-version:content-disposition; bh=9bnp1mTZx+VxatmeNSHc/b45quKcsVDe0nqYfD3wnOI=; b=GlcI665xv8Zb9SExorn2OnQ6OKGSgsRnc83048OQTY/yEIuQIkckvENJMh3bIkLNc8 +kOdQVp0YFhjkZ+fwt6xQJHmaZkEexjNQ2NB4BkjLoQ+MaUILbZU1ClWqut9ZaxbJO49 J39VXEGysk75/++GSZZMks23UixGmaDefBeQkH9XjlMCwjJyE4Y2xlLvm8vqR/DUR18u Kt+3kfQMpBtDWiq9vtgDT9UcSr+smTfnTqDBDSvMXtW0G1Y8zQ/MfkS2I0ojmwhLZoLE v3ot5cPXIwpQxVakK5Cx3TpuB9pYUU0g9/90pwbpvOUqJXkw8xbbf85iHji/mzfaJFku jhCg== X-Gm-Message-State: AN3rC/4ISGfn43sulji44SPBGECJ0k433oXz6pCbOOLkHUjZDwUzCe68 wumqm3TzfINN7Q== X-Received: by 10.223.155.141 with SMTP id d13mr10118251wrc.90.1493495649224; Sat, 29 Apr 2017 12:54:09 -0700 (PDT) Received: from sanghar.laptop ([2a00:23c4:7320:5e00:224:d6ff:fe76:7136]) by smtp.gmail.com with ESMTPSA id y60sm7944605wrb.39.2017.04.29.12.54.06 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 29 Apr 2017 12:54:08 -0700 (PDT) Received: by sanghar.laptop (sSMTP sendmail emulation); Sat, 29 Apr 2017 20:54:06 +0100 Message-Id: <20170429195406.212534900@gmail.com> User-Agent: quilt/0.65 Date: Sat, 29 Apr 2017 20:53:00 +0100 From: Okash Khawaja To: Greg Kroah-Hartman , Jiri Slaby , Samuel Thibault , linux-kernel@vger.kernel.org Cc: William Hubbs , Chris Brannon , Kirk Reiser , speakup@linux-speakup.org, devel@driverdev.osuosl.org, Okash Khawaja Subject: [patch 3/6] staging: speakup: add tty-based comms functions References: <20170429195257.630355823@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15 Content-Disposition: inline; filename=03_add_spk_ttyio X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 X-BeenThere: speakup@linux-speakup.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Speakup is a screen review system for Linux." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 29 Apr 2017 19:54:52 -0000 This adds spk_ttyio.c file. It contains a set of functions which implement those methods in spk_synth struct which relate to sending bytes out using serial comms. Implementations in this file perform the same function but using TTY subsystem instead. Currently synths access serial ports, directly poking standard ISA ports by trying to steal them from serial driver. Some ISA cards actually need this way of doing it, but most other synthesizers don't, and can actually work by using the proper TTY subsystem through a new N_SPEAKUP line discipline. So this adds the methods for drivers to switch to accessing serial ports through the TTY subsystem, whenever appropriate. Signed-off-by: Okash Khawaja Reviewed-by: Samuel Thibault Index: linux-staging/drivers/staging/speakup/Makefile =================================================================== --- linux-staging.orig/drivers/staging/speakup/Makefile +++ linux-staging/drivers/staging/speakup/Makefile @@ -25,6 +25,7 @@ speakup-y := \ kobjects.o \ selection.o \ serialio.o \ + spk_ttyio.o \ synth.o \ thread.o \ varhandlers.o Index: linux-staging/drivers/staging/speakup/spk_priv.h =================================================================== --- linux-staging.orig/drivers/staging/speakup/spk_priv.h +++ linux-staging/drivers/staging/speakup/spk_priv.h @@ -44,6 +44,7 @@ const struct old_serial_port *spk_serial void spk_stop_serial_interrupt(void); int spk_wait_for_xmitr(struct spk_synth *in_synth); void spk_serial_release(void); +void spk_ttyio_release(void); void synth_buffer_skip_nonlatin1(void); u16 synth_buffer_getc(void); @@ -56,7 +57,9 @@ ssize_t spk_var_store(struct kobject *ko const char *buf, size_t count); int spk_serial_synth_probe(struct spk_synth *synth); +int spk_ttyio_synth_probe(struct spk_synth *synth); const char *spk_serial_synth_immediate(struct spk_synth *synth, const char *buff); +const char *spk_ttyio_synth_immediate(struct spk_synth *synth, const char *buff); void spk_do_catch_up(struct spk_synth *synth); void spk_synth_flush(struct spk_synth *synth); unsigned char spk_synth_get_index(struct spk_synth *synth); @@ -78,5 +81,6 @@ extern struct speakup_info_t speakup_inf extern struct var_t synth_time_vars[]; extern struct spk_io_ops spk_serial_io_ops; +extern struct spk_io_ops spk_ttyio_ops; #endif Index: linux-staging/drivers/staging/speakup/spk_ttyio.c =================================================================== --- /dev/null +++ linux-staging/drivers/staging/speakup/spk_ttyio.c @@ -0,0 +1,143 @@ +#include +#include + +#include "speakup.h" +#include "spk_types.h" + +static struct tty_struct *speakup_tty; + +static int spk_ttyio_ldisc_open(struct tty_struct *tty) +{ + if (tty->ops->write == NULL) + return -EOPNOTSUPP; + speakup_tty = tty; + + return 0; +} + +static void spk_ttyio_ldisc_close(struct tty_struct *tty) +{ + speakup_tty = NULL; +} + +static struct tty_ldisc_ops spk_ttyio_ldisc_ops = { + .owner = THIS_MODULE, + .magic = TTY_LDISC_MAGIC, + .name = "speakup_ldisc", + .open = spk_ttyio_ldisc_open, + .close = spk_ttyio_ldisc_close, +}; + +static int spk_ttyio_out(struct spk_synth *in_synth, const char ch); +struct spk_io_ops spk_ttyio_ops = { + .synth_out = spk_ttyio_out, +}; +EXPORT_SYMBOL_GPL(spk_ttyio_ops); + +static int spk_ttyio_initialise_ldisc(int ser) +{ + int ret = 0; + struct tty_struct *tty; + + ret = tty_register_ldisc(N_SPEAKUP, &spk_ttyio_ldisc_ops); + if (ret) { + pr_err("Error registering line discipline.\n"); + return ret; + } + + if (ser < 0 || ser > (255 - 64)) { + pr_err("speakup: Invalid ser param. Must be between 0 and 191 inclusive.\n"); + return -EINVAL; + } + + /* TODO: support more than ttyS* */ + tty = tty_open_by_driver(MKDEV(4, (ser + 64)), NULL, NULL); + if (IS_ERR(tty)) + return PTR_ERR(tty); + + if (tty->ops->open) + ret = tty->ops->open(tty, NULL); + else + ret = -ENODEV; + + if (ret) { + tty_unlock(tty); + return ret; + } + + clear_bit(TTY_HUPPED, &tty->flags); + tty_unlock(tty); + + ret = tty_set_ldisc(tty, N_SPEAKUP); + + return ret; +} + +static int spk_ttyio_out(struct spk_synth *in_synth, const char ch) +{ + if (in_synth->alive && speakup_tty && speakup_tty->ops->write) { + int ret = speakup_tty->ops->write(speakup_tty, &ch, 1); + if (ret == 0) + /* No room */ + return 0; + if (ret < 0) { + pr_warn("%s: I/O error, deactivating speakup\n", in_synth->long_name); + /* No synth any more, so nobody will restart TTYs, and we thus + * need to do it ourselves. Now that there is no synth we can + * let application flood anyway + */ + in_synth->alive = 0; + speakup_start_ttys(); + return 0; + } + return 1; + } + return 0; +} + +int spk_ttyio_synth_probe(struct spk_synth *synth) +{ + int rv = spk_ttyio_initialise_ldisc(synth->ser); + + if (rv) + return rv; + + synth->alive = 1; + + return 0; +} +EXPORT_SYMBOL_GPL(spk_ttyio_synth_probe); + +void spk_ttyio_release(void) +{ + int idx; + + if (!speakup_tty) + return; + + tty_lock(speakup_tty); + idx = speakup_tty->index; + + if (speakup_tty->ops->close) + speakup_tty->ops->close(speakup_tty, NULL); + + tty_ldisc_flush(speakup_tty); + tty_unlock(speakup_tty); + tty_ldisc_release(speakup_tty); +} +EXPORT_SYMBOL_GPL(spk_ttyio_release); + +const char *spk_ttyio_synth_immediate(struct spk_synth *synth, const char *buff) +{ + u_char ch; + + while ((ch = *buff)) { + if (ch == '\n') + ch = synth->procspeech; + if (tty_write_room(speakup_tty) < 1 || !synth->io_ops->synth_out(synth, ch)) + return buff; + buff++; + } + return NULL; +} +EXPORT_SYMBOL_GPL(spk_ttyio_synth_immediate); Index: linux-staging/drivers/tty/tty_ldisc.c =================================================================== --- linux-staging.orig/drivers/tty/tty_ldisc.c +++ linux-staging/drivers/tty/tty_ldisc.c @@ -556,6 +556,7 @@ err: tty_unlock(tty); return retval; } +EXPORT_SYMBOL(tty_set_ldisc); /** * tty_ldisc_kill - teardown ldisc @@ -744,6 +745,7 @@ void tty_ldisc_release(struct tty_struct tty_ldisc_debug(tty, "released\n"); } +EXPORT_SYMBOL(tty_ldisc_release); /** * tty_ldisc_init - ldisc setup for new tty Index: linux-staging/include/uapi/linux/tty.h =================================================================== --- linux-staging.orig/include/uapi/linux/tty.h +++ linux-staging/include/uapi/linux/tty.h @@ -35,5 +35,6 @@ #define N_TRACESINK 23 /* Trace data routing for MIPI P1149.7 */ #define N_TRACEROUTER 24 /* Trace data routing for MIPI P1149.7 */ #define N_NCI 25 /* NFC NCI UART */ +#define N_SPEAKUP 26 /* Speakup communication with synths*/ #endif /* _UAPI_LINUX_TTY_H */