2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
11 * Linux module support routines.
14 #include <afsconfig.h>
15 #include "afs/param.h"
18 #include <linux/module.h> /* early to avoid printf->printk mapping */
19 #include "afs/sysincludes.h"
20 #include "afsincludes.h"
21 #include "h/unistd.h" /* For syscall numbers. */
24 #ifdef AFS_AMD64_LINUX20_ENV
25 #include <asm/ia32_unistd.h>
27 #ifdef AFS_SPARC64_LINUX20_ENV
28 #include <linux/ioctl32.h>
31 #include <linux/proc_fs.h>
32 #include <linux/slab.h>
33 #include <linux/init.h>
34 #include <linux/sched.h>
35 #include <linux/kernel.h>
37 extern struct proc_dir_entry *openafs_procfs;
38 #if defined(NEED_IOCTL32) && !defined(HAVE_COMPAT_IOCTL)
39 static int ioctl32_done;
42 extern asmlinkage long
43 afs_syscall(long syscall, long parm1, long parm2, long parm3, long parm4);
46 afs_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
50 struct afsprocdata sysargs;
52 struct afsprocdata32 sysargs32;
55 if (cmd != VIOC_SYSCALL && cmd != VIOC_SYSCALL32) return -EINVAL;
58 #ifdef AFS_LINUX26_ENV
59 #ifdef AFS_S390X_LINUX26_ENV
60 if (test_thread_flag(TIF_31BIT))
61 #elif AFS_AMD64_LINUX20_ENV
62 if (test_thread_flag(TIF_IA32))
64 if (test_thread_flag(TIF_32BIT))
65 #endif /* AFS_S390X_LINUX26_ENV */
67 #ifdef AFS_SPARC64_LINUX24_ENV
68 if (current->thread.flags & SPARC_FLAG_32BIT)
69 #elif defined(AFS_SPARC64_LINUX20_ENV)
70 if (current->tss.flags & SPARC_FLAG_32BIT)
71 #elif defined(AFS_AMD64_LINUX20_ENV)
72 if (current->thread.flags & THREAD_IA32)
73 #elif defined(AFS_PPC64_LINUX20_ENV)
74 if (current->thread.flags & PPC_FLAG_32BIT)
75 #elif defined(AFS_S390X_LINUX20_ENV)
76 if (current->thread.flags & S390_FLAG_31BIT)
78 #error Not done for this linux type
79 #endif /* AFS_LINUX26_ENV */
80 #endif /* NEED_IOCTL32 */
82 if (copy_from_user(&sysargs32, (void *)arg,
83 sizeof(struct afsprocdata32)))
86 return afs_syscall((unsigned long)sysargs32.syscall,
87 (unsigned long)sysargs32.param1,
88 (unsigned long)sysargs32.param2,
89 (unsigned long)sysargs32.param3,
90 (unsigned long)sysargs32.param4);
94 if (copy_from_user(&sysargs, (void *)arg, sizeof(struct afsprocdata)))
97 return afs_syscall(sysargs.syscall, sysargs.param1,
98 sysargs.param2, sysargs.param3, sysargs.param4);
102 #if defined(HAVE_UNLOCKED_IOCTL) || defined(HAVE_COMPAT_IOCTL)
103 static long afs_unlocked_ioctl(struct file *file, unsigned int cmd,
105 return afs_ioctl(FILE_INODE(file), file, cmd, arg);
109 static struct file_operations afs_syscall_fops = {
110 #ifdef HAVE_UNLOCKED_IOCTL
111 .unlocked_ioctl = afs_unlocked_ioctl,
115 #ifdef HAVE_COMPAT_IOCTL
116 .compat_ioctl = afs_unlocked_ioctl,
123 struct proc_dir_entry *entry;
125 entry = create_proc_entry(PROC_SYSCALL_NAME, 0666, openafs_procfs);
126 entry->proc_fops = &afs_syscall_fops;
127 #if defined(STRUCT_PROC_DIR_ENTRY_HAS_OWNER)
128 entry->owner = THIS_MODULE;
131 #if defined(NEED_IOCTL32) && !defined(HAVE_COMPAT_IOCTL)
132 if (register_ioctl32_conversion(VIOC_SYSCALL32, NULL) == 0)
138 osi_ioctl_clean(void)
140 remove_proc_entry(PROC_SYSCALL_NAME, openafs_procfs);
141 #if defined(NEED_IOCTL32) && !defined(HAVE_COMPAT_IOCTL)
143 unregister_ioctl32_conversion(VIOC_SYSCALL32);