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

[dm-devel] [PATCH] 2.4: dm-ioctl.c: Register ioctls on PPC64, Sparc64, and x86-64



When running on ppc64, sparc64, or x86-64, register ioctls with the ioctl32
translation layer. [Don Mulvey]

--- linux-2.4.20a/drivers/md/dm-ioctl.c	2003/01/21 16:57:59
+++ linux-2.4.20b/drivers/md/dm-ioctl.c	2003/02/04 17:10:34
@@ -925,32 +925,79 @@
 }
 
 
+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},
+};
+
 /*-----------------------------------------------------------------
  * 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},
-	};
-
 	return (cmd >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[cmd].fn;
 }
 
+#if defined(CONFIG_PPC64) || defined(CONFIG_SPARC64) || defined(CONFIG_X86_64)
+#include <linux/smp_lock.h>
+
+extern int
+register_ioctl32_conversion(unsigned int cmd, void *handler);
+extern int
+unregister_ioctl32_conversion(unsigned int cmd);
+
+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)
+{
+	return;
+}
+
+static inline void
+unregister_ioctl32_cmds(void)
+{
+	return;
+}
+#endif
+
 /*
  * As well as checking the version compatibility this always
  * copies the kernel interface version out.
@@ -1122,6 +1169,8 @@
 		return r;
 	}
 
+	register_ioctl32_cmds();
+
 	r = devfs_generate_path(_dm_misc.devfs_handle, rname + 3,
 				sizeof rname - 3);
 	if (r == -ENOSYS)
@@ -1147,6 +1196,7 @@
 	return 0;
 
       failed:
+	unregister_ioctl32_cmds();
 	misc_deregister(&_dm_misc);
 	dm_hash_exit();
 	return r;
@@ -1154,6 +1204,8 @@
 
 void dm_interface_exit(void)
 {
+	unregister_ioctl32_cmds();
+
 	if (misc_deregister(&_dm_misc) < 0)
 		DMERR("misc_deregister failed for control device");
 



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