When running on ppc64, sparc64, or x86-64, register ioctls with the ioctl32
translation layer. [Don Mulvey]
--- diff/drivers/md/dm-ioctl.c 2003-02-13 10:42:45.000000000 +0000
+++ source/drivers/md/dm-ioctl.c 2003-02-13 10:42:50.000000000 +0000
@@ -922,30 +922,30 @@
return dm_hash_rename(param->name, new_name);
}
-
/*-----------------------------------------------------------------
* Implementation of open/close/ioctl on the special char
* device.
*---------------------------------------------------------------*/
-static ioctl_fn lookup_ioctl(unsigned int cmd)
-{
- static struct {
- int cmd;
- ioctl_fn fn;
- } _ioctls[] = {
- {DM_VERSION_CMD, NULL}, /* version is dealt with elsewhere */
- {DM_REMOVE_ALL_CMD, remove_all},
- {DM_DEV_CREATE_CMD, create},
- {DM_DEV_REMOVE_CMD, remove},
- {DM_DEV_RELOAD_CMD, reload},
- {DM_DEV_RENAME_CMD, rename},
- {DM_DEV_SUSPEND_CMD, suspend},
- {DM_DEV_DEPS_CMD, dep},
- {DM_DEV_STATUS_CMD, info},
- {DM_TARGET_STATUS_CMD, get_status},
- {DM_TARGET_WAIT_CMD, wait_device_event},
- };
+static struct {
+ int cmd;
+ ioctl_fn fn;
+} _ioctls[] = {
+ {DM_VERSION_CMD, NULL}, /* version is dealt with elsewhere */
+ {DM_REMOVE_ALL_CMD, remove_all},
+ {DM_DEV_CREATE_CMD, create},
+ {DM_DEV_REMOVE_CMD, remove},
+ {DM_DEV_RELOAD_CMD, reload},
+ {DM_DEV_RENAME_CMD, rename},
+ {DM_DEV_SUSPEND_CMD, suspend},
+ {DM_DEV_DEPS_CMD, dep},
+ {DM_DEV_STATUS_CMD, info},
+ {DM_TARGET_STATUS_CMD, get_status},
+ {DM_TARGET_WAIT_CMD, wait_device_event},
+};
+
+static inline ioctl_fn lookup_ioctl(unsigned int cmd)
+{
return (cmd >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[cmd].fn;
}
@@ -1102,6 +1102,41 @@
};
/*
+ * Register 32 bit ioctls on 64bit systems.
+ */
+#if defined(CONFIG_PPC64) || defined(CONFIG_SPARC64) || defined(CONFIG_X86_64)
+#include <linux/smp_lock.h>
+#include <asm/ioctl32.h>
+
+static inline void register_ioctl32_cmds(void)
+{
+ int i;
+
+ lock_kernel();
+ for (i = 0; i < ARRAY_SIZE(_ioctls); i++) {
+ register_ioctl32_conversion(_IOWR(DM_IOCTL, _ioctls[i].cmd,
+ struct dm_ioctl), NULL);
+ }
+ unlock_kernel();
+}
+
+static inline void unregister_ioctl32_cmds(void)
+{
+ int i;
+
+ lock_kernel();
+ for (i = 0; i < ARRAY_SIZE(_ioctls); i++) {
+ unregister_ioctl32_conversion(_IOWR(DM_IOCTL, _ioctls[i].cmd,
+ struct dm_ioctl));
+ }
+ unlock_kernel();
+}
+#else
+static inline void register_ioctl32_cmds(void) {}
+static inline void unregister_ioctl32_cmds(void) {}
+#endif
+
+/*
* Create misc character device and link to DM_DIR/control.
*/
int __init dm_interface_init(void)
@@ -1120,6 +1155,8 @@
return r;
}
+ register_ioctl32_cmds();
+
r = devfs_generate_path(_dm_misc.devfs_handle, rname + 3,
sizeof rname - 3);
if (r == -ENOSYS)
@@ -1146,6 +1183,7 @@
return 0;
failed:
+ unregister_ioctl32_cmds();
misc_deregister(&_dm_misc);
dm_hash_exit();
return r;
@@ -1153,6 +1191,8 @@
void dm_interface_exit(void)
{
+ unregister_ioctl32_cmds();
+
if (misc_deregister(&_dm_misc) < 0)
DMERR("misc_deregister failed for control device");