[PATCH 22/25] serial: move ioctl32 code to tty_io.c

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

 



All driver implementing TIOCGSERIAL are tty drivers, so
the conversion handler can be part of tty_compat_ioctl.

In a perfect world, this would live in serial_core.c, but
there are still a number of drivers that are not moved
over to use that yet. If it were in serial_core, it
could also live without the get_fs/set_fs hacks.

CC: [email protected]
CC: [email protected]
Signed-off-by: Arnd Bergmann <[email protected]>

Index: linux-cg/drivers/char/tty_io.c
===================================================================
--- linux-cg.orig/drivers/char/tty_io.c	2005-11-05 14:22:34.000000000 +0100
+++ linux-cg/drivers/char/tty_io.c	2005-11-05 15:42:22.000000000 +0100
@@ -104,7 +104,6 @@
 #include <linux/vt_kern.h>
 #include <linux/selection.h>
 #include <linux/devfs_fs_kernel.h>
-
 #include <linux/kmod.h>
 
 #undef TTY_DEBUG_HANGUP
@@ -153,7 +152,7 @@
 static int tty_release(struct inode *, struct file *);
 int tty_ioctl(struct inode * inode, struct file * file,
 	      unsigned int cmd, unsigned long arg);
-long tty_compat_ioctl(struct file * file, unsigned int cmd, unsigned long arg);
+static long tty_compat_ioctl(struct file * file, unsigned int cmd, unsigned long arg);
 static int tty_fasync(int fd, struct file * filp, int on);
 static void release_mem(struct tty_struct *tty, int idx);
 
@@ -2437,7 +2436,75 @@
 
 
 #ifdef CONFIG_COMPAT
