From: Okash Khawaja <okash.khawaja@gmail.com>
To: samuel.thibault@ens-lyon.org
Cc: speakup@linux-speakup.org
Subject: [patch 4/6] staging: speakup: Add spk_ttyio
Date: Sat, 25 Feb 2017 19:26:57 +0000 [thread overview]
Message-ID: <20170225192657.GA4513@sanghar> (raw)
In-Reply-To: <20170225192526.GA4507@sanghar>
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>
Index: linux-stable/drivers/staging/speakup/Makefile
===================================================================
--- linux-stable.orig/drivers/staging/speakup/Makefile
+++ linux-stable/drivers/staging/speakup/Makefile
@@ -25,6 +25,7 @@
kobjects.o \
selection.o \
serialio.o \
+ spk_ttyio.o \
synth.o \
thread.o \
varhandlers.o
Index: linux-stable/drivers/staging/speakup/spk_priv.h
===================================================================
--- linux-stable.orig/drivers/staging/speakup/spk_priv.h
+++ linux-stable/drivers/staging/speakup/spk_priv.h
@@ -46,7 +46,9 @@
unsigned char spk_serial_in(void);
unsigned char spk_serial_in_nowait(void);
int spk_serial_out(struct spk_synth *in_synth, const char ch);
+int spk_ttyio_out(struct spk_synth *in_synth, const char ch);
void spk_serial_release(void);
+void spk_ttyio_release(void);
char synth_buffer_getc(void);
char synth_buffer_peek(void);
@@ -58,7 +60,9 @@
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_synth_immediate(struct spk_synth *synth, const char *buff);
+const char *spk_ttyio_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);
int spk_synth_is_alive_nop(struct spk_synth *synth);
Index: linux-stable/drivers/staging/speakup/spk_ttyio.c
===================================================================
--- /dev/null
+++ linux-stable/drivers/staging/speakup/spk_ttyio.c
@@ -0,0 +1,148 @@
+#include <linux/types.h>
+#include <linux/tty.h>
+
+#include "speakup.h"
+#include "spk_types.h"
+
+struct tty_struct *speakup_tty;
+EXPORT_SYMBOL_GPL(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_initialise_ldisc(void)
+{
+ int ret = 0;
+ struct tty_struct *tty;
+
+ ret = tty_register_ldisc(N_SPEAKUP, &spk_ttyio_ldisc_ops);
+ if (ret) {
+ pr_err("speakup_test_init(): Error registering line discipline.\n");
+ return ret;
+ }
+
+ tty = tty_open_by_driver(MKDEV(4, 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;
+}
+
+int spk_ttyio_synth_probe(struct spk_synth *synth)
+{
+ int rv = spk_ttyio_initialise_ldisc();
+
+ 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 0
+ if (tty_release_checks(tty, idx)) {
+ tty_unlock(tty);
+ return 0;
+ }
+#endif
+
+ 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);
+#if 0
+ tty_flush_works(tty);
+#endif
+#if 0
+ mutex_lock(&tty_mutex);
+ release_tty(tty, idx);
+ mutex_unlock(&tty_mutex);
+#endif
+}
+EXPORT_SYMBOL_GPL(spk_ttyio_release);
+
+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;
+}
+EXPORT_SYMBOL_GPL(spk_ttyio_out);
+
+const char *spk_ttyio_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 || !spk_ttyio_out(synth, ch))
+ return buff;
+ buff++;
+ }
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(spk_ttyio_immediate);
Index: linux-stable/include/uapi/linux/tty.h
===================================================================
--- linux-stable.orig/include/uapi/linux/tty.h
+++ linux-stable/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 */
Index: linux-stable/drivers/tty/tty_ldisc.c
===================================================================
--- linux-stable.orig/drivers/tty/tty_ldisc.c
+++ linux-stable/drivers/tty/tty_ldisc.c
@@ -603,6 +603,8 @@
return retval;
}
+EXPORT_SYMBOL(tty_set_ldisc);
+
/**
* tty_ldisc_kill - teardown ldisc
* @tty: tty being released
@@ -795,6 +797,8 @@
tty_ldisc_debug(tty, "released\n");
}
+EXPORT_SYMBOL(tty_ldisc_release);
+
/**
* tty_ldisc_init - ldisc setup for new tty
* @tty: tty being allocated
next prev parent reply other threads:[~ UTC|newest]
Thread overview: 53+ messages / expand[flat|nested] mbox.gz Atom feed top
[patch 0/6] staging: speakup: Introduce TTY-based comms Okash Khawaja
` [patch 1/6] tty_port: allow a port to be opened with a tty that has no file handle Okash Khawaja
` Samuel Thibault
` Samuel Thibault
` John Covici
` Samuel Thibault
` Okash Khawaja
` Samuel Thibault
` Okash Khawaja
` Samuel Thibault
` Okash Khawaja
` Samuel Thibault
` Okash Khawaja
[not found] ` <20170225192358.GA4499@sanghar>
` [patch 3/6] staging: speakup: refactor spk_stop_serial_interrupt Okash Khawaja
` Okash Khawaja [this message]
` [patch 5/6] staging: speakup: Make speakup_dummy use ttyio Okash Khawaja
` [patch 6/6] staging: speakup: Migrate acntsa, bns, dectlk and txprt to ttyio Okash Khawaja
` Samuel Thibault
` Samuel Thibault
` Samuel Thibault
` Samuel Thibault
` Okash Khawaja
` Samuel Thibault
` Okash Khawaja
` Okash Khawaja
` Samuel Thibault
` Okash Khawaja
` Samuel Thibault
` Samuel Thibault
` Samuel Thibault
` Okash Khawaja
` Samuel Thibault
` Okash Khawaja
` Samuel Thibault
` Samuel Thibault
` Samuel Thibault
` [patch 4/6] staging: speakup: Add spk_ttyio Samuel Thibault
` Samuel Thibault
` [patch 3/6] staging: speakup: refactor spk_stop_serial_interrupt Samuel Thibault
` Okash Khawaja
` Samuel Thibault
` [patch 2/6] staging: speakup: Add serial_out method Samuel Thibault
` Samuel Thibault
` Okash Khawaja
` Samuel Thibault
` [patch 0/6] staging: speakup: Introduce TTY-based comms Trevor Astrope
` Okash Khawaja
` Samuel Thibault
` Samuel Thibault
` Samuel Thibault
` Read this first :) " Samuel Thibault
` Okash Khawaja
` Samuel Thibault
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=20170225192657.GA4513@sanghar \
--to=okash.khawaja@gmail.com \
--cc=samuel.thibault@ens-lyon.org \
--cc=speakup@linux-speakup.org \
/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 read-only IMAP folder(s) and NNTP newsgroup(s).