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 */
sys_ipc(uint call,int first,int second,int third,void * ptr,long fifth)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 }
103