linux/arch/powerpc/platforms/cell/spufs/syscalls.c
<<
>>
Prefs
   1#include <linux/file.h>
   2#include <linux/fs.h>
   3#include <linux/module.h>
   4#include <linux/mount.h>
   5#include <linux/namei.h>
   6
   7#include <asm/uaccess.h>
   8
   9#include "spufs.h"
  10
  11/**
  12 * sys_spu_run - run code loaded into an SPU
  13 *
  14 * @unpc:    next program counter for the SPU
  15 * @ustatus: status of the SPU
  16 *
  17 * This system call transfers the control of execution of a
  18 * user space thread to an SPU. It will return when the
  19 * SPU has finished executing or when it hits an error
  20 * condition and it will be interrupted if a signal needs
  21 * to be delivered to a handler in user space.
  22 *
  23 * The next program counter is set to the passed value
  24 * before the SPU starts fetching code and the user space
  25 * pointer gets updated with the new value when returning
  26 * from kernel space.
  27 *
  28 * The status value returned from spu_run reflects the
  29 * value of the spu_status register after the SPU has stopped.
  30 *
  31 */
  32static long do_spu_run(struct file *filp,
  33                        __u32 __user *unpc,
  34                        __u32 __user *ustatus)
  35{
  36        long ret;
  37        struct spufs_inode_info *i;
  38        u32 npc, status;
  39
  40        ret = -EFAULT;
  41        if (get_user(npc, unpc))
  42                goto out;
  43
  44        /* check if this file was created by spu_create */
  45        ret = -EINVAL;
  46        if (filp->f_op != &spufs_context_fops)
  47                goto out;
  48
  49        i = SPUFS_I(filp->f_path.dentry->d_inode);
  50        ret = spufs_run_spu(i->i_ctx, &npc, &status);
  51
  52        if (put_user(npc, unpc))
  53                ret = -EFAULT;
  54
  55        if (ustatus && put_user(status, ustatus))
  56                ret = -EFAULT;
  57out:
  58        return ret;
  59}
  60
  61static long do_spu_create(const char __user *pathname, unsigned int flags,
  62                mode_t mode, struct file *neighbor)
  63{
  64        char *tmp;
  65        int ret;
  66
  67        tmp = getname(pathname);
  68        ret = PTR_ERR(tmp);
  69        if (!IS_ERR(tmp)) {
  70                struct nameidata nd;
  71
  72                ret = path_lookup(tmp, LOOKUP_PARENT|
  73                                LOOKUP_OPEN|LOOKUP_CREATE, &nd);
  74                if (!ret) {
  75                        ret = spufs_create(&nd, flags, mode, neighbor);
  76                        path_release(&nd);
  77                }
  78                putname(tmp);
  79        }
  80
  81        return ret;
  82}
  83
  84struct spufs_calls spufs_calls = {
  85        .create_thread = do_spu_create,
  86        .spu_run = do_spu_run,
  87        .coredump_extra_notes_size = spufs_coredump_extra_notes_size,
  88        .coredump_extra_notes_write = spufs_coredump_extra_notes_write,
  89        .notify_spus_active = do_notify_spus_active,
  90        .owner = THIS_MODULE,
  91};
  92