-long tty_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+#include <linux/serial.h>
+
+struct serial_struct32 {
+	compat_int_t type;
+	compat_int_t line;
+	compat_uint_t port;
+	compat_int_t irq;
+	compat_int_t flags;
+	compat_int_t xmit_fifo_size;
+	compat_int_t custom_divisor;
+	compat_int_t baud_base;
+	unsigned short close_delay;
+	char io_type;
+	char reserved_char[1];
+	compat_int_t hub6;
+	unsigned short closing_wait;	/* time to wait before closing */
+	unsigned short closing_wait2;	/* no longer used... */
+	compat_uint_t iomem_base;
+	unsigned short iomem_reg_shift;
+	unsigned int port_high;
+	/* compat_ulong_t  iomap_base FIXME */
+	compat_int_t reserved[1];
+};
+
+static int serial_struct_ioctl(struct inode *inode, struct file *file,
+				unsigned cmd, unsigned long arg)
+{
+	typedef struct serial_struct SS;
+	typedef struct serial_struct32 SS32;
+	struct serial_struct32 __user *ss32 = compat_ptr(arg);
+	int err;
+	struct serial_struct ss;
+	mm_segment_t oldseg = get_fs();
+	__u32 udata;
+
+	if (cmd == TIOCSSERIAL) {
+		if (!access_ok(VERIFY_READ, ss32, sizeof(SS32)))
+			return -EFAULT;
+		if (__copy_from_user
+		    (&ss, ss32, offsetof(SS32, iomem_base)))
+			return -EFAULT;
+		__get_user(udata, &ss32->iomem_base);
+		ss.iomem_base = compat_ptr(udata);
+		__get_user(ss.iomem_reg_shift, &ss32->iomem_reg_shift);
+		__get_user(ss.port_high, &ss32->port_high);
+		ss.iomap_base = 0UL;
+	}
+	set_fs(KERNEL_DS);
+	lock_kernel();
+	err = tty_ioctl(inode, file, cmd, (unsigned long) (&ss));
+	unlock_kernel();
+	set_fs(oldseg);
+	if (cmd == TIOCGSERIAL && err >= 0) {
+		if (!access_ok(VERIFY_WRITE, ss32, sizeof(SS32)))
+			return -EFAULT;
+		if (__copy_to_user(ss32, &ss, offsetof(SS32, iomem_base)))
+			return -EFAULT;
+		__put_user((unsigned long) ss.iomem_base >> 32 ?
+			   0xffffffff : (unsigned) (unsigned long) ss.
+			   iomem_base, &ss32->iomem_base);
+		__put_user(ss.iomem_reg_shift, &ss32->iomem_reg_shift);
+		__put_user(ss.port_high, &ss32->port_high);
+
+	}
+	return err;
+}
+
+static long tty_compat_ioctl(struct file *file, unsigned int cmd,
+				unsigned long arg)
 {
 	struct inode *inode = file->f_dentry->d_inode;
 	struct tty_struct *tty;
@@ -2499,6 +2566,14 @@
 	/* enter the native code path for those numbers known
 	 * to be compatible */
 	switch (cmd) {
+	case TIOCGSERIAL:
+	case TIOCSSERIAL:
+		ret = serial_struct_ioctl(inode, file, cmd, arg);
+		break;
+#ifdef TIOCGLTC
+	case TIOCGLTC:
+	case TIOCSLTC:
+#endif
 	case TCFLSH:
 	case TCGETA:
 	case TCGETS:
Index: linux-cg/fs/compat_ioctl.c
===================================================================
--- linux-cg.orig/fs/compat_ioctl.c	2005-11-05 14:47:57.000000000 +0100
+++ linux-cg/fs/compat_ioctl.c	2005-11-05 15:46:46.000000000 +0100
@@ -356,67 +356,6 @@
 #define HIDPGETCONNLIST	_IOR('H', 210, int)
 #define HIDPGETCONNINFO	_IOR('H', 211, int)
 
-struct serial_struct32 {
-        compat_int_t    type;
-        compat_int_t    line;
-        compat_uint_t   port;
-        compat_int_t    irq;
-        compat_int_t    flags;
-        compat_int_t    xmit_fifo_size;
-        compat_int_t    custom_divisor;
-        compat_int_t    baud_base;
-        unsigned short  close_delay;
-        char    io_type;
-        char    reserved_char[1];
-        compat_int_t    hub6;
-        unsigned short  closing_wait; /* time to wait before closing */
-        unsigned short  closing_wait2; /* no longer used... */
-        compat_uint_t   iomem_base;
-        unsigned short  iomem_reg_shift;
-        unsigned int    port_high;
-     /* compat_ulong_t  iomap_base FIXME */
-        compat_int_t    reserved[1];
-};
-
-static int serial_struct_ioctl(unsigned fd, unsigned cmd, unsigned long arg)
-{
-        typedef struct serial_struct SS;
-        typedef struct serial_struct32 SS32;
-        struct serial_struct32 __user *ss32 = compat_ptr(arg);
-        int err;
-        struct serial_struct ss;
-        mm_segment_t oldseg = get_fs();
-        __u32 udata;
-
-        if (cmd == TIOCSSERIAL) {
-                if (!access_ok(VERIFY_READ, ss32, sizeof(SS32)))
-                        return -EFAULT;
-                if (__copy_from_user(&ss, ss32, offsetof(SS32, iomem_base)))
-			return -EFAULT;
-                __get_user(udata, &ss32->iomem_base);
-                ss.iomem_base = compat_ptr(udata);
-                __get_user(ss.iomem_reg_shift, &ss32->iomem_reg_shift);
-                __get_user(ss.port_high, &ss32->port_high);
-                ss.iomap_base = 0UL;
-        }
-        set_fs(KERNEL_DS);
-                err = sys_ioctl(fd,cmd,(unsigned long)(&ss));
-        set_fs(oldseg);
-        if (cmd == TIOCGSERIAL && err >= 0) {
-                if (!access_ok(VERIFY_WRITE, ss32, sizeof(SS32)))
-                        return -EFAULT;
-                if (__copy_to_user(ss32,&ss,offsetof(SS32,iomem_base)))
-			return -EFAULT;
-                __put_user((unsigned long)ss.iomem_base  >> 32 ?
-                            0xffffffff : (unsigned)(unsigned long)ss.iomem_base,
-                            &ss32->iomem_base);
-                __put_user(ss.iomem_reg_shift, &ss32->iomem_reg_shift);
-                __put_user(ss.port_high, &ss32->port_high);
-
-        }
-        return err;
-}
-
 #undef CODE
 #endif
 
@@ -425,13 +364,5 @@
 HANDLE_IOCTL(MTIOCPOS32, mt_ioctl_trans)
 HANDLE_IOCTL(CDROMREADAUDIO, cdrom_ioctl_trans)
 HANDLE_IOCTL(CDROM_SEND_PACKET, cdrom_ioctl_trans)
-/* Serial */
-HANDLE_IOCTL(TIOCGSERIAL, serial_struct_ioctl)
-HANDLE_IOCTL(TIOCSSERIAL, serial_struct_ioctl)
-#ifdef TIOCGLTC
-COMPATIBLE_IOCTL(TIOCGLTC)
-COMPATIBLE_IOCTL(TIOCSLTC)
-#endif
-
 #undef DECLARES
 #endif

--

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux