[PATCH 2/3] input: serio: allow more than one byte to be sent at once

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



serio drivers can only send one byte at a time. If the underlying tty
is a usb serial port, then each byte will be put into separate usb
urbs, which is not efficient.

Additionally, the Infrared Toy device refuses to transmit IR if the
IR data is sent one byte at a time. IR data is formatted in u16 values,
and the firmware expects complete u16 values in the packet.

https://github.com/DangerousPrototypes/USB_IR_Toy/blob/master/Firmware-main/IRs.c#L240

Signed-off-by: Sean Young <sean@xxxxxxxx>
---
 drivers/input/serio/serport.c |  9 +++++++++
 include/linux/serio.h         | 23 ++++++++++++++++++++++-
 2 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c
index 8ac970a423de6..887801691dddc 100644
--- a/drivers/input/serio/serport.c
+++ b/drivers/input/serio/serport.c
@@ -47,6 +47,14 @@ static int serport_serio_write(struct serio *serio, unsigned char data)
 	return -(serport->tty->ops->write(serport->tty, &data, 1) != 1);
 }
 
+static int serport_serio_write_buf(struct serio *serio, unsigned char *data,
+				   uint count)
+{
+	struct serport *serport = serio->port_data;
+
+	return -(serport->tty->ops->write(serport->tty, data, count) != count);
+}
+
 static int serport_serio_open(struct serio *serio)
 {
 	struct serport *serport = serio->port_data;
@@ -173,6 +181,7 @@ static ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file, u
 	serio->id = serport->id;
 	serio->id.type = SERIO_RS232;
 	serio->write = serport_serio_write;
+	serio->write_buf = serport_serio_write_buf;
 	serio->open = serport_serio_open;
 	serio->close = serport_serio_close;
 	serio->port_data = serport;
diff --git a/include/linux/serio.h b/include/linux/serio.h
index 6c27d413da921..3918e56aec51c 100644
--- a/include/linux/serio.h
+++ b/include/linux/serio.h
@@ -32,6 +32,7 @@ struct serio {
 	spinlock_t lock;
 
 	int (*write)(struct serio *, unsigned char);
+	int (*write_buf)(struct serio *serio, unsigned char *buf, uint size);
 	int (*open)(struct serio *);
 	void (*close)(struct serio *);
 	int (*start)(struct serio *);
@@ -121,12 +122,32 @@ void serio_unregister_driver(struct serio_driver *drv);
 
 static inline int serio_write(struct serio *serio, unsigned char data)
 {
-	if (serio->write)
+	if (serio->write_buf)
+		return serio->write_buf(serio, &data, 1);
+	else if (serio->write)
 		return serio->write(serio, data);
 	else
 		return -1;
 }
 
+static inline int serio_write_buf(struct serio *serio, unsigned char *data,
+				  uint size)
+{
+	if (serio->write_buf) {
+		return serio->write_buf(serio, data, size);
+	} else if (serio->write) {
+		int ret;
+
+		do {
+			ret = serio->write(serio, *data++);
+		} while (ret == 0 && --size);
+
+		return ret;
+	} else {
+		return -1;
+	}
+}
+
 static inline void serio_drv_write_wakeup(struct serio *serio)
 {
 	if (serio->drv && serio->drv->write_wakeup)
-- 
2.26.2




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux