Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 3772

kernel-2.6.18-194.11.1.el5.src.rpm

From: Aristeu Rozanski <aris@redhat.com>
Date: Tue, 2 Sep 2008 15:37:13 -0400
Subject: [tty] add termiox support
Message-id: 20080902193713.GF10700@redhat.com
O-Subject: [RHEL5.3 PATCH 1/2] tty: add termiox support v3
Bugzilla: 445211
RH-Acked-by: Mauro Carvalho Chehab <mchehab@redhat.com>

https://bugzilla.redhat.com/show_bug.cgi?id=445211

This is a preparation patch for adding support for DTR/DSR serial flow control.
This is the interface that is going to be upstream (TC{G,S}ETX* ioctls).

kabi: just like done with the shutdown() method, this patch adds two new
elements to tty_driver and a respective flag to indicate the driver supports
it.

Tested locally with serial console and a Point of Sale Printer (as many
probably heard)

Updated: using __GENKSYMS__ and fixed the build on different architectures

Original upstream commit (in linux-next now):

>From f810b01cbdf82d7627c000dd5945a236d5c496a1 Mon Sep 17 00:00:00 2001
From: Alan Cox <alan@redhat.com>
Date: Sat, 23 Aug 2008 20:22:35 +1000
Subject: [PATCH] tty-add-termiox

We need a way to describe the various additional modes and flow control
features that random weird hardware shows up and software such as wine
wants to emulate as Windows supports them.

TCGETX/TCSETX and the termiox ioctl are a SYS5 extension that we might as
well adopt. This patches adds the structures and the basic ioctl interfaces
when the TCGETX etc defines are added for an architecture. Drivers wishing
to use this stuff need to add new methods.

Signed-off-by: Alan Cox <alan@redhat.com>

diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index 3b6fa7b..dc25af0 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -418,6 +418,61 @@ static int set_ltchars(struct tty_struct * tty, struct ltchars __user * ltchars)
 }
 #endif
 
+static int get_termiox(struct tty_struct *tty, void __user *arg)
+{
+	struct termiox tx;
+
+	if (!(tty->driver->flags & TTY_DRIVER_HAS_TERMIOX))
+		return -EINVAL;
+
+	memset(&tx, 0, sizeof(tx));
+	tty->driver->get_termiox(tty, &tx);
+	if (copy_to_user(arg, &tx, sizeof(struct termiox)))
+		return -EFAULT;
+
+	return 0;
+}
+
+/**
+ *	set_termiox	-	set termiox fields if possible
+ *	@tty: terminal
+ *	@arg: termiox structure from user
+ *	@opt: option flags for ioctl type
+ *
+ *	Implement the device calling points for the SYS5 termiox ioctl
+ *	interface in Linux
+ */
+
+static int set_termiox(struct tty_struct *tty, void __user *arg, int opt)
+{
+	struct termiox tnew;
+	struct tty_ldisc *ld;
+	int ret, i;
+
+	if (!(tty->driver->flags & TTY_DRIVER_HAS_TERMIOX))
+		return -EINVAL;
+
+	if (copy_from_user(&tnew, arg, sizeof(struct termiox)))
+		return -EFAULT;
+
+	ld = tty_ldisc_ref(tty);
+	if (ld != NULL) {
+		if ((opt & TERMIOS_FLUSH) && ld->flush_buffer)
+			ld->flush_buffer(tty);
+		tty_ldisc_deref(ld);
+	}
+	if (opt & TERMIOS_WAIT) {
+		tty_wait_until_sent(tty, 0);
+		if (signal_pending(current))
+			return -EINTR;
+	}
+
+	ret = tty->driver->set_termiox(tty, &tnew);
+	mutex_unlock(&tty->termios_mutex);
+
+	return ret;
+}
+
 /**
  *	send_prio_char		-	send priority character
  *
@@ -592,6 +647,16 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file,
 				tty->packet = 0;
 			return 0;
 		}
+#ifdef TCGETX
+		case TCGETX:
+			return get_termiox(tty, p);
+		case TCSETX:
+			return set_termiox(tty, p, 0);
+		case TCSETXW:
+			return set_termiox(tty, p, TERMIOS_WAIT);
+		case TCSETXF:
+			return set_termiox(tty, p, TERMIOS_FLUSH);
+#endif
 		case TIOCGSOFTCAR:
 			return put_user(C_CLOCAL(tty) ? 1 : 0, (int __user *)arg);
 		case TIOCSSOFTCAR:
diff --git a/include/asm-i386/ioctls.h b/include/asm-i386/ioctls.h
index f962fad..0c21b60 100644
--- a/include/asm-i386/ioctls.h
+++ b/include/asm-i386/ioctls.h
@@ -50,6 +50,11 @@
 #define TIOCGPTN	_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
 #define TIOCSPTLCK	_IOW('T',0x31, int)  /* Lock/unlock Pty */
 
+#define TCGETX		0x5432 /* SYS5 TCGETX compatibility */
+#define TCSETX		0x5433
+#define TCSETXF		0x5434
+#define TCSETXW		0x5435
+
 #define FIONCLEX	0x5450
 #define FIOCLEX		0x5451
 #define FIOASYNC	0x5452
diff --git a/include/asm-x86_64/ioctls.h b/include/asm-x86_64/ioctls.h
index 62caf8b..1df9b15 100644
--- a/include/asm-x86_64/ioctls.h
+++ b/include/asm-x86_64/ioctls.h
@@ -49,6 +49,11 @@
 #define TIOCGPTN	_IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
 #define TIOCSPTLCK	_IOW('T',0x31, int)  /* Lock/unlock Pty */
 
+#define TCGETX		0x5432 /* SYS5 TCGETX compatibility */
+#define TCSETX		0x5433
+#define TCSETXF		0x5434
+#define TCSETXW		0x5435
+
 #define FIONCLEX	0x5450  /* these numbers need to be adjusted. */
 #define FIOCLEX		0x5451
 #define FIOASYNC	0x5452
diff --git a/include/linux/termios.h b/include/linux/termios.h
index 4786628..2acd0c1 100644
--- a/include/linux/termios.h
+++ b/include/linux/termios.h
@@ -4,4 +4,19 @@
 #include <linux/types.h>
 #include <asm/termios.h>
 
+#define NFF	5
+
+struct termiox
+{
+	__u16	x_hflag;
+	__u16	x_cflag;
+	__u16	x_rflag[NFF];
+	__u16	x_sflag;
+};
+
+#define	RTSXOFF		0x0001		/* RTS flow control on input */
+#define	CTSXON		0x0002		/* CTS flow control on output */
+#define	DTRXOFF		0x0004		/* DTR flow control on input */
+#define DSRXON		0x0008		/* DCD flow control on output */
+
 #endif
diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h
index 2846f11..247b1ca 100644
--- a/include/linux/tty_driver.h
+++ b/include/linux/tty_driver.h
@@ -215,6 +215,8 @@ struct tty_driver {
 	struct list_head tty_drivers;
 #ifndef __GENKSYMS__
 	void (*shutdown)(struct tty_struct *tty);
+	int (*set_termiox)(struct tty_struct *tty, struct termiox *old);
+	void (*get_termiox)(struct tty_struct *tty, struct termiox *tx);
 #endif
 };
 
@@ -261,6 +263,7 @@ void tty_shutdown(struct tty_struct *tty);
  *	is only applicable to the pty driver.
  * TTY_DRIVER_HAS_SHUTDOWN - if the driver implements the shutdown()
  *	function
+ * TTY_DRIVER_HAS_TERMIOX - if the driver implements the termiox ioctls
  */
 #define TTY_DRIVER_INSTALLED		0x0001
 #define TTY_DRIVER_RESET_TERMIOS	0x0002
@@ -268,6 +271,7 @@ void tty_shutdown(struct tty_struct *tty);
 #define TTY_DRIVER_DYNAMIC_DEV		0x0008
 #define TTY_DRIVER_DEVPTS_MEM		0x0010
 #define TTY_DRIVER_HAS_SHUTDOWN		0x0020
+#define TTY_DRIVER_HAS_TERMIOX		0x0040
 
 /* tty driver types */
 #define TTY_DRIVER_TYPE_SYSTEM		0x0001