Merge branch 'e1000-fixes' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik...
[pandora-kernel.git] / arch / mips / kernel / kspd.c
index 5929f88..c658001 100644 (file)
@@ -17,6 +17,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/sched.h>
 #include <linux/unistd.h>
 #include <linux/file.h>
 #include <linux/fs.h>
@@ -70,6 +71,7 @@ static int sp_stopping = 0;
 #define MTSP_SYSCALL_GETTIME   (MTSP_SYSCALL_BASE + 7)
 #define MTSP_SYSCALL_PIPEFREQ  (MTSP_SYSCALL_BASE + 8)
 #define MTSP_SYSCALL_GETTOD    (MTSP_SYSCALL_BASE + 9)
+#define MTSP_SYSCALL_IOCTL     (MTSP_SYSCALL_BASE + 10)
 
 #define MTSP_O_RDONLY          0x0000
 #define MTSP_O_WRONLY          0x0001
@@ -110,7 +112,8 @@ struct apsp_table syscall_command_table[] = {
        { MTSP_SYSCALL_CLOSE, __NR_close },
        { MTSP_SYSCALL_READ, __NR_read },
        { MTSP_SYSCALL_WRITE, __NR_write },
-       { MTSP_SYSCALL_LSEEK32, __NR_lseek }
+       { MTSP_SYSCALL_LSEEK32, __NR_lseek },
+       { MTSP_SYSCALL_IOCTL, __NR_ioctl }
 };
 
 static int sp_syscall(int num, int arg0, int arg1, int arg2, int arg3)
@@ -189,17 +192,22 @@ void sp_work_handle_request(void)
        struct mtsp_syscall_generic generic;
        struct mtsp_syscall_ret ret;
        struct kspd_notifications *n;
+       unsigned long written;
+       mm_segment_t old_fs;
        struct timeval tv;
        struct timezone tz;
        int cmd;
 
        char *vcwd;
-       mm_segment_t old_fs;
        int size;
 
        ret.retval = -1;
 
-       if (!rtlx_read(RTLX_CHANNEL_SYSIO, &sc, sizeof(struct mtsp_syscall), 0)) {
+       old_fs = get_fs();
+       set_fs(KERNEL_DS);
+
+       if (!rtlx_read(RTLX_CHANNEL_SYSIO, &sc, sizeof(struct mtsp_syscall))) {
+               set_fs(old_fs);
                printk(KERN_ERR "Expected request but nothing to read\n");
                return;
        }
@@ -207,7 +215,8 @@ void sp_work_handle_request(void)
        size = sc.size;
 
        if (size) {
-               if (!rtlx_read(RTLX_CHANNEL_SYSIO, &generic, size, 0)) {
+               if (!rtlx_read(RTLX_CHANNEL_SYSIO, &generic, size)) {
+                       set_fs(old_fs);
                        printk(KERN_ERR "Expected request but nothing to read\n");
                        return;
                }
@@ -232,8 +241,6 @@ void sp_work_handle_request(void)
                if ((ret.retval = sp_syscall(__NR_gettimeofday, (int)&tv,
                                             (int)&tz, 0,0)) == 0)
                ret.retval = tv.tv_sec;
-
-               ret.errno = errno;
                break;
 
        case MTSP_SYSCALL_EXIT:
@@ -270,7 +277,6 @@ void sp_work_handle_request(void)
                if (cmd >= 0) {
                        ret.retval = sp_syscall(cmd, generic.arg0, generic.arg1,
                                                generic.arg2, generic.arg3);
-                       ret.errno = errno;
                } else
                        printk(KERN_WARNING
                               "KSPD: Unknown SP syscall number %d\n", sc.cmd);
@@ -280,8 +286,11 @@ void sp_work_handle_request(void)
        if (vpe_getuid(SP_VPE))
                sp_setfsuidgid( 0, 0);
 
-       if ((rtlx_write(RTLX_CHANNEL_SYSIO, &ret, sizeof(struct mtsp_syscall_ret), 0))
-           < sizeof(struct mtsp_syscall_ret))
+       old_fs = get_fs();
+       set_fs(KERNEL_DS);
+       written = rtlx_write(RTLX_CHANNEL_SYSIO, &ret, sizeof(ret));
+       set_fs(old_fs);
+       if (written < sizeof(ret))
                printk("KSPD: sp_work_handle_request failed to send to SP\n");
 }