[parisc-linux-cvs] Wrapper for ioctl(fd, TIOCGSERIAL ...

Richard Hirst rhirst@linuxcare.com
Fri, 18 May 2001 16:13:01 +0100


Oops, forgot to send this earlier

Index: arch/parisc/kernel/ioctl32.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/kernel/ioctl32.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- ioctl32.c   2001/03/27 20:08:22     1.3
+++ ioctl32.c   2001/05/18 08:17:48     1.4
@@ -1,4 +1,4 @@
-/* $Id: ioctl32.c,v 1.3 2001/03/27 20:08:22 bame Exp $
+/* $Id: ioctl32.c,v 1.4 2001/05/18 08:17:48 rhirst Exp $
  * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
  *
  * Copyright (C) 1997-2000  Jakub Jelinek  (jakub@redhat.com)
@@ -50,6 +50,7 @@
 #include <linux/blk.h>
 #include <linux/elevator.h>
 #include <linux/rtc.h>
+#include <linux/serial.h>
 #if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
 /* Ugh. This header really is not clean */
 #define min min
@@ -2697,6 +2698,52 @@
        return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg);
 }
 
+
+struct serial_struct32 {
+       int     type;
+       int     line;
+       unsigned int    port;
+       int     irq;
+       int     flags;
+       int     xmit_fifo_size;
+       int     custom_divisor;
+       int     baud_base;
+       unsigned short  close_delay;
+       char    io_type;
+       char    reserved_char[1];
+       int     hub6;
+       unsigned short  closing_wait; /* time to wait before closing */
+       unsigned short  closing_wait2; /* no longer used... */
+       unsigned int    iomem_base;     /* char * really */
+       unsigned short  iomem_reg_shift;
+       unsigned int    port_high;
+       int     reserved[1];
+};
+
+static int do_tiocgserial(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+       struct serial_struct ss;
+       int ret;
+       struct serial_struct32 * uptr = (struct serial_struct32 *)arg;
+       mm_segment_t old_fs = get_fs();
+
+       set_fs (KERNEL_DS);
+       ret = sys_ioctl(fd, cmd, (unsigned long) &ss);
+       set_fs(old_fs);
+
+       if (!ret) {
+               /* structs match up to iomem_base */
+               ret = copy_to_user(uptr, &ss, sizeof(struct serial_struct32));
+               ret |= put_user(ss.iomem_base, &uptr->iomem_base);
+               ret |= put_user(ss.iomem_reg_shift, &uptr->iomem_reg_shift);
+               ret |= put_user(ss.port_high, &uptr->port_high);
+               if (ret)
+                       ret = -EFAULT;
+       }
+       return ret;
+}
+
+
 struct ioctl_trans {
        unsigned long handler;
        unsigned int cmd;
@@ -2750,7 +2797,6 @@
 COMPATIBLE_IOCTL(TIOCSCTTY)
 COMPATIBLE_IOCTL(TIOCGPTN)
 COMPATIBLE_IOCTL(TIOCSPTLCK)
-COMPATIBLE_IOCTL(TIOCGSERIAL)
 COMPATIBLE_IOCTL(TIOCSSERIAL)
 COMPATIBLE_IOCTL(TIOCSERGETLSR)
 /* Big F */
@@ -3246,6 +3292,7 @@
 COMPATIBLE_IOCTL(BLKELVGET)
 COMPATIBLE_IOCTL(BLKELVSET)
 /* And these ioctls need translation */
+HANDLE_IOCTL(TIOCGSERIAL, do_tiocgserial)
 HANDLE_IOCTL(SIOCGIFNAME, dev_ifname32)
 HANDLE_IOCTL(SIOCGIFCONF, dev_ifconf)
 HANDLE_IOCTL(SIOCGIFFLAGS, dev_ifsioc)