linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Okash Khawaja <okash.khawaja@gmail.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Jiri Slaby <jslaby@suse.com>,
	Samuel Thibault <samuel.thibault@ens-lyon.org>,
	linux-kernel@vger.kernel.org
Cc: William Hubbs <w.d.hubbs@gmail.com>,
	Chris Brannon <chris@the-brannons.com>,
	Kirk Reiser <kirk@reisers.ca>,
	speakup@linux-speakup.org, devel@driverdev.osuosl.org,
	Okash Khawaja <okash.khawaja@gmail.com>
Subject: [patch 3/6] staging: speakup: add tty-based comms functions
Date: Sat, 29 Apr 2017 20:53:00 +0100	[thread overview]
Message-ID: <20170429195406.212534900@gmail.com> (raw)
In-Reply-To: 20170429195257.630355823@gmail.com

[-- Attachment #1: 03_add_spk_ttyio --]
[-- Type: text/plain, Size: 6779 bytes --]

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 <okash.khawaja@gmail.com>
Reviewed-by: Samuel Thibault <samuel.thibault@ens-lyon.org>

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 <linux/types.h>
+#include <linux/tty.h>
+
+#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 */

  parent reply	other threads:[~2017-04-29 19:54 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-29 19:52 [patch 0/6] staging: speakup: migrate synths to use TTY-based comms Okash Khawaja
2017-04-29 19:52 ` [patch 1/6] staging: speakup: make input functionality swappable Okash Khawaja
2017-04-29 19:52 ` [patch 2/6] tty: export tty_open_by_driver Okash Khawaja
2017-05-15 10:31   ` Greg Kroah-Hartman
2017-05-15 11:10     ` Okash Khawaja
2017-05-15 11:29       ` Greg Kroah-Hartman
2017-04-29 19:53 ` Okash Khawaja [this message]
2017-04-29 19:53 ` [patch 4/6] staging: speakup: migrate acntsa, bns, dummy and txprt to ttyio Okash Khawaja
2017-04-29 19:53 ` [patch 5/6] staging: speakup: add send_xchar, tiocmset and input functionality for tty Okash Khawaja
2017-04-29 19:53 ` [patch 6/6] staging: speakup: migrate apollo, ltlk, audptr, decext, dectlk and spkout Okash Khawaja
2017-04-29 19:58 ` [patch 0/6] staging: speakup: migrate synths to use TTY-based comms Okash Khawaja

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170429195406.212534900@gmail.com \
    --to=okash.khawaja@gmail.com \
    --cc=chris@the-brannons.com \
    --cc=devel@driverdev.osuosl.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=jslaby@suse.com \
    --cc=kirk@reisers.ca \
    --cc=linux-kernel@vger.kernel.org \
    --cc=samuel.thibault@ens-lyon.org \
    --cc=speakup@linux-speakup.org \
    --cc=w.d.hubbs@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).