netdev
[Top] [All Lists]

[PATCH] Add 32bit emulation for wireless

To: netdev@xxxxxxxxxxx, jt@xxxxxxxxxx
Subject: [PATCH] Add 32bit emulation for wireless
From: Andi Kleen <ak@xxxxxxxxxxxxx>
Date: 19 Jan 2004 13:33:43 +0100
Date: Mon, 19 Jan 2004 13:33:43 +0100
Sender: netdev-bounce@xxxxxxxxxxx
User-agent: Mutt/1.4.1i
[First version of this mail seems to have gotten lost. Apologies if you
see it twice]

Some distributions call iwconfig at every bootup and I was sick of 
seeing all the unimplemented ioctl messages on AMD64 with a 32bit userland.

This patch implements ioctl emulation for the wireless subsytem.
The only structure that was incompatible from visual inspection was
"iw_point". The rest is just passed through.

It reuses the existing ioctl description table, but renames it to 
export it (standard_ioctls wasn't a good name for a global variable) 

I don't actually have have a working wireless card (only some non supported
Samsung one), so I wasn't able to test it, but at least the messages
are gone.

-Andi

diff -u linux-2.6.1-amd64/net/core/wireless.c-WIRELESS 
linux-2.6.1-amd64/net/core/wireless.c
--- linux-2.6.1-amd64/net/core/wireless.c-WIRELESS      2003-10-09 
00:29:02.000000000 +0200
+++ linux-2.6.1-amd64/net/core/wireless.c       2004-01-17 18:46:58.000000000 
+0100
@@ -27,7 +27,7 @@
  *     o Initial dumb commit strategy based on orinoco.c
  *
  * v3 - 19.12.01 - Jean II
- *     o Make sure we don't go out of standard_ioctl[] in ioctl_standard_call
+ *     o Make sure we don't go out of wireless_ioctl[] in ioctl_standard_call
  *     o Add event dispatcher function
  *     o Add event description
  *     o Propagate events as rtnetlink IFLA_WIRELESS option
@@ -91,7 +91,7 @@
  * Meta-data about all the standard Wireless Extension request we
  * know about.
  */
-static const struct iw_ioctl_description standard_ioctl[] = {
+const struct iw_ioctl_description wireless_ioctl[] = {
        [SIOCSIWCOMMIT  - SIOCIWFIRST] = {
                .header_type    = IW_HEADER_TYPE_NULL,
        },
@@ -266,7 +266,7 @@
                .header_type    = IW_HEADER_TYPE_PARAM,
        },
 };
