import of upstream 2.4.34.4 from kernel.org
[linux-2.4.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_semtimedop (first, (struct sembuf *)ptr, second,
36                                        NULL);
37         case SEMTIMEDOP:
38                 return sys_semtimedop (first, (struct sembuf *)ptr, second,
39                                        (const struct timespec *)fifth);
40         case SEMGET:
41                 return sys_semget (first, second, third);
42         case SEMCTL: {
43                 union semun fourth;
44                 if (!ptr)
45                         return -EINVAL;
46                 if (get_user(fourth.__pad, (void **) ptr))
47                         return -EFAULT;
48                 return sys_semctl (first, second, third, fourth);
49         }
50
51         case MSGSND:
52                 return sys_msgsnd (first, (struct msgbuf *) ptr,
53                                    second, third);
54         case MSGRCV:
55                 switch (version) {
56                 case 0: {
57                         struct ipc_kludge tmp;
58                         if (!ptr)
59                                 return -EINVAL;
60
61                         if (copy_from_user(&tmp,
62                                            (struct ipc_kludge *) ptr,
63                                            sizeof (tmp)))
64                                 return -EFAULT;
65                         return sys_msgrcv (first, tmp.msgp, second,
66                                            tmp.msgtyp, third);
67                 }
68                 default:
69                         return sys_msgrcv (first,
70                                            (struct msgbuf *) ptr,
71                                            second, fifth, third);
72                 }
73         case MSGGET:
74                 return sys_msgget ((key_t) first, second);
75         case MSGCTL:
76                 return sys_msgctl (first, second, (struct msqid_ds *) ptr);
77
78         case SHMAT:
79                 switch (version) {
80                 default: {
81                         ulong raddr;
82                         ret = sys_shmat (first, (char *) ptr, second, &raddr);
83                         if (ret)
84                                 return ret;
85                         return put_user (raddr, (ulong *) third);
86                 }
87                 case 1: /* iBCS2 emulator entry point */
88                         if (!segment_eq(get_fs(), get_ds()))
89                                 return -EINVAL;
90                         return sys_shmat (first, (char *) ptr, second, (ulong *) third);
91                 }
92         case SHMDT:
93                 return sys_shmdt ((char *)ptr);
94         case SHMGET:
95                 return sys_shmget (first, second, third);
96         case SHMCTL:
97                 return sys_shmctl (first, second,
98                                    (struct shmid_ds *) ptr);
99         default:
100                 return -ENOSYS;
101         }
102 }