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 +#include + +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");