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");