6c242f1ebddf48ce37c25825d537bae09c028298
[linux-flexiantxendom0-3.2.10.git] / arch / mips / kernel / ipc.c
1 /*
2  * linux/arch/mips/kernel/ipc.c
3  *
4  * This file contains various random system calls that
5  * have a non-standard calling sequence on the Linux/MIPS
6  * platform.
7  */
8 #include <linux/errno.h>
9 #include <linux/sched.h>
10 #include <linux/mm.h>
11 #include <linux/smp.h>
12 #include <linux/smp_lock.h>
13 #include <linux/sem.h>
14 #include <linux/msg.h>
15 #include <linux/shm.h>
16
17 #include <asm/ipc.h>
18 #include <asm/uaccess.h>
19
20 /*
21  * sys_ipc() is the de-multiplexer for the SysV IPC calls..
22  *
23  * This is really horribly ugly.
24  */
25 asmlinkage int sys_ipc (uint call, int first, int second,
26                         int third, void *ptr, long fifth)
27 {
28         int version, ret;
29
30         version = call >> 16; /* hack for backward compatibility */
31         call &= 0xffff;
32
33         switch (call) {
34         case SEMOP:
35                 return sys_semop (first, (struct sembuf *)ptr, second);
36         case SEMGET:
37                 return sys_semget (first, second, third);
38         case SEMCTL: {
39                 union semun fourth;
40                 if (!ptr)
41                         return -EINVAL;
42                 if (get_user(fourth.__pad, (void **) ptr))
43                         return -EFAULT;
44                 return sys_semctl (first, second, third, fourth);
45         }
46
47         case MSGSND:
48                 return sys_msgsnd (first, (struct msgbuf *) ptr,
49                                    second, third);
50         case MSGRCV:
51                 switch (version) {
52                 case 0: {
53                         struct ipc_kludge tmp;
54                         if (!ptr)
55                                 return -EINVAL;
56
57                         if (copy_from_user(&tmp,
58                                            (struct ipc_kludge *) ptr,
59                                            sizeof (tmp)))
60                                 return -EFAULT;
61                         return sys_msgrcv (first, tmp.msgp, second,
62                                            tmp.msgtyp, third);
63                 }
64                 default:
65                         return sys_msgrcv (first,
66                                            (struct msgbuf *) ptr,
67                                            second, fifth, third);
68                 }
69         case MSGGET:
70                 return sys_msgget ((key_t) first, second);
71         case MSGCTL:
72                 return sys_msgctl (first, second, (struct msqid_ds *) ptr);
73
74         case SHMAT:
75                 switch (version) {
76                 default: {
77                         ulong raddr;
78                         ret = sys_shmat (first, (char *) ptr, second, &raddr);
79                         if (ret)
80                                 return ret;
81                         return put_user (raddr, (ulong *) third);
82                 }
83                 case 1: /* iBCS2 emulator entry point */
84                         if (!segment_eq(get_fs(), get_ds()))
85                                 return -EINVAL;
86                         return sys_shmat (first, (char *) ptr, second, (ulong *) third);
87                 }
88         case SHMDT:
89                 return sys_shmdt ((char *)ptr);
90         case SHMGET:
91                 return sys_shmget (first, second, third);
92         case SHMCTL:
93                 return sys_shmctl (first, second,
94                                    (struct shmid_ds *) ptr);
95         default:
96                 return -ENOSYS;
97         }
98 }