-static const int standard_ioctl_num = (sizeof(standard_ioctl) /
+const int wireless_ioctl_num = (sizeof(wireless_ioctl) /
                                       sizeof(struct iw_ioctl_description));
 
 /*
@@ -593,9 +593,9 @@
        int                                     user_size = 0;
 
        /* Get the description of the IOCTL */
-       if((cmd - SIOCIWFIRST) >= standard_ioctl_num)
+       if((cmd - SIOCIWFIRST) >= wireless_ioctl_num)
                return -EOPNOTSUPP;
-       descr = &(standard_ioctl[cmd - SIOCIWFIRST]);
+       descr = &(wireless_ioctl[cmd - SIOCIWFIRST]);
 
 #ifdef WE_IOCTL_DEBUG
        printk(KERN_DEBUG "%s (WE) : Found standard handler for 0x%04X\n",
@@ -1041,8 +1041,8 @@
        /* Get the description of the IOCTL */
        if(cmd <= SIOCIWLAST) {
                cmd_index = cmd - SIOCIWFIRST;
-               if(cmd_index < standard_ioctl_num)
-                       descr = &(standard_ioctl[cmd_index]);
+               if(cmd_index < wireless_ioctl_num)
+                       descr = &(wireless_ioctl[cmd_index]);
        } else {
                cmd_index = cmd - IWEVFIRST;
                if(cmd_index < standard_event_num)
diff -u linux-2.6.1-amd64/fs/compat_ioctl.c-WIRELESS 
linux-2.6.1-amd64/fs/compat_ioctl.c
--- linux-2.6.1-amd64/fs/compat_ioctl.c-WIRELESS        2004-01-01 
06:25:25.000000000 +0100
+++ linux-2.6.1-amd64/fs/compat_ioctl.c 2004-01-17 19:02:44.000000000 +0100
@@ -65,6 +65,8 @@
 #include <linux/ncp_fs.h>
 #include <linux/i2c.h>
 #include <linux/i2c-dev.h>
+#include <linux/wireless.h>
+#include <net/iw_handler.h>
 
 #include <net/sock.h>          /* siocdevprivate_ioctl */
 #include <net/bluetooth/bluetooth.h>
@@ -706,6 +708,69 @@
        return err;
 }
 
+#ifdef CONFIG_NET_RADIO
+
+extern const struct iw_ioctl_description wireless_ioctl[];
+extern int wireless_ioctl_num;
+
+/* assumes no padding */
+struct iw_point32 { 
+       compat_uptr_t pointer;
+       u16 length;
+       u16 flags; 
+}; 
+
+struct iwreq32 { 
+       char ifrn_name[IFNAMSIZ]; 
+       struct iw_point32 iw_point; 
+};
+
+static int wireless_ioctl32(unsigned int fd, unsigned int cmd, unsigned long 
arg)
+{ 
+       int num = cmd - SIOCIWFIRSTPRIV;
+       if (num >= wireless_ioctl_num) { 
+               printk(KERN_DEBUG "%s: unknown wireless ioctl %x\n", 
current->comm, cmd);
+               return -EINVAL;
+       }
+
+       /* only iw_point needs conversion right now. If any others do add them
+          to this switch. */ 
+
+       switch (wireless_ioctl[num].header_type) { 
+       case IW_HEADER_TYPE_POINT: { 
+               int err;
+               compat_uptr_t ptr;
+               struct iwreq32 *i32 = (struct iwreq32 *)arg;
+               struct iwreq i, *iu = compat_alloc_user_space(sizeof(struct 
iwreq));
+
+               if (!access_ok(VERIFY_READ, i32, sizeof(struct iwreq32)))
+                       return -EFAULT;
+               
+               err = __copy_from_user(i.ifr_ifrn.ifrn_name, 
i32->ifrn_name,IFNAMSIZ);
+               err |= __get_user(ptr, &i32->iw_point.pointer); 
+               i.u.essid.pointer = compat_ptr(ptr);
+               err |= __get_user(i.u.essid.length, &i32->iw_point.length); 
+               err |= __get_user(i.u.essid.flags, &i32->iw_point.flags);; 
+               if (!err) 
+                       err |= copy_to_user(iu, &i, sizeof(struct iwreq));
+               if (err) 
+                       return -EFAULT;
+
+               arg = (unsigned long) iu;                       
+               break;
+       }
+       } 
+
+       return sys_ioctl(fd, cmd, arg);
+} 
+#else
+/* stub to avoid warning */
+static int wireless_ioctl32(unsigned int fd, unsigned int cmd, unsigned long 
arg)
+{ 
+       return -ENOTTY; 
+} 
+#endif
+
 struct rtentry32 {
         u32            rt_pad1;
         struct sockaddr rt_dst;         /* target address               */
@@ -3133,6 +3198,39 @@
 HANDLE_IOCTL(I2C_FUNCS, w_long)
 HANDLE_IOCTL(I2C_RDWR, do_i2c_rdwr_ioctl)
 HANDLE_IOCTL(I2C_SMBUS, do_i2c_smbus_ioctl)
+/* wireless */
+HANDLE_IOCTL(SIOCIWFIRSTPRIV+0,wireless_ioctl32)
+HANDLE_IOCTL(SIOCIWFIRSTPRIV+1,wireless_ioctl32)
+HANDLE_IOCTL(SIOCIWFIRSTPRIV+2,wireless_ioctl32)
+HANDLE_IOCTL(SIOCIWFIRSTPRIV+3,wireless_ioctl32)
+HANDLE_IOCTL(SIOCIWFIRSTPRIV+4,wireless_ioctl32)
+HANDLE_IOCTL(SIOCIWFIRSTPRIV+5,wireless_ioctl32)
+HANDLE_IOCTL(SIOCIWFIRSTPRIV+6,wireless_ioctl32)
+HANDLE_IOCTL(SIOCIWFIRSTPRIV+7,wireless_ioctl32)
+HANDLE_IOCTL(SIOCIWFIRSTPRIV+8,wireless_ioctl32)
+HANDLE_IOCTL(SIOCIWFIRSTPRIV+9,wireless_ioctl32)
+HANDLE_IOCTL(SIOCIWFIRSTPRIV+10,wireless_ioctl32)
+HANDLE_IOCTL(SIOCIWFIRSTPRIV+11,wireless_ioctl32)
+HANDLE_IOCTL(SIOCIWFIRSTPRIV+12,wireless_ioctl32)
+HANDLE_IOCTL(SIOCIWFIRSTPRIV+13,wireless_ioctl32)
+HANDLE_IOCTL(SIOCIWFIRSTPRIV+14,wireless_ioctl32)
+HANDLE_IOCTL(SIOCIWFIRSTPRIV+15,wireless_ioctl32)
+HANDLE_IOCTL(SIOCIWFIRSTPRIV+16,wireless_ioctl32)
+HANDLE_IOCTL(SIOCIWFIRSTPRIV+17,wireless_ioctl32)
+HANDLE_IOCTL(SIOCIWFIRSTPRIV+18,wireless_ioctl32)
+HANDLE_IOCTL(SIOCIWFIRSTPRIV+19,wireless_ioctl32)
+HANDLE_IOCTL(SIOCIWFIRSTPRIV+20,wireless_ioctl32)
+HANDLE_IOCTL(SIOCIWFIRSTPRIV+21,wireless_ioctl32)
+HANDLE_IOCTL(SIOCIWFIRSTPRIV+22,wireless_ioctl32)
+HANDLE_IOCTL(SIOCIWFIRSTPRIV+23,wireless_ioctl32)
+HANDLE_IOCTL(SIOCIWFIRSTPRIV+24,wireless_ioctl32)
+HANDLE_IOCTL(SIOCIWFIRSTPRIV+25,wireless_ioctl32)
+HANDLE_IOCTL(SIOCIWFIRSTPRIV+26,wireless_ioctl32)
+HANDLE_IOCTL(SIOCIWFIRSTPRIV+27,wireless_ioctl32)
+HANDLE_IOCTL(SIOCIWFIRSTPRIV+28,wireless_ioctl32)
+HANDLE_IOCTL(SIOCIWFIRSTPRIV+29,wireless_ioctl32)
+HANDLE_IOCTL(SIOCIWFIRSTPRIV+30,wireless_ioctl32)
+HANDLE_IOCTL(SIOCIWFIRSTPRIV+31,wireless_ioctl32)
 
 #undef DECLARES
 #endif

<Prev in Thread] Current Thread [Next in Thread>