staging: speakup: migrate synths to use TTY-based comms
Subsystems (2)
v2 cover staging: speakup: migrate synths to use TTY-based comms
This patchset migrates all external synths from using raw serial i/o to using tty-based comms. The synths not migrated are internal ones - plugged directly into motherboard, communicating over ISA etc. It's important to note that these patches access TTY from inside kernel.
Here is the summary of the patches in this set.
Patch 1: Exports tty_open_by_driver in order to allow the speakup to access it.
Patch 2: Adds spk_ttyio.c, a container of TTY-based comms. Patch 3: Migrates some synths which use relatively simple comms - output only.
Patch 4: Adds more TTY-based functionality that wasn't already added in patch 2.
Patch 5: Migrates remaining external synths based.
Patch 6: Contains these fixes: flushing TTY buffers and ensuring hardware flow control.
Thanks,
Okash
PATCH v2 1/6 tty: export tty_open_by_driver
This exports tty_open_by_driver so that it can be called from other places inside the kernel. The checks for null file pointer are based on Alan Cox's patch here: http://www.mail-archive.com/[email protected]/msg1215095.html. Description below is quoted from it:
"[RFC] tty_port: allow a port to be opened with a tty that has no file handle
Let us create tty objects entirely in kernel space. Untested proposal to show why all the ideas around rewriting half the uart stack are not needed.
With this a kernel created non file backed tty object could be used to
handle
data, and set terminal modes. Not all ldiscs can cope with this as N_TTY in particular has to work back to the fs/tty layer.
The tty_port code is however otherwise clean of file handles as far as I can tell as is the low level tty port write path used by the ldisc, the configuration low level interfaces and most of the ldiscs.
Currently you don't have any exposure to see tty hangups because those are built around the file layer. However a) it's a fixed port so you probably don't care about that b) if you do we can add a callback and c) you almost certainly don't want the userspace tear down/rebuild behaviour anyway.
This should however be sufficient if we wanted for example to enumerate all the bluetooth bound fixed ports via ACPI and make them directly available.
It doesn't deal with the case of a user opening a port that's also kernel opened and that would need some locking out (so it returned EBUSY if bound to a kernel device of some kind). That needs resolving along with how you "up" or "down" your new bluetooth device, or enumerate it while providing the existing tty API to avoid regressions (and to debug)."
The exported funtion is used later in this patch set to gain access to tty_struct.
drivers/tty/tty_io.c +7 -3
@@ -1369,7 +1369,10 @@ static struct tty_struct *tty_driver_loostruct tty_struct *tty;if (driver->ops->lookup) - tty = driver->ops->lookup (driver, file, idx); +if (!file) + tty =ERR_PTR (-EIO ); +else + tty = driver->ops->lookup (driver, file, idx);else tty = driver->ttys[idx];
@@ -2001,7 +2004,7 @@ static struct tty_driver *tty_lookup_dristruct tty_driver *console_driver =console_device (index);if (console_driver) { driver =tty_driver_kref_get (console_driver); -if (driver) { +if (driver && filp) {/* Don't let /dev/console block */ filp->f_flags |=O_NONBLOCK ;break ;
@@ -2034,7 +2037,7 @@ static struct tty_driver *tty_lookup_dri* - concurrent tty driver removal w/ lookup * - concurrent tty removal from driver table */ -static struct tty_struct *tty_open_by_driver (dev_t device,struct inode *inode, +struct tty_struct *tty_open_by_driver (dev_t device,struct inode *inode,struct file *filp) {struct tty_struct *tty;
@@ -2079,6 +2082,7 @@ out:tty_driver_kref_put (driver);return tty; } +EXPORT_SYMBOL (tty_open_by_driver);/** * tty_open - open a tty device
include/linux/tty.h +2 -0
@@ -401,6 +401,8 @@ extern struct tty_struct *get_current_tt/* tty_io.c */ extern int __init tty_init (void );extern const char *tty_name (const struct tty_struct *tty); +extern struct tty_struct *tty_open_by_driver (dev_t device,struct inode *inode, +struct file *filp);#else static inline void console_init (void ) { }
Re: [patch v2 1/6] tty: export tty_open_by_driver
Quoted 1 line · Okash Khawaja
This exports
tty_open_by_driverso that it can be called from other places inside the kernel. The checks for null file pointer are based on Alan Cox's patch here: http://www.mail-archive.com/[email protected]/msg1215095.html. Description below is quoted from it:
Any non-staging users? Please don't add new APIs with proper in-kernel users (and staging doesn't count for that).
Greg Kroah-Hartman
maintainerRe: [patch v2 1/6] tty: export tty_open_by_driver
Quoted 5 lines · Christoph Hellwig
Quoted 1 line · Okash Khawaja
This exports
tty_open_by_driverso that it can be called from other places inside the kernel. The checks for null file pointer are based on Alan Cox's patch here: http://www.mail-archive.com/[email protected]/msg1215095.html. Description below is quoted from it:Any non-staging users? Please don't add new APIs with proper in-kernel users (and staging doesn't count for that).
I'll give the speakup code a pass here, as they are trying to get this cleaned up properly and moved into the correct location. It's almost ready, with this and the serdev interface, it should be pretty close...
thanks,
greg k-h
PATCH v2 2/6 staging: speakup: add tty-based comms functions
In reply to Okash KhawajaThis 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.
drivers/staging/speakup/Makefile +1 -0
@@ -25,6 +25,7 @@ speakup-y := \ kobjects.o \ selection.o \ serialio.o \ + spk_ttyio.o \ synth.o \ thread.o \ varhandlers.o
drivers/staging/speakup/spk_priv.h +4 -0
@@ -44,6 +44,7 @@ const struct old_serial_port *spk_serialvoid 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_infextern struct var_t synth_time_vars[];extern struct spk_io_ops spk_serial_io_ops; +extern struct spk_io_ops spk_ttyio_ops;#endif
drivers/staging/speakup/spk_ttyio.c new file +143 -0
143 lines not on this page · raw message
drivers/tty/tty_ldisc.c +2 -0
@@ -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_structtty_ldisc_debug (tty,"released\n" ); } +EXPORT_SYMBOL (tty_ldisc_release);/** * tty_ldisc_init - ldisc setup for new tty
include/uapi/linux/tty.h +1 -0
@@ -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 */
PATCH v2 3/6 staging: speakup: migrate acntsa, bns, dummy and txprt to ttyio
In reply to Okash KhawajaThis changes the above five synths to TTY-based comms. They were chosen as a first pass because their serial comms are straightforward, i.e. they don't use serial input and don't do internal port knocking.
drivers/staging/speakup/speakup_dummy.c +4 -4
@@ -98,10 +98,10 @@ static struct spk_synth synth_dummy = { .startup = SYNTH_START, .checkval = SYNTH_CHECK, .vars = vars, - .io_ops = &spk_serial_io_ops, - .probe = spk_serial_synth_probe, - .release = spk_serial_release, - .synth_immediate = spk_serial_synth_immediate, + .io_ops = &spk_ttyio_ops, + .probe = spk_ttyio_synth_probe, + .release = spk_ttyio_release, + .synth_immediate = spk_ttyio_synth_immediate, .catch_up = spk_do_catch_up, .flush = spk_synth_flush, .is_alive = spk_synth_is_alive_restart,
drivers/staging/speakup/speakup_acntsa.c +4 -4
@@ -99,10 +99,10 @@ static struct spk_synth synth_acntsa = { .startup = SYNTH_START, .checkval = SYNTH_CHECK, .vars = vars, - .io_ops = &spk_serial_io_ops, + .io_ops = &spk_ttyio_ops, .probe = synth_probe, - .release = spk_serial_release, - .synth_immediate = spk_serial_synth_immediate, + .release = spk_ttyio_release, + .synth_immediate = spk_ttyio_synth_immediate, .catch_up = spk_do_catch_up, .flush = spk_synth_flush, .is_alive = spk_synth_is_alive_restart,
@@ -125,7 +125,7 @@ static int synth_probe(struct spk_synth {int failed; - failed =spk_serial_synth_probe (synth); + failed =spk_ttyio_synth_probe (synth);if (failed ==0 ) { synth->synth_immediate (synth,"\033=R\r" );mdelay (100 );
drivers/staging/speakup/speakup_txprt.c +4 -4
@@ -95,10 +95,10 @@ static struct spk_synth synth_txprt = { .startup = SYNTH_START, .checkval = SYNTH_CHECK, .vars = vars, - .io_ops = &spk_serial_io_ops, - .probe = spk_serial_synth_probe, - .release = spk_serial_release, - .synth_immediate = spk_serial_synth_immediate, + .io_ops = &spk_ttyio_ops, + .probe = spk_ttyio_synth_probe, + .release = spk_ttyio_release, + .synth_immediate = spk_ttyio_synth_immediate, .catch_up = spk_do_catch_up, .flush = spk_synth_flush, .is_alive = spk_synth_is_alive_restart,
PATCH v2 4/6 staging: speakup: add send_xchar, tiocmset and input functionality for tty
In reply to Okash KhawajaThis patch adds further TTY-based functionality, specifically implementation of send_xchar and tiocmset methods, and input. send_xchar and tiocmset methods simply delegate to corresponding TTY operations.
For input, it implements the receive_buf2 callback in tty_ldisc_ops of speakup's ldisc. If a synth defines read_buff_add method then receive_buf2 simply delegates to that and returns.
For spk_ttyio_in, the data is passed from receive_buf2 thread to spk_ttyio_in thread through spk_ldisc_data structure. It has following members:
- char buf: represents data received
- struct semaphore sem: used to signal to spk_ttyio_in thread that data is available to be read without having to busy wait
- bool buf_free: this is used in comination with mb() calls to syncronise the two threads over buf
receive_buf2 only writes to buf if buf_free is true. The check for buf_free and writing to buf are separated by mb() to ensure that spk_ttyio_in has read buf before receive_buf2 writes to it. After writing, it ups the semaphore to signal to spk_ttyio_in that there is now data to read.
spk_ttyio_in waits for data to read by downing the semaphore. Thus when signalled by receive_buf2 thread above, it reads from buf and sets buf_free to true. These two operations are separated by mb() to ensure that receive_buf2 thread finds buf_free to be true only after buf has been read. After that spk_ttyio_in calls tty_schedule_flip for subsequent data to come in through receive_buf2.
drivers/staging/speakup/spk_ttyio.c +107 -0
@@ -1,36 +1,97 @@#include <linux/types.h> #include <linux/tty.h> +#include <linux/tty_flip.h> +#include <linux/slab.h> #include "speakup.h" #include "spk_types.h" +#include "spk_priv.h" +struct spk_ldisc_data { +char buf; +struct semaphore sem; +bool buf_free; +}; + +static struct spk_synth *spk_ttyio_synth;static struct tty_struct *speakup_tty;static int spk_ttyio_ldisc_open (struct tty_struct *tty) { +struct spk_ldisc_data *ldisc_data; +if (tty->ops->write ==NULL )return -EOPNOTSUPP ; speakup_tty = tty; + ldisc_data =kmalloc (sizeof (struct spk_ldisc_data ),GFP_KERNEL ); +if (!ldisc_data) { +pr_err ("speakup: Failed to allocate ldisc_data.\n" ); +return -ENOMEM ; + } + +sema_init (&ldisc_data->sem,0 ); + ldisc_data->buf_free = true; + speakup_tty->disc_data = ldisc_data; +return 0 ; }static void spk_ttyio_ldisc_close (struct tty_struct *tty) { +kfree (speakup_tty->disc_data); speakup_tty =NULL ; } +static int spk_ttyio_receive_buf2 (struct tty_struct *tty, +const unsigned char *cp,char *fp,int count) +{ +struct spk_ldisc_data *ldisc_data = tty->disc_data; + +if (spk_ttyio_synth->read_buff_add) { +int i; +for (i =0 ; i < count; i++) + spk_ttyio_synth->read_buff_add (cp[i]); + +return count; + } + +if (!ldisc_data->buf_free) +/* ttyio_in will tty_schedule_flip */ +return 0 ; + +/* Make sure the consumer has read buf before we have seen +* buf_free == true and overwrite buf */ +mb (); + + ldisc_data->buf = cp[0 ]; + ldisc_data->buf_free = false; +up (&ldisc_data->sem); + +return 1 ; +} +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, + .receive_buf2 = spk_ttyio_receive_buf2, };static int spk_ttyio_out (struct spk_synth *in_synth,const char ch); +static void spk_ttyio_send_xchar (char ch); +static void spk_ttyio_tiocmset (unsigned int set,unsigned int clear); +static unsigned char spk_ttyio_in (void ); +static unsigned char spk_ttyio_in_nowait (void ); +struct spk_io_ops spk_ttyio_ops = { .synth_out = spk_ttyio_out, + .send_xchar = spk_ttyio_send_xchar, + .tiocmset = spk_ttyio_tiocmset, + .synth_in = spk_ttyio_in, + .synth_in_nowait = spk_ttyio_in_nowait, };EXPORT_SYMBOL_GPL (spk_ttyio_ops);
@@ -95,6 +156,51 @@return 0 ; } +static void spk_ttyio_send_xchar (char ch) +{ + speakup_tty->ops->send_xchar (speakup_tty, ch); +} + +static void spk_ttyio_tiocmset (unsigned int set,unsigned int clear) +{ + speakup_tty->ops->tiocmset (speakup_tty, set, clear); +} + +static unsigned char ttyio_in (int timeout) +{ +struct spk_ldisc_data *ldisc_data = speakup_tty->disc_data; +char rv; + +if (down_timeout (&ldisc_data->sem,usecs_to_jiffies (timeout)) == -ETIME ) { +if (timeout) +pr_warn ("spk_ttyio: timeout (%d) while waiting for input\n" , + timeout); +return 0xff ; + } + + rv = ldisc_data->buf; +/* Make sure we have read buf before we set buf_free to let +* the producer overwrite it */ +mb (); + ldisc_data->buf_free = true; +/* Let TTY push more characters */ +tty_schedule_flip (speakup_tty->port); + +return rv; +} + +static unsigned char spk_ttyio_in (void ) +{ +return ttyio_in (SPK_SYNTH_TIMEOUT ); +} + +static unsigned char spk_ttyio_in_nowait (void ) +{ +char rv =ttyio_in (0 ); + +return (rv ==0xff ) ?0 : rv; +} +int spk_ttyio_synth_probe (struct spk_synth *synth) {int rv =spk_ttyio_initialise_ldisc (synth->ser);
@@ -103,6 +209,7 @@return rv; synth->alive =1 ; + spk_ttyio_synth = synth;return 0 ; }
drivers/staging/speakup/serialio.h +3 -1
@@ -8,6 +8,8 @@#endif #include <linux/serial_core.h> +#include "spk_priv.h" +/* * this is cut&paste from 8250.h. Get rid of the structure, the definitions * and this whole broken driver.
@@ -21,7 +23,7 @@ };/* countdown values for serial timeouts in us */ -#define SPK_SERIAL_TIMEOUT 100000 +#define SPK_SERIAL_TIMEOUT SPK_SYNTH_TIMEOUT/* countdown values transmitter/dsr timeouts in us */ #define SPK_XMITR_TIMEOUT 100000/* countdown values cts timeouts in us */
drivers/staging/speakup/spk_priv.h +1 -0
@@ -39,6 +39,7 @@#endif #define KT_SPKUP 15 +#define SPK_SYNTH_TIMEOUT 100000/* in micro-seconds */ const struct old_serial_port *spk_serial_init (int index);void spk_stop_serial_interrupt (void );
PATCH v2 5/6 staging: speakup: migrate apollo, ltlk, audptr, decext, dectlk and spkout
In reply to Okash KhawajaThis patch simply uses the changes introduced in previous patches and migrates apollo, ltlk, audptr, decext, spkout and dectlk. Migrations are straightforward function pointer updates.
Signed-off by: Okash Khawaja <[email protected]>
drivers/staging/speakup/speakup_apollo.c +5 -5
@@ -22,9 +22,9 @@#include <linux/sched.h> #include <linux/timer.h> #include <linux/kthread.h> +#include <linux/serial_reg.h> /* for UART_MCR* constants */ #include "spk_priv.h" -#include "serialio.h" #include "speakup.h" #define DRV_VERSION "2.21"
@@ -108,10 +108,10 @@ .startup = SYNTH_START, .checkval = SYNTH_CHECK, .vars = vars, - .io_ops = &spk_serial_io_ops, - .probe = spk_serial_synth_probe, - .release = spk_serial_release, - .synth_immediate = spk_serial_synth_immediate, + .io_ops = &spk_ttyio_ops, + .probe = spk_ttyio_synth_probe, + .release = spk_ttyio_release, + .synth_immediate = spk_ttyio_synth_immediate, .catch_up = do_catch_up, .flush = spk_synth_flush, .is_alive = spk_synth_is_alive_restart,
drivers/staging/speakup/speakup_ltlk.c +4 -5
@@ -20,7 +20,6 @@*/ #include "speakup.h" #include "spk_priv.h" -#include "serialio.h" #include "speakup_dtlk.h" /* local header file for LiteTalk values */ #define DRV_VERSION "2.11"
@@ -111,10 +110,10 @@ .startup = SYNTH_START, .checkval = SYNTH_CHECK, .vars = vars, - .io_ops = &spk_serial_io_ops, + .io_ops = &spk_ttyio_ops, .probe = synth_probe, - .release = spk_serial_release, - .synth_immediate = spk_serial_synth_immediate, + .release = spk_ttyio_release, + .synth_immediate = spk_ttyio_synth_immediate, .catch_up = spk_do_catch_up, .flush = spk_synth_flush, .is_alive = spk_synth_is_alive_restart,
@@ -159,7 +158,7 @@ {int failed =0 ; - failed =spk_serial_synth_probe (synth); + failed =spk_ttyio_synth_probe (synth);if (failed ==0 )synth_interrogate (synth); synth->alive = !failed;
drivers/staging/speakup/speakup_audptr.c +4 -5
@@ -20,7 +20,6 @@*/ #include "spk_priv.h" #include "speakup.h" -#include "serialio.h" #define DRV_VERSION "2.11"#define SYNTH_CLEAR 0x18/* flush synth buffer */
@@ -104,10 +103,10 @@ .startup = SYNTH_START, .checkval = SYNTH_CHECK, .vars = vars, - .io_ops = &spk_serial_io_ops, + .io_ops = &spk_ttyio_ops, .probe = synth_probe, - .release = spk_serial_release, - .synth_immediate = spk_serial_synth_immediate, + .release = spk_ttyio_release, + .synth_immediate = spk_ttyio_synth_immediate, .catch_up = spk_do_catch_up, .flush = synth_flush, .is_alive = spk_synth_is_alive_restart,
@@ -154,7 +153,7 @@ {int failed; - failed =spk_serial_synth_probe (synth); + failed =spk_ttyio_synth_probe (synth);if (failed ==0 )synth_version (synth); synth->alive = !failed;
drivers/staging/speakup/speakup_decext.c +5 -5
@@ -24,12 +24,12 @@#include <linux/kthread.h> #include "spk_priv.h" -#include "serialio.h" #include "speakup.h" #define DRV_VERSION "2.14"#define SYNTH_CLEAR 0x03#define PROCSPEECH 0x0b +static volatile unsigned char last_char;static void read_buff_add (u_char ch)
@@ -123,10 +123,10 @@ .startup = SYNTH_START, .checkval = SYNTH_CHECK, .vars = vars, - .io_ops = &spk_serial_io_ops, - .probe = spk_serial_synth_probe, - .release = spk_serial_release, - .synth_immediate = spk_serial_synth_immediate, + .io_ops = &spk_ttyio_ops, + .probe = spk_ttyio_synth_probe, + .release = spk_ttyio_release, + .synth_immediate = spk_ttyio_synth_immediate, .catch_up = do_catch_up, .flush = synth_flush, .is_alive = spk_synth_is_alive_restart,
drivers/staging/speakup/speakup_spkout.c +4 -5
@@ -20,7 +20,6 @@*/ #include "spk_priv.h" #include "speakup.h" -#include "serialio.h" #define DRV_VERSION "2.11"#define SYNTH_CLEAR 0x18
@@ -102,10 +101,10 @@ .startup = SYNTH_START, .checkval = SYNTH_CHECK, .vars = vars, - .io_ops = &spk_serial_io_ops, - .probe = spk_serial_synth_probe, - .release = spk_serial_release, - .synth_immediate = spk_serial_synth_immediate, + .io_ops = &spk_ttyio_ops, + .probe = spk_ttyio_synth_probe, + .release = spk_ttyio_release, + .synth_immediate = spk_ttyio_synth_immediate, .catch_up = spk_do_catch_up, .flush = synth_flush, .is_alive = spk_synth_is_alive_restart,
drivers/staging/speakup/speakup_dectlk.c +4 -5
@@ -27,7 +27,6 @@#include <linux/kthread.h> #include "speakup.h" #include "spk_priv.h" -#include "serialio.h" #define DRV_VERSION "2.20"#define SYNTH_CLEAR 0x03
@@ -130,10 +129,10 @@ .vars = vars, .default_pitch = ap_defaults, .default_vol = g5_defaults, - .io_ops = &spk_serial_io_ops, - .probe = spk_serial_synth_probe, - .release = spk_serial_release, - .synth_immediate = spk_serial_synth_immediate, + .io_ops = &spk_ttyio_ops, + .probe = spk_ttyio_synth_probe, + .release = spk_ttyio_release, + .synth_immediate = spk_ttyio_synth_immediate, .catch_up = do_catch_up, .flush = synth_flush, .is_alive = spk_synth_is_alive_restart,
PATCH v2 6/6 staging: speakup: flush tty buffers and ensure hardware flow control
In reply to Okash KhawajaThis patch fixes the issue where TTY-migrated synths would take a while to shut up after hitting numpad enter key. When calling synth_flush, even though XOFF character is sent as high priority, data buffered in TTY layer is still sent to the synth. This patch flushes that buffered data when synth_flush is called.
It also tries to ensure that hardware flow control is enabled, by setting CRTSCTS using tty's termios.
drivers/staging/speakup/serialio.c +7 -0
@@ -30,6 +30,7 @@static void spk_serial_tiocmset (unsigned int set,unsigned int clear);static unsigned char spk_serial_in (void );static unsigned char spk_serial_in_nowait (void ); +static void spk_serial_flush_buffer (void );struct spk_io_ops spk_serial_io_ops = { .synth_out = spk_serial_out,
@@ -37,6 +38,7 @@ .tiocmset = spk_serial_tiocmset, .synth_in = spk_serial_in, .synth_in_nowait = spk_serial_in_nowait, + .flush_buffer = spk_serial_flush_buffer, };EXPORT_SYMBOL_GPL (spk_serial_io_ops);
@@ -268,6 +270,11 @@return inb_p (speakup_info.port_tts +UART_RX ); } +static void spk_serial_flush_buffer (void ) +{ +/* TODO: flush the UART 16550 buffer */ +} +static int spk_serial_out (struct spk_synth *in_synth,const char ch) {if (in_synth->alive &&spk_wait_for_xmitr (in_synth)) {
drivers/staging/speakup/spk_ttyio.c +29 -0
@@ -85,6 +85,7 @@static void spk_ttyio_tiocmset (unsigned int set,unsigned int clear);static unsigned char spk_ttyio_in (void );static unsigned char spk_ttyio_in_nowait (void ); +static void spk_ttyio_flush_buffer (void );struct spk_io_ops spk_ttyio_ops = { .synth_out = spk_ttyio_out,
@@ -92,13 +93,22 @@ .tiocmset = spk_ttyio_tiocmset, .synth_in = spk_ttyio_in, .synth_in_nowait = spk_ttyio_in_nowait, + .flush_buffer = spk_ttyio_flush_buffer, };EXPORT_SYMBOL_GPL (spk_ttyio_ops); +static inline void get_termios (struct tty_struct *tty,struct ktermios *out_termios) +{ +down_read (&tty->termios_rwsem); + *out_termios = tty->termios; +up_read (&tty->termios_rwsem); +} +static int spk_ttyio_initialise_ldisc (int ser) {int ret =0 ;struct tty_struct *tty; +struct ktermios tmp_termios; ret =tty_register_ldisc (N_SPEAKUP , &spk_ttyio_ldisc_ops);if (ret) {
@@ -127,6 +137,20 @@ }clear_bit (TTY_HUPPED , &tty->flags); +/* ensure hardware flow control is enabled */ +get_termios (tty, &tmp_termios); +if (!(tmp_termios.c_cflag &CRTSCTS )) { + tmp_termios.c_cflag |=CRTSCTS ; +tty_set_termios (tty, &tmp_termios); +/* +* check c_cflag to see if it's updated as tty_set_termios may not return +* error even when no tty bits are changed by the request. +*/ +get_termios (tty, &tmp_termios); +if (!(tmp_termios.c_cflag &CRTSCTS )) +pr_warn ("speakup: Failed to set hardware flow control\n" ); + } +tty_unlock (tty); ret =tty_set_ldisc (tty,N_SPEAKUP );
@@ -201,6 +225,11 @@return (rv ==0xff ) ?0 : rv; } +static void spk_ttyio_flush_buffer (void ) +{ + speakup_tty->ops->flush_buffer (speakup_tty); +} +int spk_ttyio_synth_probe (struct spk_synth *synth) {int rv =spk_ttyio_initialise_ldisc (synth->ser);
drivers/staging/speakup/spk_types.h +1 -0
@@ -154,6 +154,7 @@void (*tiocmset)(unsigned int set,unsigned int clear);unsigned char (*synth_in)(void );unsigned char (*synth_in_nowait)(void ); +void (*flush_buffer)(void ); };struct spk_synth {
drivers/staging/speakup/speakup_audptr.c +1 -0
@@ -127,6 +127,7 @@static void synth_flush (struct spk_synth *synth) { + synth->io_ops->flush_buffer (); synth->io_ops->send_xchar (SYNTH_CLEAR ); synth->io_ops->synth_out (synth,PROCSPEECH ); }
drivers/staging/speakup/speakup_decext.c +1 -0
@@ -221,6 +221,7 @@static void synth_flush (struct spk_synth *synth) { in_escape =0 ; + synth->io_ops->flush_buffer (); synth->synth_immediate (synth,"\033P;10z\033\\" ); }
drivers/staging/speakup/speakup_dectlk.c +1 -0
@@ -293,6 +293,7 @@ synth->io_ops->synth_out (synth,']' ); in_escape =0 ; is_flushing =1 ; + synth->io_ops->flush_buffer (); synth->io_ops->synth_out (synth,SYNTH_CLEAR ); }
drivers/staging/speakup/speakup_spkout.c +1 -0
@@ -125,6 +125,7 @@static void synth_flush (struct spk_synth *synth) { + synth->io_ops->flush_buffer (); synth->io_ops->send_xchar (SYNTH_CLEAR ); }
drivers/staging/speakup/synth.c +1 -0
@@ -120,6 +120,7 @@void spk_synth_flush (struct spk_synth *synth) { + synth->io_ops->flush_buffer (); synth->io_ops->synth_out (synth, synth->clear); }EXPORT_SYMBOL_GPL (spk_synth_flush);
Greg Kroah-Hartman
maintainerRe: [patch v2 6/6] staging: speakup: flush tty buffers and ensure hardware flow control
Quoted 1 line · Okash Khawaja
This patch fixes the issue where TTY-migrated synths would take a while to shut up after hitting numpad enter key. When calling
synth_flush, even though XOFF character is sent as high priority, data buffered in TTY layer is still sent to the synth. This patch flushes that buffered data whensynth_flushis called.
Minor nit, please line-wrap your changelog text at 72 columns so that I don't have to do it "by hand".
Quoted 9 lines
It also tries to ensure that hardware flow control is enabled, by setting CRTSCTS using tty's termios.
Reported-by John Covici <[email protected]>Signed-off-by Okash Khawaja <[email protected]>Reviewed-by Samuel Thibault <[email protected]>Index:
linux-staging/drivers/staging/speakup/serialio.c
===================================================================
Are you using git? These lines are odd...
thanks,
greg k-h
Re: [patch v2 6/6] staging: speakup: flush tty buffers and ensure hardware flow control
Hi,
Quoted 5 lines · Greg Kroah-Hartman
Quoted 1 line · Okash Khawaja
This patch fixes the issue where TTY-migrated synths would take a while to shut up after hitting numpad enter key. When calling
synth_flush, even though XOFF character is sent as high priority, data buffered in TTY layer is still sent to the synth. This patch flushes that buffered data whensynth_flushis called.Minor nit, please line-wrap your changelog text at 72 columns so that I don't have to do it "by hand".
Sure, will do.
Quoted 4 lines
Quoted 4 lines
It also tries to ensure that hardware flow control is enabled, by setting CRTSCTS using tty's termios.
Quoted 8 lines
Quoted 6 lines
Reported-by John Covici <[email protected]>Signed-off-by Okash Khawaja <[email protected]>Reviewed-by Samuel Thibault <[email protected]>Index:
linux-staging/drivers/staging/speakup/serialio.c
===================================================================Are you using git? These lines are odd...
They come from quilt. Haven't checked yet if there is an option to turn them off.
Thanks,
Okash
Greg Kroah-Hartman
maintainerRe: [patch v2 6/6] staging: speakup: flush tty buffers and ensure hardware flow control
Quoted 19 lines · Okash Khawaja
Hi,
Quoted 5 lines · Greg Kroah-Hartman
Quoted 1 line · Okash Khawaja
This patch fixes the issue where TTY-migrated synths would take a while to shut up after hitting numpad enter key. When calling
synth_flush, even though XOFF character is sent as high priority, data buffered in TTY layer is still sent to the synth. This patch flushes that buffered data whensynth_flushis called.Minor nit, please line-wrap your changelog text at 72 columns so that I don't have to do it "by hand".
Sure, will do.
Quoted 8 lines
Quoted 8 lines
It also tries to ensure that hardware flow control is enabled, by setting CRTSCTS using tty's termios.
Reported-by John Covici <[email protected]>Signed-off-by Okash Khawaja <[email protected]>Reviewed-by Samuel Thibault <[email protected]>
Quoted 6 lines
Quoted 4 lines
Quoted 2 lines
Index:
linux-staging/drivers/staging/speakup/serialio.c
===================================================================Are you using git? These lines are odd...
They come from quilt. Haven't checked yet if there is an option to turn them off.
There is, here's what is in my .quiltrc:
QUILT_REFRESH_ARGS="--diffstat --strip-trailing-whitespace --no-timestamps --no-index --sort -p1 -p ab" QUILT_DIFF_ARGS="--no-timestamps --no-index --sort --color=auto -p ab" QUILT_DIFF_OPTS="-p"
That will give you the diffstat in the patch as well, which is always helpful to reviewers.
thanks,
greg k-h
Re: [patch v2 6/6] staging: speakup: flush tty buffers and ensure hardware flow control
Quoted 30 lines · Greg Kroah-Hartman
Quoted 21 lines · Okash Khawaja
Hi,
Quoted 5 lines · Greg Kroah-Hartman
Quoted 1 line · Okash Khawaja
This patch fixes the issue where TTY-migrated synths would take a while to shut up after hitting numpad enter key. When calling
synth_flush, even though XOFF character is sent as high priority, data buffered in TTY layer is still sent to the synth. This patch flushes that buffered data whensynth_flushis called.Minor nit, please line-wrap your changelog text at 72 columns so that I don't have to do it "by hand".
Sure, will do.
Quoted 8 lines
Quoted 8 lines
It also tries to ensure that hardware flow control is enabled, by setting CRTSCTS using tty's termios.
Reported-by John Covici <[email protected]>Signed-off-by Okash Khawaja <[email protected]>Reviewed-by Samuel Thibault <[email protected]>Quoted 6 lines
Quoted 4 lines
Quoted 2 lines
Index:
linux-staging/drivers/staging/speakup/serialio.c
===================================================================Are you using git? These lines are odd...
They come from quilt. Haven't checked yet if there is an option to turn them off.
Quoted 8 lines
There is, here's what is in my .quiltrc:
QUILT_REFRESH_ARGS="--diffstat --strip-trailing-whitespace --no-timestamps --no-index --sort -p1 -p ab" QUILT_DIFF_ARGS="--no-timestamps --no-index --sort --color=auto -p ab" QUILT_DIFF_OPTS="-p"
That will give you the diffstat in the patch as well, which is always helpful to reviewers.
Thanks very much. Will update mine.