1 /* 2 * SPU file system -- system call stubs 3 * 4 * (C) Copyright IBM Deutschland Entwicklung GmbH 2005 5 * 6 * Author: Arnd Bergmann <arndb@de.ibm.com> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2, or (at your option) 11 * any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 */ 22 #include <linux/file.h> 23 #include <linux/module.h> 24 #include <linux/syscalls.h> 25 26 #include <asm/spu.h> 27 28 struct spufs_calls spufs_calls = { 29 .owner = NULL, 30 }; 31 32 /* These stub syscalls are needed to have the actual implementation 33 * within a loadable module. When spufs is built into the kernel, 34 * this file is not used and the syscalls directly enter the fs code */ 35 36 asmlinkage long sys_spu_create(const char __user *name, 37 unsigned int flags, mode_t mode) 38 { 39 long ret; 40 struct module *owner = spufs_calls.owner; 41 42 ret = -ENOSYS; 43 if (owner && try_module_get(owner)) { 44 ret = spufs_calls.create_thread(name, flags, mode); 45 module_put(owner); 46 } 47 return ret; 48 } 49 50 asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus) 51 { 52 long ret; 53 struct file *filp; 54 int fput_needed; 55 struct module *owner = spufs_calls.owner; 56 57 ret = -ENOSYS; 58 if (owner && try_module_get(owner)) { 59 ret = -EBADF; 60 filp = fget_light(fd, &fput_needed); 61 if (filp) { 62 ret = spufs_calls.spu_run(filp, unpc, ustatus); 63 fput_light(filp, fput_needed); 64 } 65 module_put(owner); 66 } 67 return ret; 68 } 69 70 int register_spu_syscalls(struct spufs_calls *calls) 71 { 72 if (spufs_calls.owner) 73 return -EBUSY; 74 75 spufs_calls.create_thread = calls->create_thread; 76 spufs_calls.spu_run = calls->spu_run; 77 smp_mb(); 78 spufs_calls.owner = calls->owner; 79 return 0; 80 } 81 EXPORT_SYMBOL_GPL(register_spu_syscalls); 82 83 void unregister_spu_syscalls(struct spufs_calls *calls) 84 { 85 BUG_ON(spufs_calls.owner != calls->owner); 86 spufs_calls.owner = NULL; 87 } 88 EXPORT_SYMBOL_GPL(unregister_spu_syscalls); 89