|
@@ -1170,6 +1170,112 @@ static int ioctl(struct tty_struct *tty, struct file *file,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * support for 32 bit ioctl calls on 64 bit systems
|
|
|
+ */
|
|
|
+#ifdef CONFIG_COMPAT
|
|
|
+static long get_params32(struct slgt_info *info, struct MGSL_PARAMS32 __user *user_params)
|
|
|
+{
|
|
|
+ struct MGSL_PARAMS32 tmp_params;
|
|
|
+
|
|
|
+ DBGINFO(("%s get_params32\n", info->device_name));
|
|
|
+ tmp_params.mode = (compat_ulong_t)info->params.mode;
|
|
|
+ tmp_params.loopback = info->params.loopback;
|
|
|
+ tmp_params.flags = info->params.flags;
|
|
|
+ tmp_params.encoding = info->params.encoding;
|
|
|
+ tmp_params.clock_speed = (compat_ulong_t)info->params.clock_speed;
|
|
|
+ tmp_params.addr_filter = info->params.addr_filter;
|
|
|
+ tmp_params.crc_type = info->params.crc_type;
|
|
|
+ tmp_params.preamble_length = info->params.preamble_length;
|
|
|
+ tmp_params.preamble = info->params.preamble;
|
|
|
+ tmp_params.data_rate = (compat_ulong_t)info->params.data_rate;
|
|
|
+ tmp_params.data_bits = info->params.data_bits;
|
|
|
+ tmp_params.stop_bits = info->params.stop_bits;
|
|
|
+ tmp_params.parity = info->params.parity;
|
|
|
+ if (copy_to_user(user_params, &tmp_params, sizeof(struct MGSL_PARAMS32)))
|
|
|
+ return -EFAULT;
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static long set_params32(struct slgt_info *info, struct MGSL_PARAMS32 __user *new_params)
|
|
|
+{
|
|
|
+ struct MGSL_PARAMS32 tmp_params;
|
|
|
+
|
|
|
+ DBGINFO(("%s set_params32\n", info->device_name));
|
|
|
+ if (copy_from_user(&tmp_params, new_params, sizeof(struct MGSL_PARAMS32)))
|
|
|
+ return -EFAULT;
|
|
|
+
|
|
|
+ spin_lock(&info->lock);
|
|
|
+ info->params.mode = tmp_params.mode;
|
|
|
+ info->params.loopback = tmp_params.loopback;
|
|
|
+ info->params.flags = tmp_params.flags;
|
|
|
+ info->params.encoding = tmp_params.encoding;
|
|
|
+ info->params.clock_speed = tmp_params.clock_speed;
|
|
|
+ info->params.addr_filter = tmp_params.addr_filter;
|
|
|
+ info->params.crc_type = tmp_params.crc_type;
|
|
|
+ info->params.preamble_length = tmp_params.preamble_length;
|
|
|
+ info->params.preamble = tmp_params.preamble;
|
|
|
+ info->params.data_rate = tmp_params.data_rate;
|
|
|
+ info->params.data_bits = tmp_params.data_bits;
|
|
|
+ info->params.stop_bits = tmp_params.stop_bits;
|
|
|
+ info->params.parity = tmp_params.parity;
|
|
|
+ spin_unlock(&info->lock);
|
|
|
+
|
|
|
+ change_params(info);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static long slgt_compat_ioctl(struct tty_struct *tty, struct file *file,
|
|
|
+ unsigned int cmd, unsigned long arg)
|
|
|
+{
|
|
|
+ struct slgt_info *info = tty->driver_data;
|
|
|
+ int rc = -ENOIOCTLCMD;
|
|
|
+
|
|
|
+ if (sanity_check(info, tty->name, "compat_ioctl"))
|
|
|
+ return -ENODEV;
|
|
|
+ DBGINFO(("%s compat_ioctl() cmd=%08X\n", info->device_name, cmd));
|
|
|
+
|
|
|
+ switch (cmd) {
|
|
|
+
|
|
|
+ case MGSL_IOCSPARAMS32:
|
|
|
+ rc = set_params32(info, compat_ptr(arg));
|
|
|
+ break;
|
|
|
+
|
|
|
+ case MGSL_IOCGPARAMS32:
|
|
|
+ rc = get_params32(info, compat_ptr(arg));
|
|
|
+ break;
|
|
|
+
|
|
|
+ case MGSL_IOCGPARAMS:
|
|
|
+ case MGSL_IOCSPARAMS:
|
|
|
+ case MGSL_IOCGTXIDLE:
|
|
|
+ case MGSL_IOCGSTATS:
|
|
|
+ case MGSL_IOCWAITEVENT:
|
|
|
+ case MGSL_IOCGIF:
|
|
|
+ case MGSL_IOCSGPIO:
|
|
|
+ case MGSL_IOCGGPIO:
|
|
|
+ case MGSL_IOCWAITGPIO:
|
|
|
+ case TIOCGICOUNT:
|
|
|
+ rc = ioctl(tty, file, cmd, (unsigned long)(compat_ptr(arg)));
|
|
|
+ break;
|
|
|
+
|
|
|
+ case MGSL_IOCSTXIDLE:
|
|
|
+ case MGSL_IOCTXENABLE:
|
|
|
+ case MGSL_IOCRXENABLE:
|
|
|
+ case MGSL_IOCTXABORT:
|
|
|
+ case TIOCMIWAIT:
|
|
|
+ case MGSL_IOCSIF:
|
|
|
+ rc = ioctl(tty, file, cmd, arg);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ DBGINFO(("%s compat_ioctl() cmd=%08X rc=%d\n", info->device_name, cmd, rc));
|
|
|
+ return rc;
|
|
|
+}
|
|
|
+#else
|
|
|
+#define slgt_compat_ioctl NULL
|
|
|
+#endif /* ifdef CONFIG_COMPAT */
|
|
|
+
|
|
|
/*
|
|
|
* proc fs support
|
|
|
*/
|
|
@@ -3446,6 +3552,7 @@ static const struct tty_operations ops = {
|
|
|
.chars_in_buffer = chars_in_buffer,
|
|
|
.flush_buffer = flush_buffer,
|
|
|
.ioctl = ioctl,
|
|
|
+ .compat_ioctl = slgt_compat_ioctl,
|
|
|
.throttle = throttle,
|
|
|
.unthrottle = unthrottle,
|
|
|
.send_xchar = send_xchar,
|