|
@@ -310,96 +310,6 @@ static int __init init_sys32_ioctl(void)
|
|
|
|
|
|
__initcall(init_sys32_ioctl);
|
|
__initcall(init_sys32_ioctl);
|
|
|
|
|
|
-int register_ioctl32_conversion(unsigned int cmd,
|
|
|
|
- ioctl_trans_handler_t handler)
|
|
|
|
-{
|
|
|
|
- struct ioctl_trans *t;
|
|
|
|
- struct ioctl_trans *new_t;
|
|
|
|
- unsigned long hash = ioctl32_hash(cmd);
|
|
|
|
-
|
|
|
|
- new_t = kmalloc(sizeof(*new_t), GFP_KERNEL);
|
|
|
|
- if (!new_t)
|
|
|
|
- return -ENOMEM;
|
|
|
|
-
|
|
|
|
- down_write(&ioctl32_sem);
|
|
|
|
- for (t = ioctl32_hash_table[hash]; t; t = t->next) {
|
|
|
|
- if (t->cmd == cmd) {
|
|
|
|
- printk(KERN_ERR "Trying to register duplicated ioctl32 "
|
|
|
|
- "handler %x\n", cmd);
|
|
|
|
- up_write(&ioctl32_sem);
|
|
|
|
- kfree(new_t);
|
|
|
|
- return -EINVAL;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- new_t->next = NULL;
|
|
|
|
- new_t->cmd = cmd;
|
|
|
|
- new_t->handler = handler;
|
|
|
|
- ioctl32_insert_translation(new_t);
|
|
|
|
-
|
|
|
|
- up_write(&ioctl32_sem);
|
|
|
|
- return 0;
|
|
|
|
-}
|
|
|
|
-EXPORT_SYMBOL(register_ioctl32_conversion);
|
|
|
|
-
|
|
|
|
-static inline int builtin_ioctl(struct ioctl_trans *t)
|
|
|
|
-{
|
|
|
|
- return t >= ioctl_start && t < (ioctl_start + ioctl_table_size);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/* Problem:
|
|
|
|
- This function cannot unregister duplicate ioctls, because they are not
|
|
|
|
- unique.
|
|
|
|
- When they happen we need to extend the prototype to pass the handler too. */
|
|
|
|
-
|
|
|
|
-int unregister_ioctl32_conversion(unsigned int cmd)
|
|
|
|
-{
|
|
|
|
- unsigned long hash = ioctl32_hash(cmd);
|
|
|
|
- struct ioctl_trans *t, *t1;
|
|
|
|
-
|
|
|
|
- down_write(&ioctl32_sem);
|
|
|
|
-
|
|
|
|
- t = ioctl32_hash_table[hash];
|
|
|
|
- if (!t) {
|
|
|
|
- up_write(&ioctl32_sem);
|
|
|
|
- return -EINVAL;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (t->cmd == cmd) {
|
|
|
|
- if (builtin_ioctl(t)) {
|
|
|
|
- printk("%p tried to unregister builtin ioctl %x\n",
|
|
|
|
- __builtin_return_address(0), cmd);
|
|
|
|
- } else {
|
|
|
|
- ioctl32_hash_table[hash] = t->next;
|
|
|
|
- up_write(&ioctl32_sem);
|
|
|
|
- kfree(t);
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- while (t->next) {
|
|
|
|
- t1 = t->next;
|
|
|
|
- if (t1->cmd == cmd) {
|
|
|
|
- if (builtin_ioctl(t1)) {
|
|
|
|
- printk("%p tried to unregister builtin "
|
|
|
|
- "ioctl %x\n",
|
|
|
|
- __builtin_return_address(0), cmd);
|
|
|
|
- goto out;
|
|
|
|
- } else {
|
|
|
|
- t->next = t1->next;
|
|
|
|
- up_write(&ioctl32_sem);
|
|
|
|
- kfree(t1);
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- t = t1;
|
|
|
|
- }
|
|
|
|
- printk(KERN_ERR "Trying to free unknown 32bit ioctl handler %x\n",
|
|
|
|
- cmd);
|
|
|
|
-out:
|
|
|
|
- up_write(&ioctl32_sem);
|
|
|
|
- return -EINVAL;
|
|
|
|
-}
|
|
|
|
-EXPORT_SYMBOL(unregister_ioctl32_conversion);
|
|
|
|
-
|
|
|
|
static void compat_ioctl_error(struct file *filp, unsigned int fd,
|
|
static void compat_ioctl_error(struct file *filp, unsigned int fd,
|
|
unsigned int cmd, unsigned long arg)
|
|
unsigned int cmd, unsigned long arg)
|
|
{
|
|
{
|