aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/solaris
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/solaris')
-rw-r--r--arch/sparc64/solaris/Makefile10
-rw-r--r--arch/sparc64/solaris/conv.h38
-rw-r--r--arch/sparc64/solaris/entry64.S223
-rw-r--r--arch/sparc64/solaris/fs.c745
-rw-r--r--arch/sparc64/solaris/ioctl.c825
-rw-r--r--arch/sparc64/solaris/ipc.c126
-rw-r--r--arch/sparc64/solaris/misc.c786
-rw-r--r--arch/sparc64/solaris/signal.c429
-rw-r--r--arch/sparc64/solaris/signal.h108
-rw-r--r--arch/sparc64/solaris/socket.c461
-rw-r--r--arch/sparc64/solaris/socksys.c203
-rw-r--r--arch/sparc64/solaris/socksys.h208
-rw-r--r--arch/sparc64/solaris/systbl.S285
-rw-r--r--arch/sparc64/solaris/timod.c976
14 files changed, 0 insertions, 5423 deletions
diff --git a/arch/sparc64/solaris/Makefile b/arch/sparc64/solaris/Makefile
deleted file mode 100644
index 8c8663033bfb..000000000000
--- a/arch/sparc64/solaris/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
1#
2# Makefile for the Solaris binary emulation.
3#
4
5EXTRA_AFLAGS := -ansi
6
7solaris-objs := entry64.o fs.o misc.o signal.o systbl.o socket.o \
8 ioctl.o ipc.o socksys.o timod.o
9
10obj-$(CONFIG_SOLARIS_EMUL) += solaris.o
diff --git a/arch/sparc64/solaris/conv.h b/arch/sparc64/solaris/conv.h
deleted file mode 100644
index 50e58232cf2b..000000000000
--- a/arch/sparc64/solaris/conv.h
+++ /dev/null
@@ -1,38 +0,0 @@
1/* $Id: conv.h,v 1.4 1998/08/15 20:42:51 davem Exp $
2 * conv.h: Utility macros for Solaris emulation
3 *
4 * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5 */
6
7/* #define DEBUG_SOLARIS */
8#define DEBUG_SOLARIS_KMALLOC
9
10#ifndef __ASSEMBLY__
11
12#include <asm/unistd.h>
13
14/* Use this to get at 32-bit user passed pointers. */
15#define A(__x) \
16({ unsigned long __ret; \
17 __asm__ ("srl %0, 0, %0" \
18 : "=r" (__ret) \
19 : "0" (__x)); \
20 (void __user *)__ret; \
21})
22
23extern unsigned sys_call_table[];
24extern unsigned sys_call_table32[];
25extern unsigned sunos_sys_table[];
26
27#define SYS(name) ((long)sys_call_table[__NR_##name])
28#define SUNOS(x) ((long)sunos_sys_table[x])
29
30#ifdef DEBUG_SOLARIS
31#define SOLD(s) printk("%s,%d,%s(): %s\n",__FILE__,__LINE__,__func__,(s))
32#define SOLDD(s) printk("solaris: "); printk s
33#else
34#define SOLD(s)
35#define SOLDD(s)
36#endif
37
38#endif /* __ASSEMBLY__ */
diff --git a/arch/sparc64/solaris/entry64.S b/arch/sparc64/solaris/entry64.S
deleted file mode 100644
index f170324e8bf2..000000000000
--- a/arch/sparc64/solaris/entry64.S
+++ /dev/null
@@ -1,223 +0,0 @@
1/* $Id: entry64.S,v 1.7 2002/02/09 19:49:31 davem Exp $
2 * entry64.S: Solaris syscall emulation entry point.
3 *
4 * Copyright (C) 1996,1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5 * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu)
6 * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
7 */
8
9#include <linux/errno.h>
10
11#include <asm/head.h>
12#include <asm/asi.h>
13#include <asm/smp.h>
14#include <asm/ptrace.h>
15#include <asm/page.h>
16#include <asm/signal.h>
17#include <asm/pgtable.h>
18#include <asm/processor.h>
19#include <asm/thread_info.h>
20
21#include "conv.h"
22
23#define NR_SYSCALLS 256
24
25 .text
26solaris_syscall_trace:
27 add %sp, PTREGS_OFF, %o0
28 call syscall_trace
29 mov 0, %o1
30 srl %i0, 0, %o0
31 mov %i4, %o4
32 srl %i1, 0, %o1
33 mov %i5, %o5
34 andcc %l3, 1, %g0
35 be,pt %icc, 2f
36 srl %i2, 0, %o2
37 b,pt %xcc, 2f
38 add %sp, PTREGS_OFF, %o0
39
40solaris_sucks:
41/* Solaris is a big system which needs to be able to do all the things
42 * in Inf+1 different ways */
43 add %i6, 0x5c, %o0
44 mov %i0, %g1
45 mov %i1, %i0
46 mov %i2, %i1
47 srl %o0, 0, %o0
48 mov %i3, %i2
49 movrz %g1, 256, %g1 /* Ensure we don't loop forever */
50 mov %i4, %i3
51 mov %i5, %i4
52 ba,pt %xcc, solaris_sparc_syscall
53exen: lduwa [%o0] ASI_S, %i5
54
55exenf: ba,pt %xcc, solaris_sparc_syscall
56 clr %i5
57
58/* For shared binaries, binfmt_elf32 already sets up personality
59 and exec_domain. This is to handle static binaries as well */
60solaris_reg:
61 call solaris_register
62 nop
63 ba,pt %xcc, 1f
64 mov %i4, %o4
65
66linux_syscall_for_solaris:
67 sethi %hi(sys_call_table32), %l6
68 or %l6, %lo(sys_call_table32), %l6
69 sll %l3, 2, %l4
70 ba,pt %xcc, 10f
71 lduw [%l6 + %l4], %l3
72
73 /* Solaris system calls enter here... */
74 .align 32
75 .globl solaris_sparc_syscall, entry64_personality_patch
76solaris_sparc_syscall:
77entry64_personality_patch:
78 ldub [%g4 + 0x0], %l0
79 cmp %g1, 255
80 bg,pn %icc, solaris_unimplemented
81 srl %g1, 0, %g1
82 sethi %hi(solaris_sys_table), %l7
83 or %l7, %lo(solaris_sys_table), %l7
84 brz,pn %g1, solaris_sucks
85 mov %i4, %o4
86 sll %g1, 2, %l4
87 cmp %l0, 1
88 bne,pn %icc, solaris_reg
891: srl %i0, 0, %o0
90 lduw [%l7 + %l4], %l3
91 srl %i1, 0, %o1
92 ldx [%g6 + TI_FLAGS], %l5
93 cmp %l3, NR_SYSCALLS
94 bleu,a,pn %xcc, linux_syscall_for_solaris
95 nop
96 andcc %l3, 1, %g0
97 bne,a,pn %icc, 10f
98 add %sp, PTREGS_OFF, %o0
9910: srl %i2, 0, %o2
100 mov %i5, %o5
101 andn %l3, 3, %l7
102 andcc %l5, _TIF_SYSCALL_TRACE, %g0
103 bne,pn %icc, solaris_syscall_trace
104 mov %i0, %l5
1052: call %l7
106 srl %i3, 0, %o3
107ret_from_solaris:
108 stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
109 ldx [%g6 + TI_FLAGS], %l6
110 sra %o0, 0, %o0
111 mov %ulo(TSTATE_XCARRY | TSTATE_ICARRY), %g2
112 ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %g3
113 cmp %o0, -ERESTART_RESTARTBLOCK
114 sllx %g2, 32, %g2
115 bgeu,pn %xcc, 1f
116 andcc %l6, _TIF_SYSCALL_TRACE, %l6
117
118 /* System call success, clear Carry condition code. */
119 andn %g3, %g2, %g3
120 stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE]
121 bne,pn %icc, solaris_syscall_trace2
122 ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1
123 andcc %l1, 1, %g0
124 bne,pn %icc, 2f
125 clr %l6
126 add %l1, 0x4, %l2
127 stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC] ! pc = npc
128 call rtrap
129 stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] !npc = npc+4
130
131 /* When tnpc & 1, this comes from setcontext and we don't want to advance pc */
1322: andn %l1, 3, %l1
133 call rtrap
134 stx %l1, [%sp + PTREGS_OFF + PT_V9_TNPC] !npc = npc&~3
135
1361:
137 /* System call failure, set Carry condition code.
138 * Also, get abs(errno) to return to the process.
139 */
140 sub %g0, %o0, %o0
141 or %g3, %g2, %g3
142 cmp %o0, ERANGE /* 0-ERANGE are identity mapped */
143 bleu,pt %icc, 1f
144 cmp %o0, EMEDIUMTYPE
145 bgu,pn %icc, 1f
146 sethi %hi(solaris_err_table), %l6
147 sll %o0, 2, %o0
148 or %l6, %lo(solaris_err_table), %l6
149 ldsw [%l6 + %o0], %o0
1501: stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
151 mov 1, %l6
152 stx %g3, [%sp + PTREGS_OFF + PT_V9_TSTATE]
153 bne,pn %icc, solaris_syscall_trace2
154 ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %l1
155 andcc %l1, 1, %g0
156 bne,pn %icc, 2b
157 add %l1, 0x4, %l2
158 stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC] ! pc = npc
159 call rtrap
160 stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC] !npc = npc+4
161
162solaris_syscall_trace2:
163 add %sp, PTREGS_OFF, %o0
164 call syscall_trace
165 mov 1, %o1
166 add %l1, 0x4, %l2 /* npc = npc+4 */
167 andcc %l1, 1, %g0
168 bne,pn %icc, 2b
169 nop
170 stx %l1, [%sp + PTREGS_OFF + PT_V9_TPC]
171 call rtrap
172 stx %l2, [%sp + PTREGS_OFF + PT_V9_TNPC]
173
174 /* This one is tricky, so that's why we do it in assembly */
175 .globl solaris_sigsuspend
176solaris_sigsuspend:
177 call do_sol_sigsuspend
178 nop
179 brlz,pn %o0, ret_from_solaris
180 nop
181 call sys_sigsuspend
182 stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
183 b,pt %xcc, ret_from_solaris
184 nop
185
186 .globl solaris_getpid
187solaris_getpid:
188 call sys_getppid
189 nop
190 call sys_getpid
191 stx %o0, [%sp + PTREGS_OFF + PT_V9_I1]
192 b,pt %xcc, ret_from_solaris
193 nop
194
195 .globl solaris_getuid
196solaris_getuid:
197 call sys_geteuid
198 nop
199 call sys_getuid
200 stx %o1, [%sp + PTREGS_OFF + PT_V9_I1]
201 b,pt %xcc, ret_from_solaris
202 nop
203
204 .globl solaris_getgid
205solaris_getgid:
206 call sys_getegid
207 nop
208 call sys_getgid
209 stx %o1, [%sp + PTREGS_OFF + PT_V9_I1]
210 b,pt %xcc, ret_from_solaris
211 nop
212
213 .globl solaris_unimplemented
214solaris_unimplemented:
215 call do_sol_unimplemented
216 add %sp, PTREGS_OFF, %o0
217 ba,pt %xcc, ret_from_solaris
218 nop
219
220 .section __ex_table,"a"
221 .align 4
222 .word exen, exenf
223
diff --git a/arch/sparc64/solaris/fs.c b/arch/sparc64/solaris/fs.c
deleted file mode 100644
index 7d035f0d3ae1..000000000000
--- a/arch/sparc64/solaris/fs.c
+++ /dev/null
@@ -1,745 +0,0 @@
1/* $Id: fs.c,v 1.27 2002/02/08 03:57:14 davem Exp $
2 * fs.c: fs related syscall emulation for Solaris
3 *
4 * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5 *
6 * 1999-08-19 Implemented solaris F_FREESP (truncate)
7 * fcntl, by Jason Rappleye (rappleye@ccr.buffalo.edu)
8 */
9
10#include <linux/types.h>
11#include <linux/sched.h>
12#include <linux/slab.h>
13#include <linux/capability.h>
14#include <linux/fs.h>
15#include <linux/namei.h>
16#include <linux/mm.h>
17#include <linux/file.h>
18#include <linux/stat.h>
19#include <linux/smp_lock.h>
20#include <linux/limits.h>
21#include <linux/resource.h>
22#include <linux/quotaops.h>
23#include <linux/mount.h>
24#include <linux/vfs.h>
25
26#include <asm/uaccess.h>
27#include <asm/string.h>
28#include <asm/ptrace.h>
29
30#include "conv.h"
31
32#define R3_VERSION 1
33#define R4_VERSION 2
34
35typedef struct {
36 s32 tv_sec;
37 s32 tv_nsec;
38} timestruct_t;
39
40struct sol_stat {
41 u32 st_dev;
42 s32 st_pad1[3]; /* network id */
43 u32 st_ino;
44 u32 st_mode;
45 u32 st_nlink;
46 u32 st_uid;
47 u32 st_gid;
48 u32 st_rdev;
49 s32 st_pad2[2];
50 s32 st_size;
51 s32 st_pad3; /* st_size, off_t expansion */
52 timestruct_t st_atime;
53 timestruct_t st_mtime;
54 timestruct_t st_ctime;
55 s32 st_blksize;
56 s32 st_blocks;
57 char st_fstype[16];
58 s32 st_pad4[8]; /* expansion area */
59};
60
61struct sol_stat64 {
62 u32 st_dev;
63 s32 st_pad1[3]; /* network id */
64 u64 st_ino;
65 u32 st_mode;
66 u32 st_nlink;
67 u32 st_uid;
68 u32 st_gid;
69 u32 st_rdev;
70 s32 st_pad2[2];
71 s64 st_size;
72 timestruct_t st_atime;
73 timestruct_t st_mtime;
74 timestruct_t st_ctime;
75 s64 st_blksize;
76 s32 st_blocks;
77 char st_fstype[16];
78 s32 st_pad4[4]; /* expansion area */
79};
80
81#define UFSMAGIC (((unsigned)'u'<<24)||((unsigned)'f'<<16)||((unsigned)'s'<<8))
82
83static inline int putstat(struct sol_stat __user *ubuf, struct kstat *kbuf)
84{
85 u32 ino;
86
87 if (kbuf->size > MAX_NON_LFS ||
88 !sysv_valid_dev(kbuf->dev) ||
89 !sysv_valid_dev(kbuf->rdev))
90 return -EOVERFLOW;
91 ino = kbuf->ino;
92 if (sizeof(ino) < sizeof(kbuf->ino) && ino != kbuf->ino)
93 return -EOVERFLOW;
94 if (put_user (sysv_encode_dev(kbuf->dev), &ubuf->st_dev) ||
95 __put_user (ino, &ubuf->st_ino) ||
96 __put_user (kbuf->mode, &ubuf->st_mode) ||
97 __put_user (kbuf->nlink, &ubuf->st_nlink) ||
98 __put_user (kbuf->uid, &ubuf->st_uid) ||
99 __put_user (kbuf->gid, &ubuf->st_gid) ||
100 __put_user (sysv_encode_dev(kbuf->rdev), &ubuf->st_rdev) ||
101 __put_user (kbuf->size, &ubuf->st_size) ||
102 __put_user (kbuf->atime.tv_sec, &ubuf->st_atime.tv_sec) ||
103 __put_user (kbuf->atime.tv_nsec, &ubuf->st_atime.tv_nsec) ||
104 __put_user (kbuf->mtime.tv_sec, &ubuf->st_mtime.tv_sec) ||
105 __put_user (kbuf->mtime.tv_nsec, &ubuf->st_mtime.tv_nsec) ||
106 __put_user (kbuf->ctime.tv_sec, &ubuf->st_ctime.tv_sec) ||
107 __put_user (kbuf->ctime.tv_nsec, &ubuf->st_ctime.tv_nsec) ||
108 __put_user (kbuf->blksize, &ubuf->st_blksize) ||
109 __put_user (kbuf->blocks, &ubuf->st_blocks) ||
110 __put_user (UFSMAGIC, (unsigned __user *)ubuf->st_fstype))
111 return -EFAULT;
112 return 0;
113}
114
115static inline int putstat64(struct sol_stat64 __user *ubuf, struct kstat *kbuf)
116{
117 if (!sysv_valid_dev(kbuf->dev) || !sysv_valid_dev(kbuf->rdev))
118 return -EOVERFLOW;
119 if (put_user (sysv_encode_dev(kbuf->dev), &ubuf->st_dev) ||
120 __put_user (kbuf->ino, &ubuf->st_ino) ||
121 __put_user (kbuf->mode, &ubuf->st_mode) ||
122 __put_user (kbuf->nlink, &ubuf->st_nlink) ||
123 __put_user (kbuf->uid, &ubuf->st_uid) ||
124 __put_user (kbuf->gid, &ubuf->st_gid) ||
125 __put_user (sysv_encode_dev(kbuf->rdev), &ubuf->st_rdev) ||
126 __put_user (kbuf->size, &ubuf->st_size) ||
127 __put_user (kbuf->atime.tv_sec, &ubuf->st_atime.tv_sec) ||
128 __put_user (kbuf->atime.tv_nsec, &ubuf->st_atime.tv_nsec) ||
129 __put_user (kbuf->mtime.tv_sec, &ubuf->st_mtime.tv_sec) ||
130 __put_user (kbuf->mtime.tv_nsec, &ubuf->st_mtime.tv_nsec) ||
131 __put_user (kbuf->ctime.tv_sec, &ubuf->st_ctime.tv_sec) ||
132 __put_user (kbuf->ctime.tv_nsec, &ubuf->st_ctime.tv_nsec) ||
133 __put_user (kbuf->blksize, &ubuf->st_blksize) ||
134 __put_user (kbuf->blocks, &ubuf->st_blocks) ||
135 __put_user (UFSMAGIC, (unsigned __user *)ubuf->st_fstype))
136 return -EFAULT;
137 return 0;
138}
139
140asmlinkage int solaris_stat(u32 filename, u32 statbuf)
141{
142 struct kstat s;
143 int ret = vfs_stat(A(filename), &s);
144 if (!ret)
145 return putstat(A(statbuf), &s);
146 return ret;
147}
148
149asmlinkage int solaris_xstat(int vers, u32 filename, u32 statbuf)
150{
151 /* Solaris doesn't bother with looking at vers, so we do neither */
152 return solaris_stat(filename, statbuf);
153}
154
155asmlinkage int solaris_stat64(u32 filename, u32 statbuf)
156{
157 struct kstat s;
158 int ret = vfs_stat(A(filename), &s);
159 if (!ret)
160 return putstat64(A(statbuf), &s);
161 return ret;
162}
163
164asmlinkage int solaris_lstat(u32 filename, u32 statbuf)
165{
166 struct kstat s;
167 int ret = vfs_lstat(A(filename), &s);
168 if (!ret)
169 return putstat(A(statbuf), &s);
170 return ret;
171}
172
173asmlinkage int solaris_lxstat(int vers, u32 filename, u32 statbuf)
174{
175 return solaris_lstat(filename, statbuf);
176}
177
178asmlinkage int solaris_lstat64(u32 filename, u32 statbuf)
179{
180 struct kstat s;
181 int ret = vfs_lstat(A(filename), &s);
182 if (!ret)
183 return putstat64(A(statbuf), &s);
184 return ret;
185}
186
187asmlinkage int solaris_fstat(unsigned int fd, u32 statbuf)
188{
189 struct kstat s;
190 int ret = vfs_fstat(fd, &s);
191 if (!ret)
192 return putstat(A(statbuf), &s);
193 return ret;
194}
195
196asmlinkage int solaris_fxstat(int vers, u32 fd, u32 statbuf)
197{
198 return solaris_fstat(fd, statbuf);
199}
200
201asmlinkage int solaris_fstat64(unsigned int fd, u32 statbuf)
202{
203 struct kstat s;
204 int ret = vfs_fstat(fd, &s);
205 if (!ret)
206 return putstat64(A(statbuf), &s);
207 return ret;
208}
209
210asmlinkage int solaris_mknod(u32 path, u32 mode, s32 dev)
211{
212 int (*sys_mknod)(const char __user *,int,unsigned) =
213 (int (*)(const char __user *,int,unsigned))SYS(mknod);
214 int major = sysv_major(dev);
215 int minor = sysv_minor(dev);
216
217 /* minor is guaranteed to be OK for MKDEV, major might be not */
218 if (major > 0xfff)
219 return -EINVAL;
220 return sys_mknod(A(path), mode, new_encode_dev(MKDEV(major,minor)));
221}
222
223asmlinkage int solaris_xmknod(int vers, u32 path, u32 mode, s32 dev)
224{
225 return solaris_mknod(path, mode, dev);
226}
227
228asmlinkage int solaris_getdents64(unsigned int fd, void __user *dirent, unsigned int count)
229{
230 int (*sys_getdents)(unsigned int, void __user *, unsigned int) =
231 (int (*)(unsigned int, void __user *, unsigned int))SYS(getdents);
232
233 return sys_getdents(fd, dirent, count);
234}
235
236/* This statfs thingie probably will go in the near future, but... */
237
238struct sol_statfs {
239 short f_type;
240 s32 f_bsize;
241 s32 f_frsize;
242 s32 f_blocks;
243 s32 f_bfree;
244 u32 f_files;
245 u32 f_ffree;
246 char f_fname[6];
247 char f_fpack[6];
248};
249
250asmlinkage int solaris_statfs(u32 path, u32 buf, int len, int fstype)
251{
252 int ret;
253 struct statfs s;
254 mm_segment_t old_fs = get_fs();
255 int (*sys_statfs)(const char __user *,struct statfs __user *) =
256 (int (*)(const char __user *,struct statfs __user *))SYS(statfs);
257 struct sol_statfs __user *ss = A(buf);
258
259 if (len != sizeof(struct sol_statfs)) return -EINVAL;
260 if (!fstype) {
261 /* FIXME: mixing userland and kernel pointers */
262 set_fs (KERNEL_DS);
263 ret = sys_statfs(A(path), &s);
264 set_fs (old_fs);
265 if (!ret) {
266 if (put_user (s.f_type, &ss->f_type) ||
267 __put_user (s.f_bsize, &ss->f_bsize) ||
268 __put_user (0, &ss->f_frsize) ||
269 __put_user (s.f_blocks, &ss->f_blocks) ||
270 __put_user (s.f_bfree, &ss->f_bfree) ||
271 __put_user (s.f_files, &ss->f_files) ||
272 __put_user (s.f_ffree, &ss->f_ffree) ||
273 __clear_user (&ss->f_fname, 12))
274 return -EFAULT;
275 }
276 return ret;
277 }
278/* Linux can't stat unmounted filesystems so we
279 * simply lie and claim 100MB of 1GB is free. Sorry.
280 */
281 if (put_user (fstype, &ss->f_type) ||
282 __put_user (1024, &ss->f_bsize) ||
283 __put_user (0, &ss->f_frsize) ||
284 __put_user (1024*1024, &ss->f_blocks) ||
285 __put_user (100*1024, &ss->f_bfree) ||
286 __put_user (60000, &ss->f_files) ||
287 __put_user (50000, &ss->f_ffree) ||
288 __clear_user (&ss->f_fname, 12))
289 return -EFAULT;
290 return 0;
291}
292
293asmlinkage int solaris_fstatfs(u32 fd, u32 buf, int len, int fstype)
294{
295 int ret;
296 struct statfs s;
297 mm_segment_t old_fs = get_fs();
298 int (*sys_fstatfs)(unsigned,struct statfs __user *) =
299 (int (*)(unsigned,struct statfs __user *))SYS(fstatfs);
300 struct sol_statfs __user *ss = A(buf);
301
302 if (len != sizeof(struct sol_statfs)) return -EINVAL;
303 if (!fstype) {
304 set_fs (KERNEL_DS);
305 ret = sys_fstatfs(fd, &s);
306 set_fs (old_fs);
307 if (!ret) {
308 if (put_user (s.f_type, &ss->f_type) ||
309 __put_user (s.f_bsize, &ss->f_bsize) ||
310 __put_user (0, &ss->f_frsize) ||
311 __put_user (s.f_blocks, &ss->f_blocks) ||
312 __put_user (s.f_bfree, &ss->f_bfree) ||
313 __put_user (s.f_files, &ss->f_files) ||
314 __put_user (s.f_ffree, &ss->f_ffree) ||
315 __clear_user (&ss->f_fname, 12))
316 return -EFAULT;
317 }
318 return ret;
319 }
320 /* Otherwise fstatfs is the same as statfs */
321 return solaris_statfs(0, buf, len, fstype);
322}
323
324struct sol_statvfs {
325 u32 f_bsize;
326 u32 f_frsize;
327 u32 f_blocks;
328 u32 f_bfree;
329 u32 f_bavail;
330 u32 f_files;
331 u32 f_ffree;
332 u32 f_favail;
333 u32 f_fsid;
334 char f_basetype[16];
335 u32 f_flag;
336 u32 f_namemax;
337 char f_fstr[32];
338 u32 f_filler[16];
339};
340
341struct sol_statvfs64 {
342 u32 f_bsize;
343 u32 f_frsize;
344 u64 f_blocks;
345 u64 f_bfree;
346 u64 f_bavail;
347 u64 f_files;
348 u64 f_ffree;
349 u64 f_favail;
350 u32 f_fsid;
351 char f_basetype[16];
352 u32 f_flag;
353 u32 f_namemax;
354 char f_fstr[32];
355 u32 f_filler[16];
356};
357
358static int report_statvfs(struct vfsmount *mnt, struct inode *inode, u32 buf)
359{
360 struct kstatfs s;
361 int error;
362 struct sol_statvfs __user *ss = A(buf);
363
364 error = vfs_statfs(mnt->mnt_root, &s);
365 if (!error) {
366 const char *p = mnt->mnt_sb->s_type->name;
367 int i = 0;
368 int j = strlen (p);
369
370 if (j > 15) j = 15;
371 if (IS_RDONLY(inode)) i = 1;
372 if (mnt->mnt_flags & MNT_NOSUID) i |= 2;
373 if (!sysv_valid_dev(inode->i_sb->s_dev))
374 return -EOVERFLOW;
375 if (put_user (s.f_bsize, &ss->f_bsize) ||
376 __put_user (0, &ss->f_frsize) ||
377 __put_user (s.f_blocks, &ss->f_blocks) ||
378 __put_user (s.f_bfree, &ss->f_bfree) ||
379 __put_user (s.f_bavail, &ss->f_bavail) ||
380 __put_user (s.f_files, &ss->f_files) ||
381 __put_user (s.f_ffree, &ss->f_ffree) ||
382 __put_user (s.f_ffree, &ss->f_favail) ||
383 __put_user (sysv_encode_dev(inode->i_sb->s_dev), &ss->f_fsid) ||
384 __copy_to_user (ss->f_basetype,p,j) ||
385 __put_user (0, (char __user *)&ss->f_basetype[j]) ||
386 __put_user (s.f_namelen, &ss->f_namemax) ||
387 __put_user (i, &ss->f_flag) ||
388 __clear_user (&ss->f_fstr, 32))
389 return -EFAULT;
390 }
391 return error;
392}
393
394static int report_statvfs64(struct vfsmount *mnt, struct inode *inode, u32 buf)
395{
396 struct kstatfs s;
397 int error;
398 struct sol_statvfs64 __user *ss = A(buf);
399
400 error = vfs_statfs(mnt->mnt_root, &s);
401 if (!error) {
402 const char *p = mnt->mnt_sb->s_type->name;
403 int i = 0;
404 int j = strlen (p);
405
406 if (j > 15) j = 15;
407 if (IS_RDONLY(inode)) i = 1;
408 if (mnt->mnt_flags & MNT_NOSUID) i |= 2;
409 if (!sysv_valid_dev(inode->i_sb->s_dev))
410 return -EOVERFLOW;
411 if (put_user (s.f_bsize, &ss->f_bsize) ||
412 __put_user (0, &ss->f_frsize) ||
413 __put_user (s.f_blocks, &ss->f_blocks) ||
414 __put_user (s.f_bfree, &ss->f_bfree) ||
415 __put_user (s.f_bavail, &ss->f_bavail) ||
416 __put_user (s.f_files, &ss->f_files) ||
417 __put_user (s.f_ffree, &ss->f_ffree) ||
418 __put_user (s.f_ffree, &ss->f_favail) ||
419 __put_user (sysv_encode_dev(inode->i_sb->s_dev), &ss->f_fsid) ||
420 __copy_to_user (ss->f_basetype,p,j) ||
421 __put_user (0, (char __user *)&ss->f_basetype[j]) ||
422 __put_user (s.f_namelen, &ss->f_namemax) ||
423 __put_user (i, &ss->f_flag) ||
424 __clear_user (&ss->f_fstr, 32))
425 return -EFAULT;
426 }
427 return error;
428}
429
430asmlinkage int solaris_statvfs(u32 path, u32 buf)
431{
432 struct nameidata nd;
433 int error;
434
435 error = user_path_walk(A(path),&nd);
436 if (!error) {
437 struct inode *inode = nd.path.dentry->d_inode;
438 error = report_statvfs(nd.path.mnt, inode, buf);
439 path_put(&nd.path);
440 }
441 return error;
442}
443
444asmlinkage int solaris_fstatvfs(unsigned int fd, u32 buf)
445{
446 struct file * file;
447 int error;
448
449 error = -EBADF;
450 file = fget(fd);
451 if (file) {
452 error = report_statvfs(file->f_path.mnt, file->f_path.dentry->d_inode, buf);
453 fput(file);
454 }
455
456 return error;
457}
458
459asmlinkage int solaris_statvfs64(u32 path, u32 buf)
460{
461 struct nameidata nd;
462 int error;
463
464 lock_kernel();
465 error = user_path_walk(A(path), &nd);
466 if (!error) {
467 struct inode *inode = nd.path.dentry->d_inode;
468 error = report_statvfs64(nd.path.mnt, inode, buf);
469 path_put(&nd.path);
470 }
471 unlock_kernel();
472 return error;
473}
474
475asmlinkage int solaris_fstatvfs64(unsigned int fd, u32 buf)
476{
477 struct file * file;
478 int error;
479
480 error = -EBADF;
481 file = fget(fd);
482 if (file) {
483 lock_kernel();
484 error = report_statvfs64(file->f_path.mnt, file->f_path.dentry->d_inode, buf);
485 unlock_kernel();
486 fput(file);
487 }
488 return error;
489}
490
491extern asmlinkage long sparc32_open(const char * filename, int flags, int mode);
492
493asmlinkage int solaris_open(u32 fname, int flags, u32 mode)
494{
495 const char *filename = (const char *)(long)fname;
496 int fl = flags & 0xf;
497
498 /* Translate flags first. */
499 if (flags & 0x2000) fl |= O_LARGEFILE;
500 if (flags & 0x8050) fl |= O_SYNC;
501 if (flags & 0x80) fl |= O_NONBLOCK;
502 if (flags & 0x100) fl |= O_CREAT;
503 if (flags & 0x200) fl |= O_TRUNC;
504 if (flags & 0x400) fl |= O_EXCL;
505 if (flags & 0x800) fl |= O_NOCTTY;
506 flags = fl;
507
508 return sparc32_open(filename, flags, mode);
509}
510
511#define SOL_F_SETLK 6
512#define SOL_F_SETLKW 7
513#define SOL_F_FREESP 11
514#define SOL_F_ISSTREAM 13
515#define SOL_F_GETLK 14
516#define SOL_F_PRIV 15
517#define SOL_F_NPRIV 16
518#define SOL_F_QUOTACTL 17
519#define SOL_F_BLOCKS 18
520#define SOL_F_BLKSIZE 19
521#define SOL_F_GETOWN 23
522#define SOL_F_SETOWN 24
523
524struct sol_flock {
525 short l_type;
526 short l_whence;
527 u32 l_start;
528 u32 l_len;
529 s32 l_sysid;
530 s32 l_pid;
531 s32 l_pad[4];
532};
533
534asmlinkage int solaris_fcntl(unsigned fd, unsigned cmd, u32 arg)
535{
536 int (*sys_fcntl)(unsigned,unsigned,unsigned long) =
537 (int (*)(unsigned,unsigned,unsigned long))SYS(fcntl);
538 int ret, flags;
539
540 switch (cmd) {
541 case F_DUPFD:
542 case F_GETFD:
543 case F_SETFD: return sys_fcntl(fd, cmd, (unsigned long)arg);
544 case F_GETFL:
545 flags = sys_fcntl(fd, cmd, 0);
546 ret = flags & 0xf;
547 if (flags & O_SYNC) ret |= 0x8050;
548 if (flags & O_NONBLOCK) ret |= 0x80;
549 return ret;
550 case F_SETFL:
551 flags = arg & 0xf;
552 if (arg & 0x8050) flags |= O_SYNC;
553 if (arg & 0x80) flags |= O_NONBLOCK;
554 return sys_fcntl(fd, cmd, (long)flags);
555 case SOL_F_GETLK:
556 case SOL_F_SETLK:
557 case SOL_F_SETLKW:
558 {
559 struct flock f;
560 struct sol_flock __user *p = A(arg);
561 mm_segment_t old_fs = get_fs();
562
563 switch (cmd) {
564 case SOL_F_GETLK: cmd = F_GETLK; break;
565 case SOL_F_SETLK: cmd = F_SETLK; break;
566 case SOL_F_SETLKW: cmd = F_SETLKW; break;
567 }
568
569 if (get_user (f.l_type, &p->l_type) ||
570 __get_user (f.l_whence, &p->l_whence) ||
571 __get_user (f.l_start, &p->l_start) ||
572 __get_user (f.l_len, &p->l_len) ||
573 __get_user (f.l_pid, &p->l_sysid))
574 return -EFAULT;
575
576 set_fs(KERNEL_DS);
577 ret = sys_fcntl(fd, cmd, (unsigned long)&f);
578 set_fs(old_fs);
579
580 if (__put_user (f.l_type, &p->l_type) ||
581 __put_user (f.l_whence, &p->l_whence) ||
582 __put_user (f.l_start, &p->l_start) ||
583 __put_user (f.l_len, &p->l_len) ||
584 __put_user (f.l_pid, &p->l_pid) ||
585 __put_user (0, &p->l_sysid))
586 return -EFAULT;
587
588 return ret;
589 }
590 case SOL_F_FREESP:
591 {
592 int length;
593 int (*sys_newftruncate)(unsigned int, unsigned long)=
594 (int (*)(unsigned int, unsigned long))SYS(ftruncate);
595
596 if (get_user(length, &((struct sol_flock __user *)A(arg))->l_start))
597 return -EFAULT;
598
599 return sys_newftruncate(fd, length);
600 }
601 };
602 return -EINVAL;
603}
604
605asmlinkage int solaris_ulimit(int cmd, int val)
606{
607 switch (cmd) {
608 case 1: /* UL_GETFSIZE - in 512B chunks */
609 return current->signal->rlim[RLIMIT_FSIZE].rlim_cur >> 9;
610 case 2: /* UL_SETFSIZE */
611 if ((unsigned long)val > (LONG_MAX>>9)) return -ERANGE;
612 val <<= 9;
613 task_lock(current->group_leader);
614 if (val > current->signal->rlim[RLIMIT_FSIZE].rlim_max) {
615 if (!capable(CAP_SYS_RESOURCE)) {
616 task_unlock(current->group_leader);
617 return -EPERM;
618 }
619 current->signal->rlim[RLIMIT_FSIZE].rlim_max = val;
620 }
621 current->signal->rlim[RLIMIT_FSIZE].rlim_cur = val;
622 task_unlock(current->group_leader);
623 return 0;
624 case 3: /* UL_GMEMLIM */
625 return current->signal->rlim[RLIMIT_DATA].rlim_cur;
626 case 4: /* UL_GDESLIM */
627 return sysctl_nr_open;
628 }
629 return -EINVAL;
630}
631
632/* At least at the time I'm writing this, Linux doesn't have ACLs, so we
633 just fake this */
634asmlinkage int solaris_acl(u32 filename, int cmd, int nentries, u32 aclbufp)
635{
636 return -ENOSYS;
637}
638
639asmlinkage int solaris_facl(unsigned int fd, int cmd, int nentries, u32 aclbufp)
640{
641 return -ENOSYS;
642}
643
644asmlinkage int solaris_pread(unsigned int fd, char __user *buf, u32 count, u32 pos)
645{
646 ssize_t (*sys_pread64)(unsigned int, char __user *, size_t, loff_t) =
647 (ssize_t (*)(unsigned int, char __user *, size_t, loff_t))SYS(pread64);
648
649 return sys_pread64(fd, buf, count, (loff_t)pos);
650}
651
652asmlinkage int solaris_pwrite(unsigned int fd, char __user *buf, u32 count, u32 pos)
653{
654 ssize_t (*sys_pwrite64)(unsigned int, char __user *, size_t, loff_t) =
655 (ssize_t (*)(unsigned int, char __user *, size_t, loff_t))SYS(pwrite64);
656
657 return sys_pwrite64(fd, buf, count, (loff_t)pos);
658}
659
660/* POSIX.1 names */
661#define _PC_LINK_MAX 1
662#define _PC_MAX_CANON 2
663#define _PC_MAX_INPUT 3
664#define _PC_NAME_MAX 4
665#define _PC_PATH_MAX 5
666#define _PC_PIPE_BUF 6
667#define _PC_NO_TRUNC 7
668#define _PC_VDISABLE 8
669#define _PC_CHOWN_RESTRICTED 9
670/* POSIX.4 names */
671#define _PC_ASYNC_IO 10
672#define _PC_PRIO_IO 11
673#define _PC_SYNC_IO 12
674#define _PC_LAST 12
675
676/* This is not a real and complete implementation yet, just to keep
677 * the easy Solaris binaries happy.
678 */
679asmlinkage int solaris_fpathconf(int fd, int name)
680{
681 int ret;
682
683 switch(name) {
684 case _PC_LINK_MAX:
685 ret = LINK_MAX;
686 break;
687 case _PC_MAX_CANON:
688 ret = MAX_CANON;
689 break;
690 case _PC_MAX_INPUT:
691 ret = MAX_INPUT;
692 break;
693 case _PC_NAME_MAX:
694 ret = NAME_MAX;
695 break;
696 case _PC_PATH_MAX:
697 ret = PATH_MAX;
698 break;
699 case _PC_PIPE_BUF:
700 ret = PIPE_BUF;
701 break;
702 case _PC_CHOWN_RESTRICTED:
703 ret = 1;
704 break;
705 case _PC_NO_TRUNC:
706 case _PC_VDISABLE:
707 ret = 0;
708 break;
709 default:
710 ret = -EINVAL;
711 break;
712 }
713 return ret;
714}
715
716asmlinkage int solaris_pathconf(u32 path, int name)
717{
718 return solaris_fpathconf(0, name);
719}
720
721/* solaris_llseek returns long long - quite difficult */
722asmlinkage long solaris_llseek(struct pt_regs *regs, u32 off_hi, u32 off_lo, int whence)
723{
724 int (*sys_llseek)(unsigned int, unsigned long, unsigned long, loff_t __user *, unsigned int) =
725 (int (*)(unsigned int, unsigned long, unsigned long, loff_t __user *, unsigned int))SYS(_llseek);
726 int ret;
727 mm_segment_t old_fs = get_fs();
728 loff_t retval;
729
730 set_fs(KERNEL_DS);
731 ret = sys_llseek((unsigned int)regs->u_regs[UREG_I0], off_hi, off_lo, &retval, whence);
732 set_fs(old_fs);
733 if (ret < 0) return ret;
734 regs->u_regs[UREG_I1] = (u32)retval;
735 return (retval >> 32);
736}
737
738/* Have to mask out all but lower 3 bits */
739asmlinkage int solaris_access(u32 filename, long mode)
740{
741 int (*sys_access)(const char __user *, int) =
742 (int (*)(const char __user *, int))SYS(access);
743
744 return sys_access(A(filename), mode & 7);
745}
diff --git a/arch/sparc64/solaris/ioctl.c b/arch/sparc64/solaris/ioctl.c
deleted file mode 100644
index 8ad10a6d993b..000000000000
--- a/arch/sparc64/solaris/ioctl.c
+++ /dev/null
@@ -1,825 +0,0 @@
1/* $Id: ioctl.c,v 1.17 2002/02/08 03:57:14 davem Exp $
2 * ioctl.c: Solaris ioctl emulation.
3 *
4 * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5 * Copyright (C) 1997,1998 Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)
6 *
7 * Streams & timod emulation based on code
8 * Copyright (C) 1995, 1996 Mike Jagdis (jaggy@purplet.demon.co.uk)
9 *
10 * 1999-08-19 Implemented solaris 'm' (mag tape) and
11 * 'O' (openprom) ioctls, by Jason Rappleye
12 * (rappleye@ccr.buffalo.edu)
13 */
14
15#include <linux/types.h>
16#include <linux/kernel.h>
17#include <linux/sched.h>
18#include <linux/smp.h>
19#include <linux/smp_lock.h>
20#include <linux/syscalls.h>
21#include <linux/ioctl.h>
22#include <linux/fs.h>
23#include <linux/file.h>
24#include <linux/netdevice.h>
25#include <linux/mtio.h>
26#include <linux/time.h>
27#include <linux/rcupdate.h>
28#include <linux/compat.h>
29
30#include <net/sock.h>
31#include <net/net_namespace.h>
32
33#include <asm/uaccess.h>
34#include <asm/termios.h>
35#include <asm/openpromio.h>
36
37#include "conv.h"
38#include "socksys.h"
39
40extern asmlinkage int compat_sys_ioctl(unsigned int fd, unsigned int cmd,
41 u32 arg);
42asmlinkage int solaris_ioctl(unsigned int fd, unsigned int cmd, u32 arg);
43
44extern int timod_putmsg(unsigned int fd, char __user *ctl_buf, int ctl_len,
45 char __user *data_buf, int data_len, int flags);
46extern int timod_getmsg(unsigned int fd, char __user *ctl_buf, int ctl_maxlen, int __user *ctl_len,
47 char __user *data_buf, int data_maxlen, int __user *data_len, int *flags);
48
49/* termio* stuff {{{ */
50
51struct solaris_termios {
52 u32 c_iflag;
53 u32 c_oflag;
54 u32 c_cflag;
55 u32 c_lflag;
56 u8 c_cc[19];
57};
58
59struct solaris_termio {
60 u16 c_iflag;
61 u16 c_oflag;
62 u16 c_cflag;
63 u16 c_lflag;
64 s8 c_line;
65 u8 c_cc[8];
66};
67
68struct solaris_termiox {
69 u16 x_hflag;
70 u16 x_cflag;
71 u16 x_rflag[5];
72 u16 x_sflag;
73};
74
75static u32 solaris_to_linux_cflag(u32 cflag)
76{
77 cflag &= 0x7fdff000;
78 if (cflag & 0x200000) {
79 int baud = cflag & 0xf;
80 cflag &= ~0x20000f;
81 switch (baud) {
82 case 0: baud = B57600; break;
83 case 1: baud = B76800; break;
84 case 2: baud = B115200; break;
85 case 3: baud = B153600; break;
86 case 4: baud = B230400; break;
87 case 5: baud = B307200; break;
88 case 6: baud = B460800; break;
89 }
90 cflag |= CBAUDEX | baud;
91 }
92 return cflag;
93}
94
95static u32 linux_to_solaris_cflag(u32 cflag)
96{
97 cflag &= ~(CMSPAR | CIBAUD);
98 if (cflag & CBAUDEX) {
99 int baud = cflag & CBAUD;
100 cflag &= ~CBAUD;
101 switch (baud) {
102 case B57600: baud = 0; break;
103 case B76800: baud = 1; break;
104 case B115200: baud = 2; break;
105 case B153600: baud = 3; break;
106 case B230400: baud = 4; break;
107 case B307200: baud = 5; break;
108 case B460800: baud = 6; break;
109 case B614400: baud = 7; break;
110 case B921600: baud = 8; break;
111#if 0
112 case B1843200: baud = 9; break;
113#endif
114 }
115 cflag |= 0x200000 | baud;
116 }
117 return cflag;
118}
119
120static inline int linux_to_solaris_termio(unsigned int fd, unsigned int cmd, u32 arg)
121{
122 struct solaris_termio __user *p = A(arg);
123 int ret;
124
125 ret = sys_ioctl(fd, cmd, (unsigned long)p);
126 if (!ret) {
127 u32 cflag;
128
129 if (__get_user (cflag, &p->c_cflag))
130 return -EFAULT;
131 cflag = linux_to_solaris_cflag(cflag);
132 if (__put_user (cflag, &p->c_cflag))
133 return -EFAULT;
134 }
135 return ret;
136}
137
138static int solaris_to_linux_termio(unsigned int fd, unsigned int cmd, u32 arg)
139{
140 int ret;
141 struct solaris_termio s;
142 mm_segment_t old_fs = get_fs();
143
144 if (copy_from_user (&s, (struct solaris_termio __user *)A(arg), sizeof(struct solaris_termio)))
145 return -EFAULT;
146 s.c_cflag = solaris_to_linux_cflag(s.c_cflag);
147 set_fs(KERNEL_DS);
148 ret = sys_ioctl(fd, cmd, (unsigned long)&s);
149 set_fs(old_fs);
150 return ret;
151}
152
153static inline int linux_to_solaris_termios(unsigned int fd, unsigned int cmd, u32 arg)
154{
155 int ret;
156 struct solaris_termios s;
157 mm_segment_t old_fs = get_fs();
158
159 set_fs(KERNEL_DS);
160 ret = sys_ioctl(fd, cmd, (unsigned long)&s);
161 set_fs(old_fs);
162 if (!ret) {
163 struct solaris_termios __user *p = A(arg);
164 if (put_user (s.c_iflag, &p->c_iflag) ||
165 __put_user (s.c_oflag, &p->c_oflag) ||
166 __put_user (linux_to_solaris_cflag(s.c_cflag), &p->c_cflag) ||
167 __put_user (s.c_lflag, &p->c_lflag) ||
168 __copy_to_user (p->c_cc, s.c_cc, 16) ||
169 __clear_user (p->c_cc + 16, 2))
170 return -EFAULT;
171 }
172 return ret;
173}
174
175static int solaris_to_linux_termios(unsigned int fd, unsigned int cmd, u32 arg)
176{
177 int ret;
178 struct solaris_termios s;
179 struct solaris_termios __user *p = A(arg);
180 mm_segment_t old_fs = get_fs();
181
182 set_fs(KERNEL_DS);
183 ret = sys_ioctl(fd, TCGETS, (unsigned long)&s);
184 set_fs(old_fs);
185 if (ret) return ret;
186 if (put_user (s.c_iflag, &p->c_iflag) ||
187 __put_user (s.c_oflag, &p->c_oflag) ||
188 __put_user (s.c_cflag, &p->c_cflag) ||
189 __put_user (s.c_lflag, &p->c_lflag) ||
190 __copy_from_user (s.c_cc, p->c_cc, 16))
191 return -EFAULT;
192 s.c_cflag = solaris_to_linux_cflag(s.c_cflag);
193 set_fs(KERNEL_DS);
194 ret = sys_ioctl(fd, cmd, (unsigned long)&s);
195 set_fs(old_fs);
196 return ret;
197}
198
199static inline int solaris_T(unsigned int fd, unsigned int cmd, u32 arg)
200{
201 switch (cmd & 0xff) {
202 case 1: /* TCGETA */
203 return linux_to_solaris_termio(fd, TCGETA, arg);
204 case 2: /* TCSETA */
205 return solaris_to_linux_termio(fd, TCSETA, arg);
206 case 3: /* TCSETAW */
207 return solaris_to_linux_termio(fd, TCSETAW, arg);
208 case 4: /* TCSETAF */
209 return solaris_to_linux_termio(fd, TCSETAF, arg);
210 case 5: /* TCSBRK */
211 return sys_ioctl(fd, TCSBRK, arg);
212 case 6: /* TCXONC */
213 return sys_ioctl(fd, TCXONC, arg);
214 case 7: /* TCFLSH */
215 return sys_ioctl(fd, TCFLSH, arg);
216 case 13: /* TCGETS */
217 return linux_to_solaris_termios(fd, TCGETS, arg);
218 case 14: /* TCSETS */
219 return solaris_to_linux_termios(fd, TCSETS, arg);
220 case 15: /* TCSETSW */
221 return solaris_to_linux_termios(fd, TCSETSW, arg);
222 case 16: /* TCSETSF */
223 return solaris_to_linux_termios(fd, TCSETSF, arg);
224 case 103: /* TIOCSWINSZ */
225 return sys_ioctl(fd, TIOCSWINSZ, arg);
226 case 104: /* TIOCGWINSZ */
227 return sys_ioctl(fd, TIOCGWINSZ, arg);
228 }
229 return -ENOSYS;
230}
231
232static inline int solaris_t(unsigned int fd, unsigned int cmd, u32 arg)
233{
234 switch (cmd & 0xff) {
235 case 20: /* TIOCGPGRP */
236 return sys_ioctl(fd, TIOCGPGRP, arg);
237 case 21: /* TIOCSPGRP */
238 return sys_ioctl(fd, TIOCSPGRP, arg);
239 }
240 return -ENOSYS;
241}
242
243/* }}} */
244
245/* A pseudo STREAMS support {{{ */
246
247struct strioctl {
248 int cmd, timeout, len;
249 u32 data;
250};
251
252struct solaris_si_sockparams {
253 int sp_family;
254 int sp_type;
255 int sp_protocol;
256};
257
258struct solaris_o_si_udata {
259 int tidusize;
260 int addrsize;
261 int optsize;
262 int etsdusize;
263 int servtype;
264 int so_state;
265 int so_options;
266 int tsdusize;
267};
268
269struct solaris_si_udata {
270 int tidusize;
271 int addrsize;
272 int optsize;
273 int etsdusize;
274 int servtype;
275 int so_state;
276 int so_options;
277 int tsdusize;
278 struct solaris_si_sockparams sockparams;
279};
280
281#define SOLARIS_MODULE_TIMOD 0
282#define SOLARIS_MODULE_SOCKMOD 1
283#define SOLARIS_MODULE_MAX 2
284
285static struct module_info {
286 const char *name;
287 /* can be expanded further if needed */
288} module_table[ SOLARIS_MODULE_MAX + 1 ] = {
289 /* the ordering here must match the module numbers above! */
290 { "timod" },
291 { "sockmod" },
292 { NULL }
293};
294
295static inline int solaris_sockmod(unsigned int fd, unsigned int cmd, u32 arg)
296{
297 struct inode *ino;
298 struct fdtable *fdt;
299 /* I wonder which of these tests are superfluous... --patrik */
300 rcu_read_lock();
301 fdt = files_fdtable(current->files);
302 if (! fdt->fd[fd] ||
303 ! fdt->fd[fd]->f_path.dentry ||
304 ! (ino = fdt->fd[fd]->f_path.dentry->d_inode) ||
305 ! S_ISSOCK(ino->i_mode)) {
306 rcu_read_unlock();
307 return TBADF;
308 }
309 rcu_read_unlock();
310
311 switch (cmd & 0xff) {
312 case 109: /* SI_SOCKPARAMS */
313 {
314 struct solaris_si_sockparams si;
315 if (copy_from_user (&si, A(arg), sizeof(si)))
316 return (EFAULT << 8) | TSYSERR;
317
318 /* Should we modify socket ino->socket_i.ops and type? */
319 return 0;
320 }
321 case 110: /* SI_GETUDATA */
322 {
323 int etsdusize, servtype;
324 struct solaris_si_udata __user *p = A(arg);
325 switch (SOCKET_I(ino)->type) {
326 case SOCK_STREAM:
327 etsdusize = 1;
328 servtype = 2;
329 break;
330 default:
331 etsdusize = -2;
332 servtype = 3;
333 break;
334 }
335 if (put_user(16384, &p->tidusize) ||
336 __put_user(sizeof(struct sockaddr), &p->addrsize) ||
337 __put_user(-1, &p->optsize) ||
338 __put_user(etsdusize, &p->etsdusize) ||
339 __put_user(servtype, &p->servtype) ||
340 __put_user(0, &p->so_state) ||
341 __put_user(0, &p->so_options) ||
342 __put_user(16384, &p->tsdusize) ||
343 __put_user(SOCKET_I(ino)->ops->family, &p->sockparams.sp_family) ||
344 __put_user(SOCKET_I(ino)->type, &p->sockparams.sp_type) ||
345 __put_user(SOCKET_I(ino)->ops->family, &p->sockparams.sp_protocol))
346 return (EFAULT << 8) | TSYSERR;
347 return 0;
348 }
349 case 101: /* O_SI_GETUDATA */
350 {
351 int etsdusize, servtype;
352 struct solaris_o_si_udata __user *p = A(arg);
353 switch (SOCKET_I(ino)->type) {
354 case SOCK_STREAM:
355 etsdusize = 1;
356 servtype = 2;
357 break;
358 default:
359 etsdusize = -2;
360 servtype = 3;
361 break;
362 }
363 if (put_user(16384, &p->tidusize) ||
364 __put_user(sizeof(struct sockaddr), &p->addrsize) ||
365 __put_user(-1, &p->optsize) ||
366 __put_user(etsdusize, &p->etsdusize) ||
367 __put_user(servtype, &p->servtype) ||
368 __put_user(0, &p->so_state) ||
369 __put_user(0, &p->so_options) ||
370 __put_user(16384, &p->tsdusize))
371 return (EFAULT << 8) | TSYSERR;
372 return 0;
373 }
374 case 102: /* SI_SHUTDOWN */
375 case 103: /* SI_LISTEN */
376 case 104: /* SI_SETMYNAME */
377 case 105: /* SI_SETPEERNAME */
378 case 106: /* SI_GETINTRANSIT */
379 case 107: /* SI_TCL_LINK */
380 case 108: /* SI_TCL_UNLINK */
381 ;
382 }
383 return TNOTSUPPORT;
384}
385
386static inline int solaris_timod(unsigned int fd, unsigned int cmd, u32 arg,
387 int len, int __user *len_p)
388{
389 int ret;
390
391 switch (cmd & 0xff) {
392 case 141: /* TI_OPTMGMT */
393 {
394 int i;
395 u32 prim;
396 SOLD("TI_OPMGMT entry");
397 ret = timod_putmsg(fd, A(arg), len, NULL, -1, 0);
398 SOLD("timod_putmsg() returned");
399 if (ret)
400 return (-ret << 8) | TSYSERR;
401 i = MSG_HIPRI;
402 SOLD("calling timod_getmsg()");
403 ret = timod_getmsg(fd, A(arg), len, len_p, NULL, -1, NULL, &i);
404 SOLD("timod_getmsg() returned");
405 if (ret)
406 return (-ret << 8) | TSYSERR;
407 SOLD("ret ok");
408 if (get_user(prim, (u32 __user *)A(arg)))
409 return (EFAULT << 8) | TSYSERR;
410 SOLD("got prim");
411 if (prim == T_ERROR_ACK) {
412 u32 tmp, tmp2;
413 SOLD("prim is T_ERROR_ACK");
414 if (get_user(tmp, (u32 __user *)A(arg)+3) ||
415 get_user(tmp2, (u32 __user *)A(arg)+2))
416 return (EFAULT << 8) | TSYSERR;
417 return (tmp2 << 8) | tmp;
418 }
419 SOLD("TI_OPMGMT return 0");
420 return 0;
421 }
422 case 142: /* TI_BIND */
423 {
424 int i;
425 u32 prim;
426 SOLD("TI_BIND entry");
427 ret = timod_putmsg(fd, A(arg), len, NULL, -1, 0);
428 SOLD("timod_putmsg() returned");
429 if (ret)
430 return (-ret << 8) | TSYSERR;
431 len = 1024; /* Solaris allows arbitrary return size */
432 i = MSG_HIPRI;
433 SOLD("calling timod_getmsg()");
434 ret = timod_getmsg(fd, A(arg), len, len_p, NULL, -1, NULL, &i);
435 SOLD("timod_getmsg() returned");
436 if (ret)
437 return (-ret << 8) | TSYSERR;
438 SOLD("ret ok");
439 if (get_user(prim, (u32 __user *)A(arg)))
440 return (EFAULT << 8) | TSYSERR;
441 SOLD("got prim");
442 if (prim == T_ERROR_ACK) {
443 u32 tmp, tmp2;
444 SOLD("prim is T_ERROR_ACK");
445 if (get_user(tmp, (u32 __user *)A(arg)+3) ||
446 get_user(tmp2, (u32 __user *)A(arg)+2))
447 return (EFAULT << 8) | TSYSERR;
448 return (tmp2 << 8) | tmp;
449 }
450 SOLD("no ERROR_ACK requested");
451 if (prim != T_OK_ACK)
452 return TBADSEQ;
453 SOLD("OK_ACK requested");
454 i = MSG_HIPRI;
455 SOLD("calling timod_getmsg()");
456 ret = timod_getmsg(fd, A(arg), len, len_p, NULL, -1, NULL, &i);
457 SOLD("timod_getmsg() returned");
458 if (ret)
459 return (-ret << 8) | TSYSERR;
460 SOLD("TI_BIND return ok");
461 return 0;
462 }
463 case 140: /* TI_GETINFO */
464 case 143: /* TI_UNBIND */
465 case 144: /* TI_GETMYNAME */
466 case 145: /* TI_GETPEERNAME */
467 case 146: /* TI_SETMYNAME */
468 case 147: /* TI_SETPEERNAME */
469 ;
470 }
471 return TNOTSUPPORT;
472}
473
474static inline int solaris_S(struct file *filp, unsigned int fd, unsigned int cmd, u32 arg)
475{
476 char *p;
477 int ret;
478 mm_segment_t old_fs;
479 struct strioctl si;
480 struct inode *ino;
481 struct sol_socket_struct *sock;
482 struct module_info *mi;
483
484 ino = filp->f_path.dentry->d_inode;
485 if (!S_ISSOCK(ino->i_mode))
486 return -EBADF;
487 sock = filp->private_data;
488 if (! sock) {
489 printk("solaris_S: NULL private_data\n");
490 return -EBADF;
491 }
492 if (sock->magic != SOLARIS_SOCKET_MAGIC) {
493 printk("solaris_S: invalid magic\n");
494 return -EBADF;
495 }
496
497
498 switch (cmd & 0xff) {
499 case 1: /* I_NREAD */
500 return -ENOSYS;
501 case 2: /* I_PUSH */
502 {
503 p = getname (A(arg));
504 if (IS_ERR (p))
505 return PTR_ERR(p);
506 ret = -EINVAL;
507 for (mi = module_table; mi->name; mi++) {
508 if (strcmp(mi->name, p) == 0) {
509 sol_module m;
510 if (sock->modcount >= MAX_NR_STREAM_MODULES) {
511 ret = -ENXIO;
512 break;
513 }
514 m = (sol_module) (mi - module_table);
515 sock->module[sock->modcount++] = m;
516 ret = 0;
517 break;
518 }
519 }
520 putname (p);
521 return ret;
522 }
523 case 3: /* I_POP */
524 if (sock->modcount <= 0) return -EINVAL;
525 sock->modcount--;
526 return 0;
527 case 4: /* I_LOOK */
528 {
529 const char *p;
530 if (sock->modcount <= 0) return -EINVAL;
531 p = module_table[(unsigned)sock->module[sock->modcount]].name;
532 if (copy_to_user (A(arg), p, strlen(p)))
533 return -EFAULT;
534 return 0;
535 }
536 case 5: /* I_FLUSH */
537 return 0;
538 case 8: /* I_STR */
539 if (copy_from_user(&si, A(arg), sizeof(struct strioctl)))
540 return -EFAULT;
541 /* We ignore what module is actually at the top of stack. */
542 switch ((si.cmd >> 8) & 0xff) {
543 case 'I':
544 return solaris_sockmod(fd, si.cmd, si.data);
545 case 'T':
546 return solaris_timod(fd, si.cmd, si.data, si.len,
547 &((struct strioctl __user *)A(arg))->len);
548 default:
549 return solaris_ioctl(fd, si.cmd, si.data);
550 }
551 case 9: /* I_SETSIG */
552 return sys_ioctl(fd, FIOSETOWN, current->pid);
553 case 10: /* I_GETSIG */
554 old_fs = get_fs();
555 set_fs(KERNEL_DS);
556 sys_ioctl(fd, FIOGETOWN, (unsigned long)&ret);
557 set_fs(old_fs);
558 if (ret == current->pid) return 0x3ff;
559 else return -EINVAL;
560 case 11: /* I_FIND */
561 {
562 int i;
563 p = getname (A(arg));
564 if (IS_ERR (p))
565 return PTR_ERR(p);
566 ret = 0;
567 for (i = 0; i < sock->modcount; i++) {
568 unsigned m = sock->module[i];
569 if (strcmp(module_table[m].name, p) == 0) {
570 ret = 1;
571 break;
572 }
573 }
574 putname (p);
575 return ret;
576 }
577 case 19: /* I_SWROPT */
578 case 32: /* I_SETCLTIME */
579 return 0; /* Lie */
580 }
581 return -ENOSYS;
582}
583
584static inline int solaris_s(unsigned int fd, unsigned int cmd, u32 arg)
585{
586 switch (cmd & 0xff) {
587 case 0: /* SIOCSHIWAT */
588 case 2: /* SIOCSLOWAT */
589 return 0; /* We don't support them */
590 case 1: /* SIOCGHIWAT */
591 case 3: /* SIOCGLOWAT */
592 if (put_user (0, (u32 __user *)A(arg)))
593 return -EFAULT;
594 return 0; /* Lie */
595 case 7: /* SIOCATMARK */
596 return sys_ioctl(fd, SIOCATMARK, arg);
597 case 8: /* SIOCSPGRP */
598 return sys_ioctl(fd, SIOCSPGRP, arg);
599 case 9: /* SIOCGPGRP */
600 return sys_ioctl(fd, SIOCGPGRP, arg);
601 }
602 return -ENOSYS;
603}
604
605static inline int solaris_r(unsigned int fd, unsigned int cmd, u32 arg)
606{
607 switch (cmd & 0xff) {
608 case 10: /* SIOCADDRT */
609 return compat_sys_ioctl(fd, SIOCADDRT, arg);
610 case 11: /* SIOCDELRT */
611 return compat_sys_ioctl(fd, SIOCDELRT, arg);
612 }
613 return -ENOSYS;
614}
615
616static inline int solaris_i(unsigned int fd, unsigned int cmd, u32 arg)
617{
618 switch (cmd & 0xff) {
619 case 12: /* SIOCSIFADDR */
620 return compat_sys_ioctl(fd, SIOCSIFADDR, arg);
621 case 13: /* SIOCGIFADDR */
622 return compat_sys_ioctl(fd, SIOCGIFADDR, arg);
623 case 14: /* SIOCSIFDSTADDR */
624 return compat_sys_ioctl(fd, SIOCSIFDSTADDR, arg);
625 case 15: /* SIOCGIFDSTADDR */
626 return compat_sys_ioctl(fd, SIOCGIFDSTADDR, arg);
627 case 16: /* SIOCSIFFLAGS */
628 return compat_sys_ioctl(fd, SIOCSIFFLAGS, arg);
629 case 17: /* SIOCGIFFLAGS */
630 return compat_sys_ioctl(fd, SIOCGIFFLAGS, arg);
631 case 18: /* SIOCSIFMEM */
632 return compat_sys_ioctl(fd, SIOCSIFMEM, arg);
633 case 19: /* SIOCGIFMEM */
634 return compat_sys_ioctl(fd, SIOCGIFMEM, arg);
635 case 20: /* SIOCGIFCONF */
636 return compat_sys_ioctl(fd, SIOCGIFCONF, arg);
637 case 21: /* SIOCSIFMTU */
638 return compat_sys_ioctl(fd, SIOCSIFMTU, arg);
639 case 22: /* SIOCGIFMTU */
640 return compat_sys_ioctl(fd, SIOCGIFMTU, arg);
641 case 23: /* SIOCGIFBRDADDR */
642 return compat_sys_ioctl(fd, SIOCGIFBRDADDR, arg);
643 case 24: /* SIOCSIFBRDADDR */
644 return compat_sys_ioctl(fd, SIOCSIFBRDADDR, arg);
645 case 25: /* SIOCGIFNETMASK */
646 return compat_sys_ioctl(fd, SIOCGIFNETMASK, arg);
647 case 26: /* SIOCSIFNETMASK */
648 return compat_sys_ioctl(fd, SIOCSIFNETMASK, arg);
649 case 27: /* SIOCGIFMETRIC */
650 return compat_sys_ioctl(fd, SIOCGIFMETRIC, arg);
651 case 28: /* SIOCSIFMETRIC */
652 return compat_sys_ioctl(fd, SIOCSIFMETRIC, arg);
653 case 30: /* SIOCSARP */
654 return compat_sys_ioctl(fd, SIOCSARP, arg);
655 case 31: /* SIOCGARP */
656 return compat_sys_ioctl(fd, SIOCGARP, arg);
657 case 32: /* SIOCDARP */
658 return compat_sys_ioctl(fd, SIOCDARP, arg);
659 case 52: /* SIOCGETNAME */
660 case 53: /* SIOCGETPEER */
661 {
662 struct sockaddr uaddr;
663 int uaddr_len = sizeof(struct sockaddr), ret;
664 long args[3];
665 mm_segment_t old_fs = get_fs();
666 int (*sys_socketcall)(int, unsigned long *) =
667 (int (*)(int, unsigned long *))SYS(socketcall);
668
669 args[0] = fd; args[1] = (long)&uaddr; args[2] = (long)&uaddr_len;
670 set_fs(KERNEL_DS);
671 ret = sys_socketcall(((cmd & 0xff) == 52) ? SYS_GETSOCKNAME : SYS_GETPEERNAME,
672 args);
673 set_fs(old_fs);
674 if (ret >= 0) {
675 if (copy_to_user(A(arg), &uaddr, uaddr_len))
676 return -EFAULT;
677 }
678 return ret;
679 }
680#if 0
681 case 86: /* SIOCSOCKSYS */
682 return socksys_syscall(fd, arg);
683#endif
684 case 87: /* SIOCGIFNUM */
685 {
686 struct net_device *d;
687 int i = 0;
688
689 read_lock_bh(&dev_base_lock);
690 for_each_netdev(&init_net, d)
691 i++;
692 read_unlock_bh(&dev_base_lock);
693
694 if (put_user (i, (int __user *)A(arg)))
695 return -EFAULT;
696 return 0;
697 }
698 }
699 return -ENOSYS;
700}
701
702static int solaris_m(unsigned int fd, unsigned int cmd, u32 arg)
703{
704 int ret;
705
706 switch (cmd & 0xff) {
707 case 1: /* MTIOCTOP */
708 ret = sys_ioctl(fd, MTIOCTOP, (unsigned long)&arg);
709 break;
710 case 2: /* MTIOCGET */
711 ret = sys_ioctl(fd, MTIOCGET, (unsigned long)&arg);
712 break;
713 case 3: /* MTIOCGETDRIVETYPE */
714 case 4: /* MTIOCPERSISTENT */
715 case 5: /* MTIOCPERSISTENTSTATUS */
716 case 6: /* MTIOCLRERR */
717 case 7: /* MTIOCGUARANTEEDORDER */
718 case 8: /* MTIOCRESERVE */
719 case 9: /* MTIOCRELEASE */
720 case 10: /* MTIOCFORCERESERVE */
721 case 13: /* MTIOCSTATE */
722 case 14: /* MTIOCREADIGNOREILI */
723 case 15: /* MTIOCREADIGNOREEOFS */
724 case 16: /* MTIOCSHORTFMK */
725 default:
726 ret = -ENOSYS; /* linux doesn't support these */
727 break;
728 };
729
730 return ret;
731}
732
733static int solaris_O(unsigned int fd, unsigned int cmd, u32 arg)
734{
735 int ret = -EINVAL;
736
737 switch (cmd & 0xff) {
738 case 1: /* OPROMGETOPT */
739 ret = sys_ioctl(fd, OPROMGETOPT, arg);
740 break;
741 case 2: /* OPROMSETOPT */
742 ret = sys_ioctl(fd, OPROMSETOPT, arg);
743 break;
744 case 3: /* OPROMNXTOPT */
745 ret = sys_ioctl(fd, OPROMNXTOPT, arg);
746 break;
747 case 4: /* OPROMSETOPT2 */
748 ret = sys_ioctl(fd, OPROMSETOPT2, arg);
749 break;
750 case 5: /* OPROMNEXT */
751 ret = sys_ioctl(fd, OPROMNEXT, arg);
752 break;
753 case 6: /* OPROMCHILD */
754 ret = sys_ioctl(fd, OPROMCHILD, arg);
755 break;
756 case 7: /* OPROMGETPROP */
757 ret = sys_ioctl(fd, OPROMGETPROP, arg);
758 break;
759 case 8: /* OPROMNXTPROP */
760 ret = sys_ioctl(fd, OPROMNXTPROP, arg);
761 break;
762 case 9: /* OPROMU2P */
763 ret = sys_ioctl(fd, OPROMU2P, arg);
764 break;
765 case 10: /* OPROMGETCONS */
766 ret = sys_ioctl(fd, OPROMGETCONS, arg);
767 break;
768 case 11: /* OPROMGETFBNAME */
769 ret = sys_ioctl(fd, OPROMGETFBNAME, arg);
770 break;
771 case 12: /* OPROMGETBOOTARGS */
772 ret = sys_ioctl(fd, OPROMGETBOOTARGS, arg);
773 break;
774 case 13: /* OPROMGETVERSION */
775 case 14: /* OPROMPATH2DRV */
776 case 15: /* OPROMDEV2PROMNAME */
777 case 16: /* OPROMPROM2DEVNAME */
778 case 17: /* OPROMGETPROPLEN */
779 default:
780 ret = -EINVAL;
781 break;
782 };
783 return ret;
784}
785
786/* }}} */
787
788asmlinkage int solaris_ioctl(unsigned int fd, unsigned int cmd, u32 arg)
789{
790 struct file *filp;
791 int error = -EBADF;
792
793 filp = fget(fd);
794 if (!filp)
795 goto out;
796
797 lock_kernel();
798 error = -EFAULT;
799 switch ((cmd >> 8) & 0xff) {
800 case 'S': error = solaris_S(filp, fd, cmd, arg); break;
801 case 'T': error = solaris_T(fd, cmd, arg); break;
802 case 'i': error = solaris_i(fd, cmd, arg); break;
803 case 'r': error = solaris_r(fd, cmd, arg); break;
804 case 's': error = solaris_s(fd, cmd, arg); break;
805 case 't': error = solaris_t(fd, cmd, arg); break;
806 case 'f': error = sys_ioctl(fd, cmd, arg); break;
807 case 'm': error = solaris_m(fd, cmd, arg); break;
808 case 'O': error = solaris_O(fd, cmd, arg); break;
809 default:
810 error = -ENOSYS;
811 break;
812 }
813 unlock_kernel();
814 fput(filp);
815out:
816 if (error == -ENOSYS) {
817 unsigned char c = cmd>>8;
818
819 if (c < ' ' || c > 126) c = '.';
820 printk("solaris_ioctl: Unknown cmd fd(%d) cmd(%08x '%c') arg(%08x)\n",
821 (int)fd, (unsigned int)cmd, c, (unsigned int)arg);
822 error = -EINVAL;
823 }
824 return error;
825}
diff --git a/arch/sparc64/solaris/ipc.c b/arch/sparc64/solaris/ipc.c
deleted file mode 100644
index 499135fa7060..000000000000
--- a/arch/sparc64/solaris/ipc.c
+++ /dev/null
@@ -1,126 +0,0 @@
1/* $Id: ipc.c,v 1.5 1999/12/09 00:41:00 davem Exp $
2 * ipc.c: Solaris IPC emulation
3 *
4 * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5 */
6
7#include <linux/kernel.h>
8#include <linux/types.h>
9#include <linux/wait.h>
10#include <linux/mm.h>
11#include <linux/shm.h>
12#include <linux/sem.h>
13#include <linux/msg.h>
14#include <linux/ipc.h>
15
16#include <asm/uaccess.h>
17#include <asm/string.h>
18
19#include "conv.h"
20
21struct solaris_ipc_perm {
22 s32 uid;
23 s32 gid;
24 s32 cuid;
25 s32 cgid;
26 u32 mode;
27 u32 seq;
28 int key;
29 s32 pad[4];
30};
31
32struct solaris_shmid_ds {
33 struct solaris_ipc_perm shm_perm;
34 int shm_segsz;
35 u32 shm_amp;
36 unsigned short shm_lkcnt;
37 char __padxx[2];
38 s32 shm_lpid;
39 s32 shm_cpid;
40 u32 shm_nattch;
41 u32 shm_cnattch;
42 s32 shm_atime;
43 s32 shm_pad1;
44 s32 shm_dtime;
45 s32 shm_pad2;
46 s32 shm_ctime;
47 s32 shm_pad3;
48 unsigned short shm_cv;
49 char shm_pad4[2];
50 u32 shm_sptas;
51 s32 shm_pad5[2];
52};
53
54asmlinkage long solaris_shmsys(int cmd, u32 arg1, u32 arg2, u32 arg3)
55{
56 int (*sys_ipc)(unsigned,int,int,unsigned long,void __user *,long) =
57 (int (*)(unsigned,int,int,unsigned long,void __user *,long))SYS(ipc);
58 mm_segment_t old_fs;
59 unsigned long raddr;
60 int ret;
61
62 switch (cmd) {
63 case 0: /* shmat */
64 old_fs = get_fs();
65 set_fs(KERNEL_DS);
66 ret = sys_ipc(SHMAT, arg1, arg3 & ~0x4000, (unsigned long)&raddr, A(arg2), 0);
67 set_fs(old_fs);
68 if (ret >= 0) return (u32)raddr;
69 else return ret;
70 case 1: /* shmctl */
71 switch (arg2) {
72 case 3: /* SHM_LOCK */
73 case 4: /* SHM_UNLOCK */
74 return sys_ipc(SHMCTL, arg1, (arg2 == 3) ? SHM_LOCK : SHM_UNLOCK, 0, NULL, 0);
75 case 10: /* IPC_RMID */
76 return sys_ipc(SHMCTL, arg1, IPC_RMID, 0, NULL, 0);
77 case 11: /* IPC_SET */
78 {
79 struct shmid_ds s;
80 struct solaris_shmid_ds __user *p = A(arg3);
81
82 if (get_user (s.shm_perm.uid, &p->shm_perm.uid) ||
83 __get_user (s.shm_perm.gid, &p->shm_perm.gid) ||
84 __get_user (s.shm_perm.mode, &p->shm_perm.mode))
85 return -EFAULT;
86 old_fs = get_fs();
87 set_fs(KERNEL_DS);
88 ret = sys_ipc(SHMCTL, arg1, IPC_SET, 0, &s, 0);
89 set_fs(old_fs);
90 return ret;
91 }
92 case 12: /* IPC_STAT */
93 {
94 struct shmid_ds s;
95 struct solaris_shmid_ds __user *p = A(arg3);
96
97 old_fs = get_fs();
98 set_fs(KERNEL_DS);
99 ret = sys_ipc(SHMCTL, arg1, IPC_SET, 0, &s, 0);
100 set_fs(old_fs);
101 if (put_user (s.shm_perm.uid, &(p->shm_perm.uid)) ||
102 __put_user (s.shm_perm.gid, &(p->shm_perm.gid)) ||
103 __put_user (s.shm_perm.cuid, &(p->shm_perm.cuid)) ||
104 __put_user (s.shm_perm.cgid, &(p->shm_perm.cgid)) ||
105 __put_user (s.shm_perm.mode, &(p->shm_perm.mode)) ||
106 __put_user (s.shm_perm.seq, &(p->shm_perm.seq)) ||
107 __put_user (s.shm_perm.key, &(p->shm_perm.key)) ||
108 __put_user (s.shm_segsz, &(p->shm_segsz)) ||
109 __put_user (s.shm_lpid, &(p->shm_lpid)) ||
110 __put_user (s.shm_cpid, &(p->shm_cpid)) ||
111 __put_user (s.shm_nattch, &(p->shm_nattch)) ||
112 __put_user (s.shm_atime, &(p->shm_atime)) ||
113 __put_user (s.shm_dtime, &(p->shm_dtime)) ||
114 __put_user (s.shm_ctime, &(p->shm_ctime)))
115 return -EFAULT;
116 return ret;
117 }
118 default: return -EINVAL;
119 }
120 case 2: /* shmdt */
121 return sys_ipc(SHMDT, 0, 0, 0, A(arg1), 0);
122 case 3: /* shmget */
123 return sys_ipc(SHMGET, arg1, arg2, arg3, NULL, 0);
124 }
125 return -EINVAL;
126}
diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c
deleted file mode 100644
index d3e48e9701bf..000000000000
--- a/arch/sparc64/solaris/misc.c
+++ /dev/null
@@ -1,786 +0,0 @@
1/* $Id: misc.c,v 1.36 2002/02/09 19:49:31 davem Exp $
2 * misc.c: Miscellaneous syscall emulation for Solaris
3 *
4 * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5 */
6
7#include <linux/module.h>
8#include <linux/types.h>
9#include <linux/utsname.h>
10#include <linux/limits.h>
11#include <linux/mm.h>
12#include <linux/smp.h>
13#include <linux/tty.h>
14#include <linux/mman.h>
15#include <linux/file.h>
16#include <linux/timex.h>
17#include <linux/major.h>
18#include <linux/compat.h>
19
20#include <asm/uaccess.h>
21#include <asm/string.h>
22#include <asm/oplib.h>
23#include <asm/idprom.h>
24#include <asm/smp.h>
25#include <asm/prom.h>
26
27#include "conv.h"
28
29/* Conversion from Linux to Solaris errnos. 0-34 are identity mapped.
30 Some Linux errnos (EPROCLIM, EDOTDOT, ERREMOTE, EUCLEAN, ENOTNAM,
31 ENAVAIL, EISNAM, EREMOTEIO, ENOMEDIUM, EMEDIUMTYPE) have no Solaris
32 equivalents. I return EINVAL in that case, which is very wrong. If
33 someone suggest a better value for them, you're welcomed.
34 On the other side, Solaris ECANCELED and ENOTSUP have no Linux equivalents,
35 but that doesn't matter here. --jj */
36int solaris_err_table[] = {
37/* 0 */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
38/* 10 */ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
39/* 20 */ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
40/* 30 */ 30, 31, 32, 33, 34, 22, 150, 149, 95, 96,
41/* 40 */ 97, 98, 99, 120, 121, 122, 123, 124, 125, 126,
42/* 50 */ 127, 128, 129, 130, 131, 132, 133, 134, 143, 144,
43/* 60 */ 145, 146, 90, 78, 147, 148, 93, 22, 94, 49,
44/* 70 */ 151, 66, 60, 62, 63, 35, 77, 36, 45, 46,
45/* 80 */ 64, 22, 67, 68, 69, 70, 71, 74, 22, 82,
46/* 90 */ 89, 92, 79, 81, 37, 38, 39, 40, 41, 42,
47/* 100 */ 43, 44, 50, 51, 52, 53, 54, 55, 56, 57,
48/* 110 */ 87, 61, 84, 65, 83, 80, 91, 22, 22, 22,
49/* 120 */ 22, 22, 88, 86, 85, 22, 22,
50};
51
52#define SOLARIS_NR_OPEN 256
53
54static u32 do_solaris_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u64 off)
55{
56 struct file *file = NULL;
57 unsigned long retval, ret_type;
58
59 /* Do we need it here? */
60 set_personality(PER_SVR4);
61 if (flags & MAP_NORESERVE) {
62 static int cnt;
63
64 if (cnt < 5) {
65 printk("%s: unimplemented Solaris MAP_NORESERVE mmap() flag\n",
66 current->comm);
67 cnt++;
68 }
69 flags &= ~MAP_NORESERVE;
70 }
71 retval = -EBADF;
72 if(!(flags & MAP_ANONYMOUS)) {
73 if(fd >= SOLARIS_NR_OPEN)
74 goto out;
75 file = fget(fd);
76 if (!file)
77 goto out;
78 else {
79 struct inode * inode = file->f_path.dentry->d_inode;
80 if(imajor(inode) == MEM_MAJOR &&
81 iminor(inode) == 5) {
82 flags |= MAP_ANONYMOUS;
83 fput(file);
84 file = NULL;
85 }
86 }
87 }
88
89 retval = -EINVAL;
90 len = PAGE_ALIGN(len);
91 if(!(flags & MAP_FIXED))
92 addr = 0;
93 else if (len > STACK_TOP32 || addr > STACK_TOP32 - len)
94 goto out_putf;
95 ret_type = flags & _MAP_NEW;
96 flags &= ~_MAP_NEW;
97
98 down_write(&current->mm->mmap_sem);
99 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
100 retval = do_mmap(file,
101 (unsigned long) addr, (unsigned long) len,
102 (unsigned long) prot, (unsigned long) flags, off);
103 up_write(&current->mm->mmap_sem);
104 if(!ret_type)
105 retval = ((retval < STACK_TOP32) ? 0 : retval);
106
107out_putf:
108 if (file)
109 fput(file);
110out:
111 return (u32) retval;
112}
113
114asmlinkage u32 solaris_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u32 off)
115{
116 return do_solaris_mmap(addr, len, prot, flags, fd, (u64) off);
117}
118
119asmlinkage u32 solaris_mmap64(struct pt_regs *regs, u32 len, u32 prot, u32 flags, u32 fd, u32 offhi)
120{
121 u32 offlo;
122
123 if (regs->u_regs[UREG_G1]) {
124 if (get_user (offlo, (u32 __user *)(long)((u32)regs->u_regs[UREG_I6] + 0x5c)))
125 return -EFAULT;
126 } else {
127 if (get_user (offlo, (u32 __user *)(long)((u32)regs->u_regs[UREG_I6] + 0x60)))
128 return -EFAULT;
129 }
130 return do_solaris_mmap((u32)regs->u_regs[UREG_I0], len, prot, flags, fd, (((u64)offhi)<<32)|offlo);
131}
132
133asmlinkage int solaris_brk(u32 brk)
134{
135 int (*sunos_brk)(u32) = (int (*)(u32))SUNOS(17);
136
137 return sunos_brk(brk);
138}
139
140static int __set_utsfield(char __user *to, int to_size,
141 const char *from, int from_size,
142 int dotchop, int countfrom)
143{
144 int len = countfrom ? (to_size > from_size ?
145 from_size : to_size) : to_size;
146 int off;
147
148 if (copy_to_user(to, from, len))
149 return -EFAULT;
150
151 off = len < to_size? len: len - 1;
152 if (dotchop) {
153 const char *p = strnchr(from, len, '.');
154 if (p) off = p - from;
155 }
156
157 if (__put_user('\0', to + off))
158 return -EFAULT;
159
160 return 0;
161}
162
163#define set_utsfield(to, from, dotchop, countfrom) \
164 __set_utsfield((to), sizeof(to), \
165 (from), sizeof(from), \
166 (dotchop), (countfrom))
167
168struct sol_uname {
169 char sysname[9];
170 char nodename[9];
171 char release[9];
172 char version[9];
173 char machine[9];
174};
175
176struct sol_utsname {
177 char sysname[257];
178 char nodename[257];
179 char release[257];
180 char version[257];
181 char machine[257];
182};
183
184static char *machine(void)
185{
186 switch (sparc_cpu_model) {
187 case sun4: return "sun4";
188 case sun4c: return "sun4c";
189 case sun4e: return "sun4e";
190 case sun4m: return "sun4m";
191 case sun4d: return "sun4d";
192 case sun4u: return "sun4u";
193 default: return "sparc";
194 }
195}
196
197static char *platform(char *buffer, int sz)
198{
199 struct device_node *dp = of_find_node_by_path("/");
200 int len;
201
202 *buffer = 0;
203 len = strlen(dp->name);
204 if (len > sz)
205 len = sz;
206 memcpy(buffer, dp->name, len);
207 buffer[len] = 0;
208 if (*buffer) {
209 char *p;
210
211 for (p = buffer; *p; p++)
212 if (*p == '/' || *p == ' ') *p = '_';
213 return buffer;
214 }
215
216 return "sun4u";
217}
218
219static char *serial(char *buffer, int sz)
220{
221 struct device_node *dp = of_find_node_by_path("/options");
222 int len;
223
224 *buffer = 0;
225 if (dp) {
226 const char *val =
227 of_get_property(dp, "system-board-serial#", &len);
228
229 if (val && len > 0) {
230 if (len > sz)
231 len = sz;
232 memcpy(buffer, val, len);
233 buffer[len] = 0;
234 }
235 }
236 if (!*buffer)
237 return "4512348717234";
238 else
239 return buffer;
240}
241
242asmlinkage int solaris_utssys(u32 buf, u32 flags, int which, u32 buf2)
243{
244 struct sol_uname __user *v = A(buf);
245 int err;
246
247 switch (which) {
248 case 0: /* old uname */
249 /* Let's cheat */
250 err = set_utsfield(v->sysname, "SunOS", 1, 0);
251 down_read(&uts_sem);
252 err |= set_utsfield(v->nodename, utsname()->nodename,
253 1, 1);
254 up_read(&uts_sem);
255 err |= set_utsfield(v->release, "2.6", 0, 0);
256 err |= set_utsfield(v->version, "Generic", 0, 0);
257 err |= set_utsfield(v->machine, machine(), 0, 0);
258 return (err ? -EFAULT : 0);
259 case 2: /* ustat */
260 return -ENOSYS;
261 case 3: /* fusers */
262 return -ENOSYS;
263 default:
264 return -ENOSYS;
265 }
266}
267
268asmlinkage int solaris_utsname(u32 buf)
269{
270 struct sol_utsname __user *v = A(buf);
271 int err;
272
273 /* Why should we not lie a bit? */
274 down_read(&uts_sem);
275 err = set_utsfield(v->sysname, "SunOS", 0, 0);
276 err |= set_utsfield(v->nodename, utsname()->nodename, 1, 1);
277 err |= set_utsfield(v->release, "5.6", 0, 0);
278 err |= set_utsfield(v->version, "Generic", 0, 0);
279 err |= set_utsfield(v->machine, machine(), 0, 0);
280 up_read(&uts_sem);
281
282 return (err ? -EFAULT : 0);
283}
284
285#define SI_SYSNAME 1 /* return name of operating system */
286#define SI_HOSTNAME 2 /* return name of node */
287#define SI_RELEASE 3 /* return release of operating system */
288#define SI_VERSION 4 /* return version field of utsname */
289#define SI_MACHINE 5 /* return kind of machine */
290#define SI_ARCHITECTURE 6 /* return instruction set arch */
291#define SI_HW_SERIAL 7 /* return hardware serial number */
292#define SI_HW_PROVIDER 8 /* return hardware manufacturer */
293#define SI_SRPC_DOMAIN 9 /* return secure RPC domain */
294#define SI_PLATFORM 513 /* return platform identifier */
295
296asmlinkage int solaris_sysinfo(int cmd, u32 buf, s32 count)
297{
298 char *p, *q, *r;
299 char buffer[256];
300 int len;
301
302 /* Again, we cheat :)) */
303 switch (cmd) {
304 case SI_SYSNAME: r = "SunOS"; break;
305 case SI_HOSTNAME:
306 r = buffer + 256;
307 down_read(&uts_sem);
308 for (p = utsname()->nodename, q = buffer;
309 q < r && *p && *p != '.'; *q++ = *p++);
310 up_read(&uts_sem);
311 *q = 0;
312 r = buffer;
313 break;
314 case SI_RELEASE: r = "5.6"; break;
315 case SI_MACHINE: r = machine(); break;
316 case SI_ARCHITECTURE: r = "sparc"; break;
317 case SI_HW_PROVIDER: r = "Sun_Microsystems"; break;
318 case SI_HW_SERIAL: r = serial(buffer, sizeof(buffer)); break;
319 case SI_PLATFORM: r = platform(buffer, sizeof(buffer)); break;
320 case SI_SRPC_DOMAIN: r = ""; break;
321 case SI_VERSION: r = "Generic"; break;
322 default: return -EINVAL;
323 }
324 len = strlen(r) + 1;
325 if (count < len) {
326 if (copy_to_user(A(buf), r, count - 1) ||
327 __put_user(0, (char __user *)A(buf) + count - 1))
328 return -EFAULT;
329 } else {
330 if (copy_to_user(A(buf), r, len))
331 return -EFAULT;
332 }
333 return len;
334}
335
336#define SOLARIS_CONFIG_NGROUPS 2
337#define SOLARIS_CONFIG_CHILD_MAX 3
338#define SOLARIS_CONFIG_OPEN_FILES 4
339#define SOLARIS_CONFIG_POSIX_VER 5
340#define SOLARIS_CONFIG_PAGESIZE 6
341#define SOLARIS_CONFIG_CLK_TCK 7
342#define SOLARIS_CONFIG_XOPEN_VER 8
343#define SOLARIS_CONFIG_PROF_TCK 10
344#define SOLARIS_CONFIG_NPROC_CONF 11
345#define SOLARIS_CONFIG_NPROC_ONLN 12
346#define SOLARIS_CONFIG_AIO_LISTIO_MAX 13
347#define SOLARIS_CONFIG_AIO_MAX 14
348#define SOLARIS_CONFIG_AIO_PRIO_DELTA_MAX 15
349#define SOLARIS_CONFIG_DELAYTIMER_MAX 16
350#define SOLARIS_CONFIG_MQ_OPEN_MAX 17
351#define SOLARIS_CONFIG_MQ_PRIO_MAX 18
352#define SOLARIS_CONFIG_RTSIG_MAX 19
353#define SOLARIS_CONFIG_SEM_NSEMS_MAX 20
354#define SOLARIS_CONFIG_SEM_VALUE_MAX 21
355#define SOLARIS_CONFIG_SIGQUEUE_MAX 22
356#define SOLARIS_CONFIG_SIGRT_MIN 23
357#define SOLARIS_CONFIG_SIGRT_MAX 24
358#define SOLARIS_CONFIG_TIMER_MAX 25
359#define SOLARIS_CONFIG_PHYS_PAGES 26
360#define SOLARIS_CONFIG_AVPHYS_PAGES 27
361
362asmlinkage int solaris_sysconf(int id)
363{
364 switch (id) {
365 case SOLARIS_CONFIG_NGROUPS: return NGROUPS_MAX;
366 case SOLARIS_CONFIG_CHILD_MAX:
367 return current->signal->rlim[RLIMIT_NPROC].rlim_cur;
368 case SOLARIS_CONFIG_OPEN_FILES:
369 return current->signal->rlim[RLIMIT_NOFILE].rlim_cur;
370 case SOLARIS_CONFIG_POSIX_VER: return 199309;
371 case SOLARIS_CONFIG_PAGESIZE: return PAGE_SIZE;
372 case SOLARIS_CONFIG_XOPEN_VER: return 3;
373 case SOLARIS_CONFIG_CLK_TCK:
374 case SOLARIS_CONFIG_PROF_TCK:
375 return sparc64_get_clock_tick(smp_processor_id());
376#ifdef CONFIG_SMP
377 case SOLARIS_CONFIG_NPROC_CONF: return NR_CPUS;
378 case SOLARIS_CONFIG_NPROC_ONLN: return num_online_cpus();
379#else
380 case SOLARIS_CONFIG_NPROC_CONF: return 1;
381 case SOLARIS_CONFIG_NPROC_ONLN: return 1;
382#endif
383 case SOLARIS_CONFIG_SIGRT_MIN: return 37;
384 case SOLARIS_CONFIG_SIGRT_MAX: return 44;
385 case SOLARIS_CONFIG_PHYS_PAGES:
386 case SOLARIS_CONFIG_AVPHYS_PAGES:
387 {
388 struct sysinfo s;
389
390 si_meminfo(&s);
391 if (id == SOLARIS_CONFIG_PHYS_PAGES)
392 return s.totalram >>= PAGE_SHIFT;
393 else
394 return s.freeram >>= PAGE_SHIFT;
395 }
396 /* XXX support these as well -jj */
397 case SOLARIS_CONFIG_AIO_LISTIO_MAX: return -EINVAL;
398 case SOLARIS_CONFIG_AIO_MAX: return -EINVAL;
399 case SOLARIS_CONFIG_AIO_PRIO_DELTA_MAX: return -EINVAL;
400 case SOLARIS_CONFIG_DELAYTIMER_MAX: return -EINVAL;
401 case SOLARIS_CONFIG_MQ_OPEN_MAX: return -EINVAL;
402 case SOLARIS_CONFIG_MQ_PRIO_MAX: return -EINVAL;
403 case SOLARIS_CONFIG_RTSIG_MAX: return -EINVAL;
404 case SOLARIS_CONFIG_SEM_NSEMS_MAX: return -EINVAL;
405 case SOLARIS_CONFIG_SEM_VALUE_MAX: return -EINVAL;
406 case SOLARIS_CONFIG_SIGQUEUE_MAX: return -EINVAL;
407 case SOLARIS_CONFIG_TIMER_MAX: return -EINVAL;
408 default: return -EINVAL;
409 }
410}
411
412asmlinkage int solaris_procids(int cmd, s32 pid, s32 pgid)
413{
414 int ret;
415
416 switch (cmd) {
417 case 0: /* getpgrp */
418 return task_pgrp_vnr(current);
419 case 1: /* setpgrp */
420 {
421 int (*sys_setpgid)(pid_t,pid_t) =
422 (int (*)(pid_t,pid_t))SYS(setpgid);
423
424 /* can anyone explain me the difference between
425 Solaris setpgrp and setsid? */
426 ret = sys_setpgid(0, 0);
427 if (ret) return ret;
428 proc_clear_tty(current);
429 return task_pgrp_vnr(current);
430 }
431 case 2: /* getsid */
432 {
433 int (*sys_getsid)(pid_t) = (int (*)(pid_t))SYS(getsid);
434 return sys_getsid(pid);
435 }
436 case 3: /* setsid */
437 {
438 int (*sys_setsid)(void) = (int (*)(void))SYS(setsid);
439 return sys_setsid();
440 }
441 case 4: /* getpgid */
442 {
443 int (*sys_getpgid)(pid_t) = (int (*)(pid_t))SYS(getpgid);
444 return sys_getpgid(pid);
445 }
446 case 5: /* setpgid */
447 {
448 int (*sys_setpgid)(pid_t,pid_t) =
449 (int (*)(pid_t,pid_t))SYS(setpgid);
450 return sys_setpgid(pid,pgid);
451 }
452 }
453 return -EINVAL;
454}
455
456asmlinkage int solaris_gettimeofday(u32 tim)
457{
458 int (*sys_gettimeofday)(struct timeval *, struct timezone *) =
459 (int (*)(struct timeval *, struct timezone *))SYS(gettimeofday);
460
461 return sys_gettimeofday((struct timeval *)(u64)tim, NULL);
462}
463
464#define RLIM_SOL_INFINITY32 0x7fffffff
465#define RLIM_SOL_SAVED_MAX32 0x7ffffffe
466#define RLIM_SOL_SAVED_CUR32 0x7ffffffd
467#define RLIM_SOL_INFINITY ((u64)-3)
468#define RLIM_SOL_SAVED_MAX ((u64)-2)
469#define RLIM_SOL_SAVED_CUR ((u64)-1)
470#define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
471#define RLIMIT_SOL_NOFILE 5
472#define RLIMIT_SOL_VMEM 6
473
474struct rlimit32 {
475 u32 rlim_cur;
476 u32 rlim_max;
477};
478
479asmlinkage int solaris_getrlimit(unsigned int resource, struct rlimit32 __user *rlim)
480{
481 struct rlimit r;
482 int ret;
483 mm_segment_t old_fs = get_fs ();
484 int (*sys_getrlimit)(unsigned int, struct rlimit *) =
485 (int (*)(unsigned int, struct rlimit *))SYS(getrlimit);
486
487 if (resource > RLIMIT_SOL_VMEM)
488 return -EINVAL;
489 switch (resource) {
490 case RLIMIT_SOL_NOFILE: resource = RLIMIT_NOFILE; break;
491 case RLIMIT_SOL_VMEM: resource = RLIMIT_AS; break;
492 default: break;
493 }
494 set_fs (KERNEL_DS);
495 ret = sys_getrlimit(resource, &r);
496 set_fs (old_fs);
497 if (!ret) {
498 if (r.rlim_cur == RLIM_INFINITY)
499 r.rlim_cur = RLIM_SOL_INFINITY32;
500 else if ((u64)r.rlim_cur > RLIM_SOL_INFINITY32)
501 r.rlim_cur = RLIM_SOL_SAVED_CUR32;
502 if (r.rlim_max == RLIM_INFINITY)
503 r.rlim_max = RLIM_SOL_INFINITY32;
504 else if ((u64)r.rlim_max > RLIM_SOL_INFINITY32)
505 r.rlim_max = RLIM_SOL_SAVED_MAX32;
506 ret = put_user (r.rlim_cur, &rlim->rlim_cur);
507 ret |= __put_user (r.rlim_max, &rlim->rlim_max);
508 }
509 return ret;
510}
511
512asmlinkage int solaris_setrlimit(unsigned int resource, struct rlimit32 __user *rlim)
513{
514 struct rlimit r, rold;
515 int ret;
516 mm_segment_t old_fs = get_fs ();
517 int (*sys_getrlimit)(unsigned int, struct rlimit __user *) =
518 (int (*)(unsigned int, struct rlimit __user *))SYS(getrlimit);
519 int (*sys_setrlimit)(unsigned int, struct rlimit __user *) =
520 (int (*)(unsigned int, struct rlimit __user *))SYS(setrlimit);
521
522 if (resource > RLIMIT_SOL_VMEM)
523 return -EINVAL;
524 switch (resource) {
525 case RLIMIT_SOL_NOFILE: resource = RLIMIT_NOFILE; break;
526 case RLIMIT_SOL_VMEM: resource = RLIMIT_AS; break;
527 default: break;
528 }
529 if (get_user (r.rlim_cur, &rlim->rlim_cur) ||
530 __get_user (r.rlim_max, &rlim->rlim_max))
531 return -EFAULT;
532 set_fs (KERNEL_DS);
533 ret = sys_getrlimit(resource, &rold);
534 if (!ret) {
535 if (r.rlim_cur == RLIM_SOL_INFINITY32)
536 r.rlim_cur = RLIM_INFINITY;
537 else if (r.rlim_cur == RLIM_SOL_SAVED_CUR32)
538 r.rlim_cur = rold.rlim_cur;
539 else if (r.rlim_cur == RLIM_SOL_SAVED_MAX32)
540 r.rlim_cur = rold.rlim_max;
541 if (r.rlim_max == RLIM_SOL_INFINITY32)
542 r.rlim_max = RLIM_INFINITY;
543 else if (r.rlim_max == RLIM_SOL_SAVED_CUR32)
544 r.rlim_max = rold.rlim_cur;
545 else if (r.rlim_max == RLIM_SOL_SAVED_MAX32)
546 r.rlim_max = rold.rlim_max;
547 ret = sys_setrlimit(resource, &r);
548 }
549 set_fs (old_fs);
550 return ret;
551}
552
553asmlinkage int solaris_getrlimit64(unsigned int resource, struct rlimit __user *rlim)
554{
555 struct rlimit r;
556 int ret;
557 mm_segment_t old_fs = get_fs ();
558 int (*sys_getrlimit)(unsigned int, struct rlimit __user *) =
559 (int (*)(unsigned int, struct rlimit __user *))SYS(getrlimit);
560
561 if (resource > RLIMIT_SOL_VMEM)
562 return -EINVAL;
563 switch (resource) {
564 case RLIMIT_SOL_NOFILE: resource = RLIMIT_NOFILE; break;
565 case RLIMIT_SOL_VMEM: resource = RLIMIT_AS; break;
566 default: break;
567 }
568 set_fs (KERNEL_DS);
569 ret = sys_getrlimit(resource, &r);
570 set_fs (old_fs);
571 if (!ret) {
572 if (r.rlim_cur == RLIM_INFINITY)
573 r.rlim_cur = RLIM_SOL_INFINITY;
574 if (r.rlim_max == RLIM_INFINITY)
575 r.rlim_max = RLIM_SOL_INFINITY;
576 ret = put_user (r.rlim_cur, &rlim->rlim_cur);
577 ret |= __put_user (r.rlim_max, &rlim->rlim_max);
578 }
579 return ret;
580}
581
582asmlinkage int solaris_setrlimit64(unsigned int resource, struct rlimit __user *rlim)
583{
584 struct rlimit r, rold;
585 int ret;
586 mm_segment_t old_fs = get_fs ();
587 int (*sys_getrlimit)(unsigned int, struct rlimit __user *) =
588 (int (*)(unsigned int, struct rlimit __user *))SYS(getrlimit);
589 int (*sys_setrlimit)(unsigned int, struct rlimit __user *) =
590 (int (*)(unsigned int, struct rlimit __user *))SYS(setrlimit);
591
592 if (resource > RLIMIT_SOL_VMEM)
593 return -EINVAL;
594 switch (resource) {
595 case RLIMIT_SOL_NOFILE: resource = RLIMIT_NOFILE; break;
596 case RLIMIT_SOL_VMEM: resource = RLIMIT_AS; break;
597 default: break;
598 }
599 if (get_user (r.rlim_cur, &rlim->rlim_cur) ||
600 __get_user (r.rlim_max, &rlim->rlim_max))
601 return -EFAULT;
602 set_fs (KERNEL_DS);
603 ret = sys_getrlimit(resource, &rold);
604 if (!ret) {
605 if (r.rlim_cur == RLIM_SOL_INFINITY)
606 r.rlim_cur = RLIM_INFINITY;
607 else if (r.rlim_cur == RLIM_SOL_SAVED_CUR)
608 r.rlim_cur = rold.rlim_cur;
609 else if (r.rlim_cur == RLIM_SOL_SAVED_MAX)
610 r.rlim_cur = rold.rlim_max;
611 if (r.rlim_max == RLIM_SOL_INFINITY)
612 r.rlim_max = RLIM_INFINITY;
613 else if (r.rlim_max == RLIM_SOL_SAVED_CUR)
614 r.rlim_max = rold.rlim_cur;
615 else if (r.rlim_max == RLIM_SOL_SAVED_MAX)
616 r.rlim_max = rold.rlim_max;
617 ret = sys_setrlimit(resource, &r);
618 }
619 set_fs (old_fs);
620 return ret;
621}
622
623struct sol_ntptimeval {
624 struct compat_timeval time;
625 s32 maxerror;
626 s32 esterror;
627};
628
629struct sol_timex {
630 u32 modes;
631 s32 offset;
632 s32 freq;
633 s32 maxerror;
634 s32 esterror;
635 s32 status;
636 s32 constant;
637 s32 precision;
638 s32 tolerance;
639 s32 ppsfreq;
640 s32 jitter;
641 s32 shift;
642 s32 stabil;
643 s32 jitcnt;
644 s32 calcnt;
645 s32 errcnt;
646 s32 stbcnt;
647};
648
649asmlinkage int solaris_ntp_gettime(struct sol_ntptimeval __user *ntp)
650{
651 int (*sys_adjtimex)(struct timex __user *) =
652 (int (*)(struct timex __user *))SYS(adjtimex);
653 struct timex t;
654 int ret;
655 mm_segment_t old_fs = get_fs();
656
657 set_fs(KERNEL_DS);
658 t.modes = 0;
659 ret = sys_adjtimex(&t);
660 set_fs(old_fs);
661 if (ret < 0)
662 return ret;
663 ret = put_user (t.time.tv_sec, &ntp->time.tv_sec);
664 ret |= __put_user (t.time.tv_usec, &ntp->time.tv_usec);
665 ret |= __put_user (t.maxerror, &ntp->maxerror);
666 ret |= __put_user (t.esterror, &ntp->esterror);
667 return ret;
668}
669
670asmlinkage int solaris_ntp_adjtime(struct sol_timex __user *txp)
671{
672 int (*sys_adjtimex)(struct timex __user *) =
673 (int (*)(struct timex __user *))SYS(adjtimex);
674 struct timex t;
675 int ret, err;
676 mm_segment_t old_fs = get_fs();
677
678 ret = get_user (t.modes, &txp->modes);
679 ret |= __get_user (t.offset, &txp->offset);
680 ret |= __get_user (t.freq, &txp->freq);
681 ret |= __get_user (t.maxerror, &txp->maxerror);
682 ret |= __get_user (t.esterror, &txp->esterror);
683 ret |= __get_user (t.status, &txp->status);
684 ret |= __get_user (t.constant, &txp->constant);
685 set_fs(KERNEL_DS);
686 ret = sys_adjtimex(&t);
687 set_fs(old_fs);
688 if (ret < 0)
689 return ret;
690 err = put_user (t.offset, &txp->offset);
691 err |= __put_user (t.freq, &txp->freq);
692 err |= __put_user (t.maxerror, &txp->maxerror);
693 err |= __put_user (t.esterror, &txp->esterror);
694 err |= __put_user (t.status, &txp->status);
695 err |= __put_user (t.constant, &txp->constant);
696 err |= __put_user (t.precision, &txp->precision);
697 err |= __put_user (t.tolerance, &txp->tolerance);
698 err |= __put_user (t.ppsfreq, &txp->ppsfreq);
699 err |= __put_user (t.jitter, &txp->jitter);
700 err |= __put_user (t.shift, &txp->shift);
701 err |= __put_user (t.stabil, &txp->stabil);
702 err |= __put_user (t.jitcnt, &txp->jitcnt);
703 err |= __put_user (t.calcnt, &txp->calcnt);
704 err |= __put_user (t.errcnt, &txp->errcnt);
705 err |= __put_user (t.stbcnt, &txp->stbcnt);
706 if (err)
707 return -EFAULT;
708 return ret;
709}
710
711asmlinkage int do_sol_unimplemented(struct pt_regs *regs)
712{
713 printk ("Unimplemented Solaris syscall %d %08x %08x %08x %08x\n",
714 (int)regs->u_regs[UREG_G1],
715 (int)regs->u_regs[UREG_I0],
716 (int)regs->u_regs[UREG_I1],
717 (int)regs->u_regs[UREG_I2],
718 (int)regs->u_regs[UREG_I3]);
719 return -ENOSYS;
720}
721
722asmlinkage void solaris_register(void)
723{
724 set_personality(PER_SVR4);
725}
726
727extern long solaris_to_linux_signals[], linux_to_solaris_signals[];
728
729struct exec_domain solaris_exec_domain = {
730 .name = "Solaris",
731 .handler = NULL,
732 .pers_low = 1, /* PER_SVR4 personality */
733 .pers_high = 1,
734 .signal_map = solaris_to_linux_signals,
735 .signal_invmap =linux_to_solaris_signals,
736 .module = THIS_MODULE,
737 .next = NULL
738};
739
740extern int init_socksys(void);
741
742MODULE_AUTHOR("Jakub Jelinek (jj@ultra.linux.cz), Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)");
743MODULE_DESCRIPTION("Solaris binary emulation module");
744MODULE_LICENSE("GPL");
745
746extern u32 tl0_solaris[8];
747#define update_ttable(x) \
748 tl0_solaris[3] = (((long)(x) - (long)tl0_solaris - 3) >> 2) | 0x40000000; \
749 wmb(); \
750 __asm__ __volatile__ ("flush %0" : : "r" (&tl0_solaris[3]))
751
752extern u32 solaris_sparc_syscall[];
753extern u32 solaris_syscall[];
754extern void cleanup_socksys(void);
755
756extern u32 entry64_personality_patch;
757
758static int __init solaris_init(void)
759{
760 int ret;
761
762 SOLDD(("Solaris module at %p\n", solaris_sparc_syscall));
763 register_exec_domain(&solaris_exec_domain);
764 if ((ret = init_socksys())) {
765 unregister_exec_domain(&solaris_exec_domain);
766 return ret;
767 }
768 update_ttable(solaris_sparc_syscall);
769 entry64_personality_patch |=
770 (offsetof(struct task_struct, personality) +
771 (sizeof(unsigned long) - 1));
772 wmb();
773 __asm__ __volatile__("flush %0"
774 : : "r" (&entry64_personality_patch));
775 return 0;
776}
777
778static void __exit solaris_exit(void)
779{
780 update_ttable(solaris_syscall);
781 cleanup_socksys();
782 unregister_exec_domain(&solaris_exec_domain);
783}
784
785module_init(solaris_init);
786module_exit(solaris_exit);
diff --git a/arch/sparc64/solaris/signal.c b/arch/sparc64/solaris/signal.c
deleted file mode 100644
index de10c9716cfb..000000000000
--- a/arch/sparc64/solaris/signal.c
+++ /dev/null
@@ -1,429 +0,0 @@
1/* $Id: signal.c,v 1.7 2000/09/05 21:44:54 davem Exp $
2 * signal.c: Signal emulation for Solaris
3 *
4 * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5 */
6
7#include <linux/types.h>
8#include <linux/errno.h>
9
10#include <asm/uaccess.h>
11#include <asm/svr4.h>
12#include <asm/string.h>
13
14#include "conv.h"
15#include "signal.h"
16
17#define _S(nr) (1L<<((nr)-1))
18
19#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
20
21long linux_to_solaris_signals[] = {
22 0,
23 SOLARIS_SIGHUP, SOLARIS_SIGINT,
24 SOLARIS_SIGQUIT, SOLARIS_SIGILL,
25 SOLARIS_SIGTRAP, SOLARIS_SIGIOT,
26 SOLARIS_SIGEMT, SOLARIS_SIGFPE,
27 SOLARIS_SIGKILL, SOLARIS_SIGBUS,
28 SOLARIS_SIGSEGV, SOLARIS_SIGSYS,
29 SOLARIS_SIGPIPE, SOLARIS_SIGALRM,
30 SOLARIS_SIGTERM, SOLARIS_SIGURG,
31 SOLARIS_SIGSTOP, SOLARIS_SIGTSTP,
32 SOLARIS_SIGCONT, SOLARIS_SIGCLD,
33 SOLARIS_SIGTTIN, SOLARIS_SIGTTOU,
34 SOLARIS_SIGPOLL, SOLARIS_SIGXCPU,
35 SOLARIS_SIGXFSZ, SOLARIS_SIGVTALRM,
36 SOLARIS_SIGPROF, SOLARIS_SIGWINCH,
37 SOLARIS_SIGUSR1, SOLARIS_SIGUSR1,
38 SOLARIS_SIGUSR2, -1,
39};
40
41long solaris_to_linux_signals[] = {
42 0,
43 SIGHUP, SIGINT, SIGQUIT, SIGILL,
44 SIGTRAP, SIGIOT, SIGEMT, SIGFPE,
45 SIGKILL, SIGBUS, SIGSEGV, SIGSYS,
46 SIGPIPE, SIGALRM, SIGTERM, SIGUSR1,
47 SIGUSR2, SIGCHLD, -1, SIGWINCH,
48 SIGURG, SIGPOLL, SIGSTOP, SIGTSTP,
49 SIGCONT, SIGTTIN, SIGTTOU, SIGVTALRM,
50 SIGPROF, SIGXCPU, SIGXFSZ, -1,
51 -1, -1, -1, -1,
52 -1, -1, -1, -1,
53 -1, -1, -1, -1,
54};
55
56static inline long mapsig(long sig)
57{
58 if ((unsigned long)sig > SOLARIS_NSIGNALS)
59 return -EINVAL;
60 return solaris_to_linux_signals[sig];
61}
62
63asmlinkage int solaris_kill(int pid, int sig)
64{
65 int (*sys_kill)(int,int) =
66 (int (*)(int,int))SYS(kill);
67 int s = mapsig(sig);
68
69 if (s < 0) return s;
70 return sys_kill(pid, s);
71}
72
73static long sig_handler(int sig, u32 arg, int one_shot)
74{
75 struct sigaction sa, old;
76 int ret;
77 mm_segment_t old_fs = get_fs();
78 int (*sys_sigaction)(int,struct sigaction __user *,struct sigaction __user *) =
79 (int (*)(int,struct sigaction __user *,struct sigaction __user *))SYS(sigaction);
80
81 sigemptyset(&sa.sa_mask);
82 sa.sa_restorer = NULL;
83 sa.sa_handler = (__sighandler_t)A(arg);
84 sa.sa_flags = 0;
85 if (one_shot) sa.sa_flags = SA_ONESHOT | SA_NOMASK;
86 set_fs (KERNEL_DS);
87 ret = sys_sigaction(sig, (void __user *)&sa, (void __user *)&old);
88 set_fs (old_fs);
89 if (ret < 0) return ret;
90 return (u32)(unsigned long)old.sa_handler;
91}
92
93static inline long solaris_signal(int sig, u32 arg)
94{
95 return sig_handler (sig, arg, 1);
96}
97
98static long solaris_sigset(int sig, u32 arg)
99{
100 if (arg != 2) /* HOLD */ {
101 spin_lock_irq(&current->sighand->siglock);
102 sigdelsetmask(&current->blocked, _S(sig));
103 recalc_sigpending();
104 spin_unlock_irq(&current->sighand->siglock);
105 return sig_handler (sig, arg, 0);
106 } else {
107 spin_lock_irq(&current->sighand->siglock);
108 sigaddsetmask(&current->blocked, (_S(sig) & ~_BLOCKABLE));
109 recalc_sigpending();
110 spin_unlock_irq(&current->sighand->siglock);
111 return 0;
112 }
113}
114
115static inline long solaris_sighold(int sig)
116{
117 return solaris_sigset(sig, 2);
118}
119
120static inline long solaris_sigrelse(int sig)
121{
122 spin_lock_irq(&current->sighand->siglock);
123 sigdelsetmask(&current->blocked, _S(sig));
124 recalc_sigpending();
125 spin_unlock_irq(&current->sighand->siglock);
126 return 0;
127}
128
129static inline long solaris_sigignore(int sig)
130{
131 return sig_handler(sig, (u32)(unsigned long)SIG_IGN, 0);
132}
133
134static inline long solaris_sigpause(int sig)
135{
136 printk ("Need to support solaris sigpause\n");
137 return -ENOSYS;
138}
139
140asmlinkage long solaris_sigfunc(int sig, u32 arg)
141{
142 int func = sig & ~0xff;
143
144 sig = mapsig(sig & 0xff);
145 if (sig < 0) return sig;
146 switch (func) {
147 case 0: return solaris_signal(sig, arg);
148 case 0x100: return solaris_sigset(sig, arg);
149 case 0x200: return solaris_sighold(sig);
150 case 0x400: return solaris_sigrelse(sig);
151 case 0x800: return solaris_sigignore(sig);
152 case 0x1000: return solaris_sigpause(sig);
153 }
154 return -EINVAL;
155}
156
157typedef struct {
158 u32 __sigbits[4];
159} sol_sigset_t;
160
161static inline int mapin(u32 *p, sigset_t *q)
162{
163 int i;
164 u32 x;
165 int sig;
166
167 sigemptyset(q);
168 x = p[0];
169 for (i = 1; i <= SOLARIS_NSIGNALS; i++) {
170 if (x & 1) {
171 sig = solaris_to_linux_signals[i];
172 if (sig == -1)
173 return -EINVAL;
174 sigaddsetmask(q, (1L << (sig - 1)));
175 }
176 x >>= 1;
177 if (i == 32)
178 x = p[1];
179 }
180 return 0;
181}
182
183static inline int mapout(sigset_t *q, u32 *p)
184{
185 int i;
186 int sig;
187
188 p[0] = 0;
189 p[1] = 0;
190 for (i = 1; i <= 32; i++) {
191 if (sigismember(q, sigmask(i))) {
192 sig = linux_to_solaris_signals[i];
193 if (sig == -1)
194 return -EINVAL;
195 if (sig > 32)
196 p[1] |= 1L << (sig - 33);
197 else
198 p[0] |= 1L << (sig - 1);
199 }
200 }
201 return 0;
202}
203
204asmlinkage int solaris_sigprocmask(int how, u32 in, u32 out)
205{
206 sigset_t in_s, *ins, out_s, *outs;
207 mm_segment_t old_fs = get_fs();
208 int ret;
209 int (*sys_sigprocmask)(int,sigset_t __user *,sigset_t __user *) =
210 (int (*)(int,sigset_t __user *,sigset_t __user *))SYS(sigprocmask);
211
212 ins = NULL; outs = NULL;
213 if (in) {
214 u32 tmp[2];
215
216 if (copy_from_user (tmp, (void __user *)A(in), 2*sizeof(u32)))
217 return -EFAULT;
218 ins = &in_s;
219 if (mapin (tmp, ins)) return -EINVAL;
220 }
221 if (out) outs = &out_s;
222 set_fs (KERNEL_DS);
223 ret = sys_sigprocmask((how == 3) ? SIG_SETMASK : how,
224 (void __user *)ins, (void __user *)outs);
225 set_fs (old_fs);
226 if (ret) return ret;
227 if (out) {
228 u32 tmp[4];
229
230 tmp[2] = 0; tmp[3] = 0;
231 if (mapout (outs, tmp)) return -EINVAL;
232 if (copy_to_user((void __user *)A(out), tmp, 4*sizeof(u32)))
233 return -EFAULT;
234 }
235 return 0;
236}
237
238asmlinkage long do_sol_sigsuspend(u32 mask)
239{
240 sigset_t s;
241 u32 tmp[2];
242
243 if (copy_from_user (tmp, (sol_sigset_t __user *)A(mask), 2*sizeof(u32)))
244 return -EFAULT;
245 if (mapin (tmp, &s)) return -EINVAL;
246 return (long)s.sig[0];
247}
248
249struct sol_sigaction {
250 int sa_flags;
251 u32 sa_handler;
252 u32 sa_mask[4];
253 int sa_resv[2];
254};
255
256asmlinkage int solaris_sigaction(int sig, u32 act, u32 old)
257{
258 u32 tmp, tmp2[4];
259 struct sigaction s, s2;
260 int ret;
261 mm_segment_t old_fs = get_fs();
262 struct sol_sigaction __user *p = (void __user *)A(old);
263 int (*sys_sigaction)(int,struct sigaction __user *,struct sigaction __user *) =
264 (int (*)(int,struct sigaction __user *,struct sigaction __user *))SYS(sigaction);
265
266 sig = mapsig(sig);
267 if (sig < 0) {
268 /* We cheat a little bit for Solaris only signals */
269 if (old && clear_user(p, sizeof(struct sol_sigaction)))
270 return -EFAULT;
271 return 0;
272 }
273 if (act) {
274 if (get_user (tmp, &p->sa_flags))
275 return -EFAULT;
276 s.sa_flags = 0;
277 if (tmp & SOLARIS_SA_ONSTACK) s.sa_flags |= SA_STACK;
278 if (tmp & SOLARIS_SA_RESTART) s.sa_flags |= SA_RESTART;
279 if (tmp & SOLARIS_SA_NODEFER) s.sa_flags |= SA_NOMASK;
280 if (tmp & SOLARIS_SA_RESETHAND) s.sa_flags |= SA_ONESHOT;
281 if (tmp & SOLARIS_SA_NOCLDSTOP) s.sa_flags |= SA_NOCLDSTOP;
282 if (get_user (tmp, &p->sa_handler) ||
283 copy_from_user (tmp2, &p->sa_mask, 2*sizeof(u32)))
284 return -EFAULT;
285 s.sa_handler = (__sighandler_t)A(tmp);
286 if (mapin (tmp2, &s.sa_mask)) return -EINVAL;
287 s.sa_restorer = NULL;
288 }
289 set_fs(KERNEL_DS);
290 ret = sys_sigaction(sig, act ? (void __user *)&s : NULL,
291 old ? (void __user *)&s2 : NULL);
292 set_fs(old_fs);
293 if (ret) return ret;
294 if (old) {
295 if (mapout (&s2.sa_mask, tmp2)) return -EINVAL;
296 tmp = 0; tmp2[2] = 0; tmp2[3] = 0;
297 if (s2.sa_flags & SA_STACK) tmp |= SOLARIS_SA_ONSTACK;
298 if (s2.sa_flags & SA_RESTART) tmp |= SOLARIS_SA_RESTART;
299 if (s2.sa_flags & SA_NOMASK) tmp |= SOLARIS_SA_NODEFER;
300 if (s2.sa_flags & SA_ONESHOT) tmp |= SOLARIS_SA_RESETHAND;
301 if (s2.sa_flags & SA_NOCLDSTOP) tmp |= SOLARIS_SA_NOCLDSTOP;
302 if (put_user (tmp, &p->sa_flags) ||
303 __put_user ((u32)(unsigned long)s2.sa_handler, &p->sa_handler) ||
304 copy_to_user (&p->sa_mask, tmp2, 4*sizeof(u32)))
305 return -EFAULT;
306 }
307 return 0;
308}
309
310asmlinkage int solaris_sigpending(int which, u32 set)
311{
312 sigset_t s;
313 u32 tmp[4];
314 switch (which) {
315 case 1: /* sigpending */
316 spin_lock_irq(&current->sighand->siglock);
317 sigandsets(&s, &current->blocked, &current->pending.signal);
318 recalc_sigpending();
319 spin_unlock_irq(&current->sighand->siglock);
320 break;
321 case 2: /* sigfillset - I just set signals which have linux equivalents */
322 sigfillset(&s);
323 break;
324 default: return -EINVAL;
325 }
326 if (mapout (&s, tmp)) return -EINVAL;
327 tmp[2] = 0; tmp[3] = 0;
328 if (copy_to_user ((u32 __user *)A(set), tmp, sizeof(tmp)))
329 return -EFAULT;
330 return 0;
331}
332
333asmlinkage int solaris_wait(u32 stat_loc)
334{
335 unsigned __user *p = (unsigned __user *)A(stat_loc);
336 int (*sys_wait4)(pid_t,unsigned __user *, int, struct rusage __user *) =
337 (int (*)(pid_t,unsigned __user *, int, struct rusage __user *))SYS(wait4);
338 int ret, status;
339
340 ret = sys_wait4(-1, p, WUNTRACED, NULL);
341 if (ret >= 0 && stat_loc) {
342 if (get_user (status, p))
343 return -EFAULT;
344 if (((status - 1) & 0xffff) < 0xff)
345 status = linux_to_solaris_signals[status & 0x7f] & 0x7f;
346 else if ((status & 0xff) == 0x7f)
347 status = (linux_to_solaris_signals[(status >> 8) & 0xff] << 8) | 0x7f;
348 if (__put_user (status, p))
349 return -EFAULT;
350 }
351 return ret;
352}
353
354asmlinkage int solaris_waitid(int idtype, s32 pid, u32 info, int options)
355{
356 int (*sys_wait4)(pid_t,unsigned __user *, int, struct rusage __user *) =
357 (int (*)(pid_t,unsigned __user *, int, struct rusage __user *))SYS(wait4);
358 int opts, status, ret;
359
360 switch (idtype) {
361 case 0: /* P_PID */ break;
362 case 1: /* P_PGID */ pid = -pid; break;
363 case 7: /* P_ALL */ pid = -1; break;
364 default: return -EINVAL;
365 }
366 opts = 0;
367 if (options & SOLARIS_WUNTRACED) opts |= WUNTRACED;
368 if (options & SOLARIS_WNOHANG) opts |= WNOHANG;
369 current->state = TASK_RUNNING;
370 ret = sys_wait4(pid, (unsigned int __user *)A(info), opts, NULL);
371 if (ret < 0) return ret;
372 if (info) {
373 struct sol_siginfo __user *s = (void __user *)A(info);
374
375 if (get_user (status, (unsigned int __user *)A(info)))
376 return -EFAULT;
377
378 if (__put_user (SOLARIS_SIGCLD, &s->si_signo) ||
379 __put_user (ret, &s->_data._proc._pid))
380 return -EFAULT;
381
382 switch (status & 0xff) {
383 case 0: ret = SOLARIS_CLD_EXITED;
384 status = (status >> 8) & 0xff;
385 break;
386 case 0x7f:
387 status = (status >> 8) & 0xff;
388 switch (status) {
389 case SIGSTOP:
390 case SIGTSTP: ret = SOLARIS_CLD_STOPPED;
391 default: ret = SOLARIS_CLD_EXITED;
392 }
393 status = linux_to_solaris_signals[status];
394 break;
395 default:
396 if (status & 0x80) ret = SOLARIS_CLD_DUMPED;
397 else ret = SOLARIS_CLD_KILLED;
398 status = linux_to_solaris_signals[status & 0x7f];
399 break;
400 }
401
402 if (__put_user (ret, &s->si_code) ||
403 __put_user (status, &s->_data._proc._pdata._cld._status))
404 return -EFAULT;
405 }
406 return 0;
407}
408
409extern int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs);
410extern int svr4_getcontext(svr4_ucontext_t *c, struct pt_regs *regs);
411
412asmlinkage int solaris_context(struct pt_regs *regs)
413{
414 switch ((unsigned)regs->u_regs[UREG_I0]) {
415 case 0: /* getcontext */
416 return svr4_getcontext((svr4_ucontext_t *)(long)(u32)regs->u_regs[UREG_I1], regs);
417 case 1: /* setcontext */
418 return svr4_setcontext((svr4_ucontext_t *)(long)(u32)regs->u_regs[UREG_I1], regs);
419 default:
420 return -EINVAL;
421
422 }
423}
424
425asmlinkage int solaris_sigaltstack(u32 ss, u32 oss)
426{
427/* XXX Implement this soon */
428 return 0;
429}
diff --git a/arch/sparc64/solaris/signal.h b/arch/sparc64/solaris/signal.h
deleted file mode 100644
index e91570803050..000000000000
--- a/arch/sparc64/solaris/signal.h
+++ /dev/null
@@ -1,108 +0,0 @@
1/* $Id: signal.h,v 1.3 1998/04/12 06:20:33 davem Exp $
2 * signal.h: Signal emulation for Solaris
3 *
4 * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5 */
6
7#define SOLARIS_SIGHUP 1
8#define SOLARIS_SIGINT 2
9#define SOLARIS_SIGQUIT 3
10#define SOLARIS_SIGILL 4
11#define SOLARIS_SIGTRAP 5
12#define SOLARIS_SIGIOT 6
13#define SOLARIS_SIGEMT 7
14#define SOLARIS_SIGFPE 8
15#define SOLARIS_SIGKILL 9
16#define SOLARIS_SIGBUS 10
17#define SOLARIS_SIGSEGV 11
18#define SOLARIS_SIGSYS 12
19#define SOLARIS_SIGPIPE 13
20#define SOLARIS_SIGALRM 14
21#define SOLARIS_SIGTERM 15
22#define SOLARIS_SIGUSR1 16
23#define SOLARIS_SIGUSR2 17
24#define SOLARIS_SIGCLD 18
25#define SOLARIS_SIGPWR 19
26#define SOLARIS_SIGWINCH 20
27#define SOLARIS_SIGURG 21
28#define SOLARIS_SIGPOLL 22
29#define SOLARIS_SIGSTOP 23
30#define SOLARIS_SIGTSTP 24
31#define SOLARIS_SIGCONT 25
32#define SOLARIS_SIGTTIN 26
33#define SOLARIS_SIGTTOU 27
34#define SOLARIS_SIGVTALRM 28
35#define SOLARIS_SIGPROF 29
36#define SOLARIS_SIGXCPU 30
37#define SOLARIS_SIGXFSZ 31
38#define SOLARIS_SIGWAITING 32
39#define SOLARIS_SIGLWP 33
40#define SOLARIS_SIGFREEZE 34
41#define SOLARIS_SIGTHAW 35
42#define SOLARIS_SIGCANCEL 36
43#define SOLARIS_SIGRTMIN 37
44#define SOLARIS_SIGRTMAX 44
45#define SOLARIS_NSIGNALS 44
46
47
48#define SOLARIS_SA_ONSTACK 1
49#define SOLARIS_SA_RESETHAND 2
50#define SOLARIS_SA_RESTART 4
51#define SOLARIS_SA_SIGINFO 8
52#define SOLARIS_SA_NODEFER 16
53#define SOLARIS_SA_NOCLDWAIT 0x10000
54#define SOLARIS_SA_NOCLDSTOP 0x20000
55
56struct sol_siginfo {
57 int si_signo;
58 int si_code;
59 int si_errno;
60 union {
61 char pad[128-3*sizeof(int)];
62 struct {
63 s32 _pid;
64 union {
65 struct {
66 s32 _uid;
67 s32 _value;
68 } _kill;
69 struct {
70 s32 _utime;
71 int _status;
72 s32 _stime;
73 } _cld;
74 } _pdata;
75 } _proc;
76 struct { /* SIGSEGV, SIGBUS, SIGILL and SIGFPE */
77 u32 _addr;
78 int _trapno;
79 } _fault;
80 struct { /* SIGPOLL, SIGXFSZ */
81 int _fd;
82 s32 _band;
83 } _file;
84 } _data;
85};
86
87#define SOLARIS_WUNTRACED 0x04
88#define SOLARIS_WNOHANG 0x40
89#define SOLARIS_WEXITED 0x01
90#define SOLARIS_WTRAPPED 0x02
91#define SOLARIS_WSTOPPED WUNTRACED
92#define SOLARIS_WCONTINUED 0x08
93#define SOLARIS_WNOWAIT 0x80
94
95#define SOLARIS_TRAP_BRKPT 1
96#define SOLARIS_TRAP_TRACE 2
97#define SOLARIS_CLD_EXITED 1
98#define SOLARIS_CLD_KILLED 2
99#define SOLARIS_CLD_DUMPED 3
100#define SOLARIS_CLD_TRAPPED 4
101#define SOLARIS_CLD_STOPPED 5
102#define SOLARIS_CLD_CONTINUED 6
103#define SOLARIS_POLL_IN 1
104#define SOLARIS_POLL_OUT 2
105#define SOLARIS_POLL_MSG 3
106#define SOLARIS_POLL_ERR 4
107#define SOLARIS_POLL_PRI 5
108#define SOLARIS_POLL_HUP 6
diff --git a/arch/sparc64/solaris/socket.c b/arch/sparc64/solaris/socket.c
deleted file mode 100644
index cc69847cf240..000000000000
--- a/arch/sparc64/solaris/socket.c
+++ /dev/null
@@ -1,461 +0,0 @@
1/* $Id: socket.c,v 1.6 2002/02/08 03:57:14 davem Exp $
2 * socket.c: Socket syscall emulation for Solaris 2.6+
3 *
4 * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz)
5 *
6 * 1999-08-19 Fixed socketpair code
7 * Jason Rappleye (rappleye@ccr.buffalo.edu)
8 */
9
10#include <linux/types.h>
11#include <linux/mm.h>
12#include <linux/slab.h>
13#include <linux/socket.h>
14#include <linux/file.h>
15#include <linux/net.h>
16#include <linux/compat.h>
17#include <net/compat.h>
18#include <net/sock.h>
19
20#include <asm/uaccess.h>
21#include <asm/string.h>
22#include <asm/oplib.h>
23#include <asm/idprom.h>
24
25#include "conv.h"
26
27#define SOCK_SOL_STREAM 2
28#define SOCK_SOL_DGRAM 1
29#define SOCK_SOL_RAW 4
30#define SOCK_SOL_RDM 5
31#define SOCK_SOL_SEQPACKET 6
32
33#define SOL_SO_SNDLOWAT 0x1003
34#define SOL_SO_RCVLOWAT 0x1004
35#define SOL_SO_SNDTIMEO 0x1005
36#define SOL_SO_RCVTIMEO 0x1006
37#define SOL_SO_STATE 0x2000
38
39#define SOL_SS_NDELAY 0x040
40#define SOL_SS_NONBLOCK 0x080
41#define SOL_SS_ASYNC 0x100
42
43#define SO_STATE 0x000e
44
45static int socket_check(int family, int type)
46{
47 if (family != PF_UNIX && family != PF_INET)
48 return -ESOCKTNOSUPPORT;
49 switch (type) {
50 case SOCK_SOL_STREAM: type = SOCK_STREAM; break;
51 case SOCK_SOL_DGRAM: type = SOCK_DGRAM; break;
52 case SOCK_SOL_RAW: type = SOCK_RAW; break;
53 case SOCK_SOL_RDM: type = SOCK_RDM; break;
54 case SOCK_SOL_SEQPACKET: type = SOCK_SEQPACKET; break;
55 default: return -EINVAL;
56 }
57 return type;
58}
59
60static int solaris_to_linux_sockopt(int optname)
61{
62 switch (optname) {
63 case SOL_SO_SNDLOWAT: optname = SO_SNDLOWAT; break;
64 case SOL_SO_RCVLOWAT: optname = SO_RCVLOWAT; break;
65 case SOL_SO_SNDTIMEO: optname = SO_SNDTIMEO; break;
66 case SOL_SO_RCVTIMEO: optname = SO_RCVTIMEO; break;
67 case SOL_SO_STATE: optname = SO_STATE; break;
68 };
69
70 return optname;
71}
72
73asmlinkage int solaris_socket(int family, int type, int protocol)
74{
75 int (*sys_socket)(int, int, int) =
76 (int (*)(int, int, int))SYS(socket);
77
78 type = socket_check (family, type);
79 if (type < 0) return type;
80 return sys_socket(family, type, protocol);
81}
82
83asmlinkage int solaris_socketpair(int *usockvec)
84{
85 int (*sys_socketpair)(int, int, int, int *) =
86 (int (*)(int, int, int, int *))SYS(socketpair);
87
88 /* solaris socketpair really only takes one arg at the syscall
89 * level, int * usockvec. The libs apparently take care of
90 * making sure that family==AF_UNIX and type==SOCK_STREAM. The
91 * pointer we really want ends up residing in the first (and
92 * supposedly only) argument.
93 */
94
95 return sys_socketpair(AF_UNIX, SOCK_STREAM, 0, (int *)usockvec);
96}
97
98asmlinkage int solaris_bind(int fd, struct sockaddr *addr, int addrlen)
99{
100 int (*sys_bind)(int, struct sockaddr *, int) =
101 (int (*)(int, struct sockaddr *, int))SUNOS(104);
102
103 return sys_bind(fd, addr, addrlen);
104}
105
106asmlinkage int solaris_setsockopt(int fd, int level, int optname, u32 optval, int optlen)
107{
108 int (*sunos_setsockopt)(int, int, int, u32, int) =
109 (int (*)(int, int, int, u32, int))SUNOS(105);
110
111 optname = solaris_to_linux_sockopt(optname);
112 if (optname < 0)
113 return optname;
114 if (optname == SO_STATE)
115 return 0;
116
117 return sunos_setsockopt(fd, level, optname, optval, optlen);
118}
119
120asmlinkage int solaris_getsockopt(int fd, int level, int optname, u32 optval, u32 optlen)
121{
122 int (*sunos_getsockopt)(int, int, int, u32, u32) =
123 (int (*)(int, int, int, u32, u32))SUNOS(118);
124
125 optname = solaris_to_linux_sockopt(optname);
126 if (optname < 0)
127 return optname;
128
129 if (optname == SO_STATE)
130 optname = SOL_SO_STATE;
131
132 return sunos_getsockopt(fd, level, optname, optval, optlen);
133}
134
135asmlinkage int solaris_connect(int fd, struct sockaddr __user *addr, int addrlen)
136{
137 int (*sys_connect)(int, struct sockaddr __user *, int) =
138 (int (*)(int, struct sockaddr __user *, int))SYS(connect);
139
140 return sys_connect(fd, addr, addrlen);
141}
142
143asmlinkage int solaris_accept(int fd, struct sockaddr __user *addr, int __user *addrlen)
144{
145 int (*sys_accept)(int, struct sockaddr __user *, int __user *) =
146 (int (*)(int, struct sockaddr __user *, int __user *))SYS(accept);
147
148 return sys_accept(fd, addr, addrlen);
149}
150
151asmlinkage int solaris_listen(int fd, int backlog)
152{
153 int (*sys_listen)(int, int) =
154 (int (*)(int, int))SUNOS(106);
155
156 return sys_listen(fd, backlog);
157}
158
159asmlinkage int solaris_shutdown(int fd, int how)
160{
161 int (*sys_shutdown)(int, int) =
162 (int (*)(int, int))SYS(shutdown);
163
164 return sys_shutdown(fd, how);
165}
166
167#define MSG_SOL_OOB 0x1
168#define MSG_SOL_PEEK 0x2
169#define MSG_SOL_DONTROUTE 0x4
170#define MSG_SOL_EOR 0x8
171#define MSG_SOL_CTRUNC 0x10
172#define MSG_SOL_TRUNC 0x20
173#define MSG_SOL_WAITALL 0x40
174#define MSG_SOL_DONTWAIT 0x80
175
176static int solaris_to_linux_msgflags(int flags)
177{
178 int fl = flags & (MSG_OOB|MSG_PEEK|MSG_DONTROUTE);
179
180 if (flags & MSG_SOL_EOR) fl |= MSG_EOR;
181 if (flags & MSG_SOL_CTRUNC) fl |= MSG_CTRUNC;
182 if (flags & MSG_SOL_TRUNC) fl |= MSG_TRUNC;
183 if (flags & MSG_SOL_WAITALL) fl |= MSG_WAITALL;
184 if (flags & MSG_SOL_DONTWAIT) fl |= MSG_DONTWAIT;
185 return fl;
186}
187
188static int linux_to_solaris_msgflags(int flags)
189{
190 int fl = flags & (MSG_OOB|MSG_PEEK|MSG_DONTROUTE);
191
192 if (flags & MSG_EOR) fl |= MSG_SOL_EOR;
193 if (flags & MSG_CTRUNC) fl |= MSG_SOL_CTRUNC;
194 if (flags & MSG_TRUNC) fl |= MSG_SOL_TRUNC;
195 if (flags & MSG_WAITALL) fl |= MSG_SOL_WAITALL;
196 if (flags & MSG_DONTWAIT) fl |= MSG_SOL_DONTWAIT;
197 return fl;
198}
199
200asmlinkage int solaris_recvfrom(int s, char __user *buf, int len, int flags, u32 from, u32 fromlen)
201{
202 int (*sys_recvfrom)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *) =
203 (int (*)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *))SYS(recvfrom);
204
205 return sys_recvfrom(s, buf, len, solaris_to_linux_msgflags(flags), A(from), A(fromlen));
206}
207
208asmlinkage int solaris_recv(int s, char __user *buf, int len, int flags)
209{
210 int (*sys_recvfrom)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *) =
211 (int (*)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *))SYS(recvfrom);
212
213 return sys_recvfrom(s, buf, len, solaris_to_linux_msgflags(flags), NULL, NULL);
214}
215
216asmlinkage int solaris_sendto(int s, char __user *buf, int len, int flags, u32 to, u32 tolen)
217{
218 int (*sys_sendto)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *) =
219 (int (*)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *))SYS(sendto);
220
221 return sys_sendto(s, buf, len, solaris_to_linux_msgflags(flags), A(to), A(tolen));
222}
223
224asmlinkage int solaris_send(int s, char *buf, int len, int flags)
225{
226 int (*sys_sendto)(int, void *, size_t, unsigned, struct sockaddr *, int *) =
227 (int (*)(int, void *, size_t, unsigned, struct sockaddr *, int *))SYS(sendto);
228
229 return sys_sendto(s, buf, len, solaris_to_linux_msgflags(flags), NULL, NULL);
230}
231
232asmlinkage int solaris_getpeername(int fd, struct sockaddr *addr, int *addrlen)
233{
234 int (*sys_getpeername)(int, struct sockaddr *, int *) =
235 (int (*)(int, struct sockaddr *, int *))SYS(getpeername);
236
237 return sys_getpeername(fd, addr, addrlen);
238}
239
240asmlinkage int solaris_getsockname(int fd, struct sockaddr *addr, int *addrlen)
241{
242 int (*sys_getsockname)(int, struct sockaddr *, int *) =
243 (int (*)(int, struct sockaddr *, int *))SYS(getsockname);
244
245 return sys_getsockname(fd, addr, addrlen);
246}
247
248/* XXX This really belongs in some header file... -DaveM */
249#define MAX_SOCK_ADDR 128 /* 108 for Unix domain -
250 16 for IP, 16 for IPX,
251 24 for IPv6,
252 about 80 for AX.25 */
253
254struct sol_nmsghdr {
255 u32 msg_name;
256 int msg_namelen;
257 u32 msg_iov;
258 u32 msg_iovlen;
259 u32 msg_control;
260 u32 msg_controllen;
261 u32 msg_flags;
262};
263
264struct sol_cmsghdr {
265 u32 cmsg_len;
266 int cmsg_level;
267 int cmsg_type;
268 unsigned char cmsg_data[0];
269};
270
271static inline int msghdr_from_user32_to_kern(struct msghdr *kmsg,
272 struct sol_nmsghdr __user *umsg)
273{
274 u32 tmp1, tmp2, tmp3;
275 int err;
276
277 err = get_user(tmp1, &umsg->msg_name);
278 err |= __get_user(tmp2, &umsg->msg_iov);
279 err |= __get_user(tmp3, &umsg->msg_control);
280 if (err)
281 return -EFAULT;
282
283 kmsg->msg_name = A(tmp1);
284 kmsg->msg_iov = A(tmp2);
285 kmsg->msg_control = A(tmp3);
286
287 err = get_user(kmsg->msg_namelen, &umsg->msg_namelen);
288 err |= get_user(kmsg->msg_controllen, &umsg->msg_controllen);
289 err |= get_user(kmsg->msg_flags, &umsg->msg_flags);
290
291 kmsg->msg_flags = solaris_to_linux_msgflags(kmsg->msg_flags);
292
293 return err;
294}
295
296asmlinkage int solaris_sendmsg(int fd, struct sol_nmsghdr __user *user_msg, unsigned user_flags)
297{
298 struct socket *sock;
299 char address[MAX_SOCK_ADDR];
300 struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;
301 unsigned char ctl[sizeof(struct cmsghdr) + 20];
302 unsigned char *ctl_buf = ctl;
303 struct msghdr msg_sys;
304 int err, ctl_len, iov_size, total_len;
305
306 err = -EFAULT;
307 if (msghdr_from_user32_to_kern(&msg_sys, user_msg))
308 goto out;
309
310 sock = sockfd_lookup(fd, &err);
311 if (!sock)
312 goto out;
313
314 /* do not move before msg_sys is valid */
315 err = -EMSGSIZE;
316 if (msg_sys.msg_iovlen > UIO_MAXIOV)
317 goto out_put;
318
319 /* Check whether to allocate the iovec area*/
320 err = -ENOMEM;
321 iov_size = msg_sys.msg_iovlen * sizeof(struct iovec);
322 if (msg_sys.msg_iovlen > UIO_FASTIOV) {
323 iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL);
324 if (!iov)
325 goto out_put;
326 }
327
328 err = verify_compat_iovec(&msg_sys, iov, address, VERIFY_READ);
329 if (err < 0)
330 goto out_freeiov;
331 total_len = err;
332
333 err = -ENOBUFS;
334 if (msg_sys.msg_controllen > INT_MAX)
335 goto out_freeiov;
336
337 ctl_len = msg_sys.msg_controllen;
338 if (ctl_len) {
339 struct sol_cmsghdr __user *ucmsg = msg_sys.msg_control;
340 unsigned long *kcmsg;
341 compat_size_t cmlen;
342
343 err = -EINVAL;
344 if (ctl_len <= sizeof(compat_size_t))
345 goto out_freeiov;
346
347 if (ctl_len > sizeof(ctl)) {
348 err = -ENOBUFS;
349 ctl_buf = kmalloc(ctl_len, GFP_KERNEL);
350 if (!ctl_buf)
351 goto out_freeiov;
352 }
353 __get_user(cmlen, &ucmsg->cmsg_len);
354 kcmsg = (unsigned long *) ctl_buf;
355 *kcmsg++ = (unsigned long)cmlen;
356 err = -EFAULT;
357 if (copy_from_user(kcmsg, &ucmsg->cmsg_level,
358 ctl_len - sizeof(compat_size_t)))
359 goto out_freectl;
360 msg_sys.msg_control = ctl_buf;
361 }
362 msg_sys.msg_flags = solaris_to_linux_msgflags(user_flags);
363
364 if (sock->file->f_flags & O_NONBLOCK)
365 msg_sys.msg_flags |= MSG_DONTWAIT;
366 err = sock_sendmsg(sock, &msg_sys, total_len);
367
368out_freectl:
369 if (ctl_buf != ctl)
370 sock_kfree_s(sock->sk, ctl_buf, ctl_len);
371out_freeiov:
372 if (iov != iovstack)
373 sock_kfree_s(sock->sk, iov, iov_size);
374out_put:
375 sockfd_put(sock);
376out:
377 return err;
378}
379
380asmlinkage int solaris_recvmsg(int fd, struct sol_nmsghdr __user *user_msg, unsigned int user_flags)
381{
382 struct socket *sock;
383 struct iovec iovstack[UIO_FASTIOV];
384 struct iovec *iov = iovstack;
385 struct msghdr msg_sys;
386 unsigned long cmsg_ptr;
387 int err, iov_size, total_len, len;
388
389 /* kernel mode address */
390 char addr[MAX_SOCK_ADDR];
391
392 /* user mode address pointers */
393 struct sockaddr __user *uaddr;
394 int __user *uaddr_len;
395
396 if (msghdr_from_user32_to_kern(&msg_sys, user_msg))
397 return -EFAULT;
398
399 sock = sockfd_lookup(fd, &err);
400 if (!sock)
401 goto out;
402
403 err = -EMSGSIZE;
404 if (msg_sys.msg_iovlen > UIO_MAXIOV)
405 goto out_put;
406
407 /* Check whether to allocate the iovec area*/
408 err = -ENOMEM;
409 iov_size = msg_sys.msg_iovlen * sizeof(struct iovec);
410 if (msg_sys.msg_iovlen > UIO_FASTIOV) {
411 iov = sock_kmalloc(sock->sk, iov_size, GFP_KERNEL);
412 if (!iov)
413 goto out_put;
414 }
415
416 /*
417 * Save the user-mode address (verify_iovec will change the
418 * kernel msghdr to use the kernel address space)
419 */
420
421 uaddr = (void __user *) msg_sys.msg_name;
422 uaddr_len = &user_msg->msg_namelen;
423 err = verify_compat_iovec(&msg_sys, iov, addr, VERIFY_WRITE);
424 if (err < 0)
425 goto out_freeiov;
426 total_len = err;
427
428 cmsg_ptr = (unsigned long) msg_sys.msg_control;
429 msg_sys.msg_flags = MSG_CMSG_COMPAT;
430
431 if (sock->file->f_flags & O_NONBLOCK)
432 user_flags |= MSG_DONTWAIT;
433
434 err = sock_recvmsg(sock, &msg_sys, total_len, user_flags);
435 if(err < 0)
436 goto out_freeiov;
437
438 len = err;
439
440 if (uaddr != NULL) {
441 err = move_addr_to_user(addr, msg_sys.msg_namelen, uaddr, uaddr_len);
442 if (err < 0)
443 goto out_freeiov;
444 }
445 err = __put_user(linux_to_solaris_msgflags(msg_sys.msg_flags), &user_msg->msg_flags);
446 if (err)
447 goto out_freeiov;
448 err = __put_user((unsigned long)msg_sys.msg_control - cmsg_ptr,
449 &user_msg->msg_controllen);
450 if (err)
451 goto out_freeiov;
452 err = len;
453
454out_freeiov:
455 if (iov != iovstack)
456 sock_kfree_s(sock->sk, iov, iov_size);
457out_put:
458 sockfd_put(sock);
459out:
460 return err;
461}
diff --git a/arch/sparc64/solaris/socksys.c b/arch/sparc64/solaris/socksys.c
deleted file mode 100644
index 7736411f244f..000000000000
--- a/arch/sparc64/solaris/socksys.c
+++ /dev/null
@@ -1,203 +0,0 @@
1/* $Id: socksys.c,v 1.21 2002/02/08 03:57:14 davem Exp $
2 * socksys.c: /dev/inet/ stuff for Solaris emulation.
3 *
4 * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5 * Copyright (C) 1997, 1998 Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)
6 * Copyright (C) 1995, 1996 Mike Jagdis (jaggy@purplet.demon.co.uk)
7 */
8
9/*
10 * Dave, _please_ give me specifications on this fscking mess so that I
11 * could at least get it into the state when it wouldn't screw the rest of
12 * the kernel over. socksys.c and timod.c _stink_ and we are not talking
13 * H2S here, it's isopropilmercaptan in concentrations way over LD50. -- AV
14 */
15
16#include <linux/types.h>
17#include <linux/kernel.h>
18#include <linux/sched.h>
19#include <linux/smp.h>
20#include <linux/ioctl.h>
21#include <linux/fs.h>
22#include <linux/file.h>
23#include <linux/init.h>
24#include <linux/poll.h>
25#include <linux/slab.h>
26#include <linux/syscalls.h>
27#include <linux/in.h>
28
29#include <net/sock.h>
30
31#include <asm/uaccess.h>
32#include <asm/termios.h>
33
34#include "conv.h"
35#include "socksys.h"
36
37static int af_inet_protocols[] = {
38IPPROTO_ICMP, IPPROTO_ICMP, IPPROTO_IGMP, IPPROTO_IPIP, IPPROTO_TCP,
39IPPROTO_EGP, IPPROTO_PUP, IPPROTO_UDP, IPPROTO_IDP, IPPROTO_RAW,
400, 0, 0, 0, 0, 0,
41};
42
43#ifndef DEBUG_SOLARIS_KMALLOC
44
45#define mykmalloc kmalloc
46#define mykfree kfree
47
48#else
49
50extern void * mykmalloc(size_t s, gfp_t gfp);
51extern void mykfree(void *);
52
53#endif
54
55static unsigned int (*sock_poll)(struct file *, poll_table *);
56
57static struct file_operations socksys_file_ops = {
58 /* Currently empty */
59};
60
61static int socksys_open(struct inode * inode, struct file * filp)
62{
63 int family, type, protocol, fd;
64 struct dentry *dentry;
65 int (*sys_socket)(int,int,int) =
66 (int (*)(int,int,int))SUNOS(97);
67 struct sol_socket_struct * sock;
68
69 family = ((iminor(inode) >> 4) & 0xf);
70 switch (family) {
71 case AF_UNIX:
72 type = SOCK_STREAM;
73 protocol = 0;
74 break;
75 case AF_INET:
76 protocol = af_inet_protocols[iminor(inode) & 0xf];
77 switch (protocol) {
78 case IPPROTO_TCP: type = SOCK_STREAM; break;
79 case IPPROTO_UDP: type = SOCK_DGRAM; break;
80 default: type = SOCK_RAW; break;
81 }
82 break;
83 default:
84 type = SOCK_RAW;
85 protocol = 0;
86 break;
87 }
88
89 fd = sys_socket(family, type, protocol);
90 if (fd < 0)
91 return fd;
92 /*
93 * N.B. The following operations are not legal!
94 *
95 * No shit. WTF is it supposed to do, anyway?
96 *
97 * Try instead:
98 * d_delete(filp->f_path.dentry), then d_instantiate with sock inode
99 */
100 dentry = filp->f_path.dentry;
101 filp->f_path.dentry = dget(fcheck(fd)->f_path.dentry);
102 filp->f_path.dentry->d_inode->i_rdev = inode->i_rdev;
103 filp->f_path.dentry->d_inode->i_flock = inode->i_flock;
104 SOCKET_I(filp->f_path.dentry->d_inode)->file = filp;
105 filp->f_op = &socksys_file_ops;
106 sock = (struct sol_socket_struct*)
107 mykmalloc(sizeof(struct sol_socket_struct), GFP_KERNEL);
108 if (!sock) return -ENOMEM;
109 SOLDD(("sock=%016lx(%016lx)\n", sock, filp));
110 sock->magic = SOLARIS_SOCKET_MAGIC;
111 sock->modcount = 0;
112 sock->state = TS_UNBND;
113 sock->offset = 0;
114 sock->pfirst = sock->plast = NULL;
115 filp->private_data = sock;
116 SOLDD(("filp->private_data %016lx\n", filp->private_data));
117
118 sys_close(fd);
119 dput(dentry);
120 return 0;
121}
122
123static int socksys_release(struct inode * inode, struct file * filp)
124{
125 struct sol_socket_struct * sock;
126 struct T_primsg *it;
127
128 /* XXX: check this */
129 sock = (struct sol_socket_struct *)filp->private_data;
130 SOLDD(("sock release %016lx(%016lx)\n", sock, filp));
131 it = sock->pfirst;
132 while (it) {
133 struct T_primsg *next = it->next;
134
135 SOLDD(("socksys_release %016lx->%016lx\n", it, next));
136 mykfree((char*)it);
137 it = next;
138 }
139 filp->private_data = NULL;
140 SOLDD(("socksys_release %016lx\n", sock));
141 mykfree((char*)sock);
142 return 0;
143}
144
145static unsigned int socksys_poll(struct file * filp, poll_table * wait)
146{
147 struct inode *ino;
148 unsigned int mask = 0;
149
150 ino=filp->f_path.dentry->d_inode;
151 if (ino && S_ISSOCK(ino->i_mode)) {
152 struct sol_socket_struct *sock;
153 sock = (struct sol_socket_struct*)filp->private_data;
154 if (sock && sock->pfirst) {
155 mask |= POLLIN | POLLRDNORM;
156 if (sock->pfirst->pri == MSG_HIPRI)
157 mask |= POLLPRI;
158 }
159 }
160 if (sock_poll)
161 mask |= (*sock_poll)(filp, wait);
162 return mask;
163}
164
165static const struct file_operations socksys_fops = {
166 .open = socksys_open,
167 .release = socksys_release,
168};
169
170int __init init_socksys(void)
171{
172 int ret;
173 struct file * file;
174 int (*sys_socket)(int,int,int) =
175 (int (*)(int,int,int))SUNOS(97);
176 int (*sys_close)(unsigned int) =
177 (int (*)(unsigned int))SYS(close);
178
179 ret = register_chrdev (30, "socksys", &socksys_fops);
180 if (ret < 0) {
181 printk ("Couldn't register socksys character device\n");
182 return ret;
183 }
184 ret = sys_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
185 if (ret < 0) {
186 printk ("Couldn't create socket\n");
187 return ret;
188 }
189
190 file = fcheck(ret);
191 /* N.B. Is this valid? Suppose the f_ops are in a module ... */
192 socksys_file_ops = *file->f_op;
193 sys_close(ret);
194 sock_poll = socksys_file_ops.poll;
195 socksys_file_ops.poll = socksys_poll;
196 socksys_file_ops.release = socksys_release;
197 return 0;
198}
199
200void __exit cleanup_socksys(void)
201{
202 unregister_chrdev(30, "socksys");
203}
diff --git a/arch/sparc64/solaris/socksys.h b/arch/sparc64/solaris/socksys.h
deleted file mode 100644
index 5d1b78ec1600..000000000000
--- a/arch/sparc64/solaris/socksys.h
+++ /dev/null
@@ -1,208 +0,0 @@
1/* $Id: socksys.h,v 1.2 1998/03/26 08:46:07 jj Exp $
2 * socksys.h: Definitions for STREAMS modules emulation code.
3 *
4 * Copyright (C) 1998 Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)
5 */
6
7#define MSG_HIPRI 0x01
8#define MSG_ANY 0x02
9#define MSG_BAND 0x04
10
11#define MORECTL 1
12#define MOREDATA 2
13
14#define TBADADDR 1
15#define TBADOPT 2
16#define TACCES 3
17#define TBADF 4
18#define TNOADDR 5
19#define TOUTSTATE 6
20#define TBADSEQ 7
21#define TSYSERR 8
22#define TLOOK 9
23#define TBADDATA 10
24#define TBUFOVFLW 11
25#define TFLOW 12
26#define TNODATA 13
27#define TNODIS 14
28#define TNOUDERR 15
29#define TBADFLAG 16
30#define TNOREL 17
31#define TNOTSUPPORT 18
32#define TSTATECHNG 19
33
34#define T_CONN_REQ 0
35#define T_CONN_RES 1
36#define T_DISCON_REQ 2
37#define T_DATA_REQ 3
38#define T_EXDATA_REQ 4
39#define T_INFO_REQ 5
40#define T_BIND_REQ 6
41#define T_UNBIND_REQ 7
42#define T_UNITDATA_REQ 8
43#define T_OPTMGMT_REQ 9
44#define T_ORDREL_REQ 10
45
46#define T_CONN_IND 11
47#define T_CONN_CON 12
48#define T_DISCON_IND 13
49#define T_DATA_IND 14
50#define T_EXDATA_IND 15
51#define T_INFO_ACK 16
52#define T_BIND_ACK 17
53#define T_ERROR_ACK 18
54#define T_OK_ACK 19
55#define T_UNITDATA_IND 20
56#define T_UDERROR_IND 21
57#define T_OPTMGMT_ACK 22
58#define T_ORDREL_IND 23
59
60#define T_NEGOTIATE 0x0004
61#define T_FAILURE 0x0040
62
63#define TS_UNBND 0 /* unbound */
64#define TS_WACK_BREQ 1 /* waiting for T_BIND_REQ ack */
65#define TS_WACK_UREQ 2 /* waiting for T_UNBIND_REQ ack */
66#define TS_IDLE 3 /* idle */
67#define TS_WACK_OPTREQ 4 /* waiting for T_OPTMGMT_REQ ack */
68#define TS_WACK_CREQ 5 /* waiting for T_CONN_REQ ack */
69#define TS_WCON_CREQ 6 /* waiting for T_CONN_REQ confirmation */
70#define TS_WRES_CIND 7 /* waiting for T_CONN_IND */
71#define TS_WACK_CRES 8 /* waiting for T_CONN_RES ack */
72#define TS_DATA_XFER 9 /* data transfer */
73#define TS_WIND_ORDREL 10 /* releasing read but not write */
74#define TS_WREQ_ORDREL 11 /* wait to release write but not read */
75#define TS_WACK_DREQ6 12 /* waiting for T_DISCON_REQ ack */
76#define TS_WACK_DREQ7 13 /* waiting for T_DISCON_REQ ack */
77#define TS_WACK_DREQ9 14 /* waiting for T_DISCON_REQ ack */
78#define TS_WACK_DREQ10 15 /* waiting for T_DISCON_REQ ack */
79#define TS_WACK_DREQ11 16 /* waiting for T_DISCON_REQ ack */
80#define TS_NOSTATES 17
81
82struct T_conn_req {
83 s32 PRIM_type;
84 s32 DEST_length;
85 s32 DEST_offset;
86 s32 OPT_length;
87 s32 OPT_offset;
88};
89
90struct T_bind_req {
91 s32 PRIM_type;
92 s32 ADDR_length;
93 s32 ADDR_offset;
94 u32 CONIND_number;
95};
96
97struct T_unitdata_req {
98 s32 PRIM_type;
99 s32 DEST_length;
100 s32 DEST_offset;
101 s32 OPT_length;
102 s32 OPT_offset;
103};
104
105struct T_optmgmt_req {
106 s32 PRIM_type;
107 s32 OPT_length;
108 s32 OPT_offset;
109 s32 MGMT_flags;
110};
111
112struct T_bind_ack {
113 s32 PRIM_type;
114 s32 ADDR_length;
115 s32 ADDR_offset;
116 u32 CONIND_number;
117};
118
119struct T_error_ack {
120 s32 PRIM_type;
121 s32 ERROR_prim;
122 s32 TLI_error;
123 s32 UNIX_error;
124};
125
126struct T_ok_ack {
127 s32 PRIM_type;
128 s32 CORRECT_prim;
129};
130
131struct T_conn_ind {
132 s32 PRIM_type;
133 s32 SRC_length;
134 s32 SRC_offset;
135 s32 OPT_length;
136 s32 OPT_offset;
137 s32 SEQ_number;
138};
139
140struct T_conn_con {
141 s32 PRIM_type;
142 s32 RES_length;
143 s32 RES_offset;
144 s32 OPT_length;
145 s32 OPT_offset;
146};
147
148struct T_discon_ind {
149 s32 PRIM_type;
150 s32 DISCON_reason;
151 s32 SEQ_number;
152};
153
154struct T_unitdata_ind {
155 s32 PRIM_type;
156 s32 SRC_length;
157 s32 SRC_offset;
158 s32 OPT_length;
159 s32 OPT_offset;
160};
161
162struct T_optmgmt_ack {
163 s32 PRIM_type;
164 s32 OPT_length;
165 s32 OPT_offset;
166 s32 MGMT_flags;
167};
168
169struct opthdr {
170 s32 level;
171 s32 name;
172 s32 len;
173 char value[0];
174};
175
176struct T_primsg {
177 struct T_primsg *next;
178 unsigned char pri;
179 unsigned char band;
180 int length;
181 s32 type;
182};
183
184struct strbuf {
185 s32 maxlen;
186 s32 len;
187 u32 buf;
188} ;
189
190/* Constants used by STREAMS modules emulation code */
191
192typedef char sol_module;
193
194#define MAX_NR_STREAM_MODULES 16
195
196/* Private data structure assigned to sockets. */
197
198struct sol_socket_struct {
199 int magic;
200 int modcount;
201 sol_module module[MAX_NR_STREAM_MODULES];
202 long state;
203 int offset;
204 struct T_primsg *pfirst, *plast;
205};
206
207#define SOLARIS_SOCKET_MAGIC 0xADDED
208
diff --git a/arch/sparc64/solaris/systbl.S b/arch/sparc64/solaris/systbl.S
deleted file mode 100644
index 7043ca18caf9..000000000000
--- a/arch/sparc64/solaris/systbl.S
+++ /dev/null
@@ -1,285 +0,0 @@
1/* $Id: systbl.S,v 1.11 2000/03/13 21:57:35 davem Exp $
2 * systbl.S: System call entry point table for Solaris compatibility.
3 *
4 * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5 * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
6 */
7
8#include <asm/unistd.h>
9
10/* Fall back to sys_call_table32 entry */
11#define CHAIN(name) __NR_##name
12
13/* Pass pt_regs pointer as first argument */
14#define REGS(name) name+1
15
16/* Hack till all be implemented */
17#define solaris_getpmsg solaris_unimplemented
18#define solaris_hrtsys solaris_unimplemented
19#define solaris_msgsys solaris_unimplemented
20#define solaris_putpmsg solaris_unimplemented
21#define solaris_semsys solaris_unimplemented
22
23 .data
24 .globl solaris_sys_table
25solaris_sys_table:
26 .word solaris_unimplemented /* nosys 0 */
27 .word CHAIN(exit) /* exit d 1 */
28 .word CHAIN(fork) /* fork 2 */
29 .word CHAIN(read) /* read dpd 3 */
30 .word CHAIN(write) /* write dpd 4 */
31 .word solaris_open /* open soo 5 */
32 .word CHAIN(close) /* close d 6 */
33 .word solaris_wait /* wait xxx 7 */
34 .word CHAIN(creat) /* creat so 8 */
35 .word CHAIN(link) /* link ss 9 */
36 .word CHAIN(unlink) /* unlink s 10 */
37 .word solaris_unimplemented /* exec sxx 11 */
38 .word CHAIN(chdir) /* chdir s 12 */
39 .word CHAIN(time) /* time 13 */
40 .word solaris_mknod /* mknod sox 14 */
41 .word CHAIN(chmod) /* chmod so 15 */
42 .word CHAIN(chown) /* chown sdd 16 */
43 .word solaris_brk /* brk/break x 17 */
44 .word solaris_stat /* stat sp 18 */
45 .word CHAIN(lseek) /* seek/lseek ddd 19 */
46 .word solaris_getpid /* getpid 20 */
47 .word solaris_unimplemented /* mount 21 */
48 .word CHAIN(umount) /* umount s 22 */
49 .word CHAIN(setuid) /* setuid d 23 */
50 .word solaris_getuid /* getuid 24 */
51 .word CHAIN(stime) /* stime d 25 */
52#if 0
53 .word solaris_ptrace /* ptrace xdxx 26 */
54#else
55 .word CHAIN(ptrace) /* ptrace xdxx 26 */
56#endif
57 .word CHAIN(alarm) /* alarm d 27 */
58 .word solaris_fstat /* fstat dp 28 */
59 .word CHAIN(pause) /* pause 29 */
60 .word CHAIN(utime) /* utime xx 30 */
61 .word solaris_unimplemented /* stty 31 */
62 .word solaris_unimplemented /* gtty 32 */
63 .word solaris_access /* access so 33 */
64 .word CHAIN(nice) /* nice d 34 */
65 .word solaris_statfs /* statfs spdd 35 */
66 .word CHAIN(sync) /* sync 36 */
67 .word solaris_kill /* kill dd 37 */
68 .word solaris_fstatfs /* fstatfs dpdd 38 */
69 .word solaris_procids /* pgrpsys ddd 39 */
70 .word solaris_unimplemented /* xenix 40 */
71 .word CHAIN(dup) /* dup d 41 */
72 .word CHAIN(pipe) /* pipe 42 */
73 .word CHAIN(times) /* times p 43 */
74 .word 44 /*CHAIN(profil)*/ /* prof xxxx 44 */
75 .word solaris_unimplemented /* lock/plock 45 */
76 .word CHAIN(setgid) /* setgid d 46 */
77 .word solaris_getgid /* getgid 47 */
78 .word solaris_sigfunc /* sigfunc xx 48 */
79 .word REGS(solaris_msgsys) /* msgsys dxddd 49 */
80 .word solaris_unimplemented /* syssun/3b 50 */
81 .word CHAIN(acct) /* acct/sysacct x 51 */
82 .word solaris_shmsys /* shmsys ddxo 52 */
83 .word REGS(solaris_semsys) /* semsys dddx 53 */
84 .word solaris_ioctl /* ioctl dxx 54 */
85 .word solaris_unimplemented /* uadmin xxx 55 */
86 .word solaris_unimplemented /* reserved:exch 56 */
87 .word solaris_utssys /* utssys x 57 */
88 .word CHAIN(fsync) /* fsync d 58 */
89 .word CHAIN(execve) /* execv spp 59 */
90 .word CHAIN(umask) /* umask o 60 */
91 .word CHAIN(chroot) /* chroot s 61 */
92 .word solaris_fcntl /* fcntl dxx 62 */
93 .word solaris_ulimit /* ulimit xx 63 */
94 .word solaris_unimplemented /* ? 64 */
95 .word solaris_unimplemented /* ? 65 */
96 .word solaris_unimplemented /* ? 66 */
97 .word solaris_unimplemented /* ? 67 */
98 .word solaris_unimplemented /* ? 68 */
99 .word solaris_unimplemented /* ? 69 */
100 .word solaris_unimplemented /* advfs 70 */
101 .word solaris_unimplemented /* unadvfs 71 */
102 .word solaris_unimplemented /* rmount 72 */
103 .word solaris_unimplemented /* rumount 73 */
104 .word solaris_unimplemented /* rfstart 74 */
105 .word solaris_unimplemented /* ? 75 */
106 .word solaris_unimplemented /* rdebug 76 */
107 .word solaris_unimplemented /* rfstop 77 */
108 .word solaris_unimplemented /* rfsys 78 */
109 .word CHAIN(rmdir) /* rmdir s 79 */
110 .word CHAIN(mkdir) /* mkdir so 80 */
111 .word CHAIN(getdents) /* getdents dxd 81 */
112 .word solaris_unimplemented /* libattach 82 */
113 .word solaris_unimplemented /* libdetach 83 */
114 .word CHAIN(sysfs) /* sysfs dxx 84 */
115 .word solaris_getmsg /* getmsg dxxx 85 */
116 .word solaris_putmsg /* putmsg dxxd 86 */
117 .word CHAIN(poll) /* poll xdd 87 */
118 .word solaris_lstat /* lstat sp 88 */
119 .word CHAIN(symlink) /* symlink ss 89 */
120 .word CHAIN(readlink) /* readlink spd 90 */
121 .word CHAIN(setgroups) /* setgroups dp 91 */
122 .word CHAIN(getgroups) /* getgroups dp 92 */
123 .word CHAIN(fchmod) /* fchmod do 93 */
124 .word CHAIN(fchown) /* fchown ddd 94 */
125 .word solaris_sigprocmask /* sigprocmask dxx 95 */
126 .word solaris_sigsuspend /* sigsuspend x 96 */
127 .word solaris_sigaltstack /* sigaltstack xx 97 */
128 .word solaris_sigaction /* sigaction dxx 98 */
129 .word solaris_sigpending /* sigpending dd 99 */
130 .word REGS(solaris_context) /* context 100 */
131 .word solaris_unimplemented /* evsys 101 */
132 .word solaris_unimplemented /* evtrapret 102 */
133 .word solaris_statvfs /* statvfs sp 103 */
134 .word solaris_fstatvfs /* fstatvfs dp 104 */
135 .word solaris_unimplemented /* unknown 105 */
136 .word solaris_unimplemented /* nfssys 106 */
137 .word solaris_waitid /* waitid ddxd 107 */
138 .word solaris_unimplemented /* sigsendsys ddd 108 */
139 .word REGS(solaris_hrtsys) /* hrtsys xxx 109 */
140 .word solaris_unimplemented /* acancel dxd 110 */
141 .word solaris_unimplemented /* async 111 */
142 .word solaris_unimplemented /* priocntlsys 112 */
143 .word solaris_pathconf /* pathconf sd 113 */
144 .word CHAIN(mincore) /* mincore d 114 */
145 .word solaris_mmap /* mmap xxxxdx 115 */
146 .word CHAIN(mprotect) /* mprotect xdx 116 */
147 .word CHAIN(munmap) /* munmap xd 117 */
148 .word solaris_fpathconf /* fpathconf dd 118 */
149 .word CHAIN(fork) /* fork 119 */
150 .word solaris_unimplemented /* fchdir d 120 */
151 .word CHAIN(readv) /* readv dxd 121 */
152 .word CHAIN(writev) /* writev dxd 122 */
153 .word solaris_xstat /* xstat dsx 123 */
154 .word solaris_lxstat /* lxstat dsx 124 */
155 .word solaris_fxstat /* fxstat ddx 125 */
156 .word solaris_xmknod /* xmknod dsox 126 */
157 .word solaris_unimplemented /* syslocal d 127 */
158 .word solaris_setrlimit /* setrlimit dp 128 */
159 .word solaris_getrlimit /* getrlimit dp 129 */
160 .word CHAIN(chown) /* lchown sdd 130 */
161 .word solaris_unimplemented /* memcntl 131 */
162 .word solaris_getpmsg /* getpmsg dxxxx 132 */
163 .word solaris_putpmsg /* putpmsg dxxdd 133 */
164 .word CHAIN(rename) /* rename ss 134 */
165 .word solaris_utsname /* uname x 135 */
166 .word solaris_unimplemented /* setegid 136 */
167 .word solaris_sysconf /* sysconfig d 137 */
168 .word solaris_unimplemented /* adjtime 138 */
169 .word solaris_sysinfo /* systeminfo dsd 139 */
170 .word solaris_unimplemented /* ? 140 */
171 .word solaris_unimplemented /* seteuid 141 */
172 .word solaris_unimplemented /* ? 142 */
173 .word solaris_unimplemented /* ? 143 */
174 .word solaris_unimplemented /* secsys dx 144 */
175 .word solaris_unimplemented /* filepriv sdxd 145 */
176 .word solaris_unimplemented /* procpriv dxd 146 */
177 .word solaris_unimplemented /* devstat sdx 147 */
178 .word solaris_unimplemented /* aclipc ddddx 148 */
179 .word solaris_unimplemented /* fdevstat ddx 149 */
180 .word solaris_unimplemented /* flvlfile ddx 150 */
181 .word solaris_unimplemented /* lvlfile sdx 151 */
182 .word solaris_unimplemented /* ? 152 */
183 .word solaris_unimplemented /* fchroot d 153 */
184 .word solaris_unimplemented /* lvlproc dx 154 */
185 .word solaris_unimplemented /* ? 155 */
186 .word solaris_gettimeofday /* gettimeofday x 156 */
187 .word CHAIN(getitimer) /* getitimer dx 157 */
188 .word CHAIN(setitimer) /* setitimer dxx 158 */
189 .word solaris_unimplemented /* lwp-xxx 159 */
190 .word solaris_unimplemented /* lwp-xxx 160 */
191 .word solaris_unimplemented /* lwp-xxx 161 */
192 .word solaris_unimplemented /* lwp-xxx 162 */
193 .word solaris_unimplemented /* lwp-xxx 163 */
194 .word solaris_unimplemented /* lwp-xxx 164 */
195 .word solaris_unimplemented /* lwp-xxx 165 */
196 .word solaris_unimplemented /* lwp-xxx 166 */
197 .word solaris_unimplemented /* lwp-xxx 167 */
198 .word solaris_unimplemented /* lwp-xxx 168 */
199 .word solaris_unimplemented /* lwp-xxx 169 */
200 .word solaris_unimplemented /* lwp-xxx 170 */
201 .word solaris_unimplemented /* lwp-xxx 171 */
202 .word solaris_unimplemented /* lwp-xxx 172 */
203 .word solaris_pread /* pread dpdd 173 */
204 .word solaris_pwrite /* pwrite dpdd 174 */
205 .word REGS(solaris_llseek) /* llseek dLd 175 */
206 .word solaris_unimplemented /* lwpself 176 */
207 .word solaris_unimplemented /* lwpinfo 177 */
208 .word solaris_unimplemented /* lwpprivate 178 */
209 .word solaris_unimplemented /* processorbind 179 */
210 .word solaris_unimplemented /* processorexbind 180 */
211 .word solaris_unimplemented /* 181 */
212 .word solaris_unimplemented /* sync_mailbox 182 */
213 .word solaris_unimplemented /* prepblock 183 */
214 .word solaris_unimplemented /* block 184 */
215 .word solaris_acl /* acl sddp 185 */
216 .word solaris_unimplemented /* unblock 186 */
217 .word solaris_unimplemented /* cancelblock 187 */
218 .word solaris_unimplemented /* ? 188 */
219 .word solaris_unimplemented /* xxxxx 189 */
220 .word solaris_unimplemented /* xxxxxe 190 */
221 .word solaris_unimplemented /* 191 */
222 .word solaris_unimplemented /* 192 */
223 .word solaris_unimplemented /* 193 */
224 .word solaris_unimplemented /* 194 */
225 .word solaris_unimplemented /* 195 */
226 .word solaris_unimplemented /* 196 */
227 .word solaris_unimplemented /* 197 */
228 .word solaris_unimplemented /* 198 */
229 .word CHAIN(nanosleep) /* nanosleep dd 199 */
230 .word solaris_facl /* facl dddp 200 */
231 .word solaris_unimplemented /* 201 */
232 .word CHAIN(setreuid) /* setreuid dd 202 */
233 .word CHAIN(setregid) /* setregid dd 203 */
234 .word solaris_unimplemented /* 204 */
235 .word solaris_unimplemented /* 205 */
236 .word solaris_unimplemented /* 206 */
237 .word solaris_unimplemented /* 207 */
238 .word solaris_unimplemented /* 208 */
239 .word solaris_unimplemented /* 209 */
240 .word solaris_unimplemented /* 210 */
241 .word solaris_unimplemented /* 211 */
242 .word solaris_unimplemented /* 212 */
243 .word solaris_getdents64 /* getdents64 dpd 213 */
244 .word REGS(solaris_mmap64) /* mmap64 xxxxdX 214 */
245 .word solaris_stat64 /* stat64 sP 215 */
246 .word solaris_lstat64 /* lstat64 sP 216 */
247 .word solaris_fstat64 /* fstat64 dP 217 */
248 .word solaris_statvfs64 /* statvfs64 sP 218 */
249 .word solaris_fstatvfs64 /* fstatvfs64 dP 219 */
250 .word solaris_setrlimit64 /* setrlimit64 dP 220 */
251 .word solaris_getrlimit64 /* getrlimit64 dP 221 */
252 .word CHAIN(pread64) /* pread64 dpdD 222 */
253 .word CHAIN(pwrite64) /* pwrite64 dpdD 223 */
254 .word CHAIN(creat) /* creat64 so 224 */
255 .word solaris_open /* open64 soo 225 */
256 .word solaris_unimplemented /* 226 */
257 .word solaris_unimplemented /* 227 */
258 .word solaris_unimplemented /* 228 */
259 .word solaris_unimplemented /* 229 */
260 .word solaris_socket /* socket ddd 230 */
261 .word solaris_socketpair /* socketpair dddp 231 */
262 .word solaris_bind /* bind dpd 232 */
263 .word solaris_listen /* listen dd 233 */
264 .word solaris_accept /* accept dpp 234 */
265 .word solaris_connect /* connect dpd 235 */
266 .word solaris_shutdown /* shutdown dd 236 */
267 .word solaris_recv /* recv dpdd 237 */
268 .word solaris_recvfrom /* recvfrom dpddpp 238 */
269 .word solaris_recvmsg /* recvmsg dpd 239 */
270 .word solaris_send /* send dpdd 240 */
271 .word solaris_sendmsg /* sendmsg dpd 241 */
272 .word solaris_sendto /* sendto dpddpd 242 */
273 .word solaris_getpeername /* getpeername dpp 243 */
274 .word solaris_getsockname /* getsockname dpp 244 */
275 .word solaris_getsockopt /* getsockopt dddpp 245 */
276 .word solaris_setsockopt /* setsockopt dddpp 246 */
277 .word solaris_unimplemented /* 247 */
278 .word solaris_ntp_gettime /* ntp_gettime p 248 */
279 .word solaris_ntp_adjtime /* ntp_adjtime p 249 */
280 .word solaris_unimplemented /* 250 */
281 .word solaris_unimplemented /* 251 */
282 .word solaris_unimplemented /* 252 */
283 .word solaris_unimplemented /* 253 */
284 .word solaris_unimplemented /* 254 */
285 .word solaris_unimplemented /* 255 */
diff --git a/arch/sparc64/solaris/timod.c b/arch/sparc64/solaris/timod.c
deleted file mode 100644
index 15234fcd191a..000000000000
--- a/arch/sparc64/solaris/timod.c
+++ /dev/null
@@ -1,976 +0,0 @@
1/* $Id: timod.c,v 1.19 2002/02/08 03:57:14 davem Exp $
2 * timod.c: timod emulation.
3 *
4 * Copyright (C) 1998 Patrik Rak (prak3264@ss1000.ms.mff.cuni.cz)
5 *
6 * Streams & timod emulation based on code
7 * Copyright (C) 1995, 1996 Mike Jagdis (jaggy@purplet.demon.co.uk)
8 *
9 */
10
11#include <linux/types.h>
12#include <linux/kernel.h>
13#include <linux/sched.h>
14#include <linux/smp.h>
15#include <linux/smp_lock.h>
16#include <linux/ioctl.h>
17#include <linux/fs.h>
18#include <linux/file.h>
19#include <linux/netdevice.h>
20#include <linux/poll.h>
21
22#include <net/sock.h>
23
24#include <asm/uaccess.h>
25#include <asm/termios.h>
26
27#include "conv.h"
28#include "socksys.h"
29
30asmlinkage int solaris_ioctl(unsigned int fd, unsigned int cmd, u32 arg);
31
32static DEFINE_SPINLOCK(timod_pagelock);
33static char * page = NULL ;
34
35#ifndef DEBUG_SOLARIS_KMALLOC
36
37#define mykmalloc kmalloc
38#define mykfree kfree
39
40#else
41
42void * mykmalloc(size_t s, gfp_t gfp)
43{
44 static char * page;
45 static size_t free;
46 void * r;
47 s = ((s + 63) & ~63);
48 if( s > PAGE_SIZE ) {
49 SOLD("too big size, calling real kmalloc");
50 return kmalloc(s, gfp);
51 }
52 if( s > free ) {
53 /* we are wasting memory, but we don't care */
54 page = (char *)__get_free_page(gfp);
55 free = PAGE_SIZE;
56 }
57 r = page;
58 page += s;
59 free -= s;
60 return r;
61}
62
63void mykfree(void *p)
64{
65}
66
67#endif
68
69#ifndef DEBUG_SOLARIS
70
71#define BUF_SIZE PAGE_SIZE
72#define PUT_MAGIC(a,m)
73#define SCHECK_MAGIC(a,m)
74#define BUF_OFFSET 0
75#define MKCTL_TRAILER 0
76
77#else
78
79#define BUF_SIZE (PAGE_SIZE-2*sizeof(u64))
80#define BUFPAGE_MAGIC 0xBADC0DEDDEADBABEL
81#define MKCTL_MAGIC 0xDEADBABEBADC0DEDL
82#define PUT_MAGIC(a,m) do{(*(u64*)(a))=(m);}while(0)
83#define SCHECK_MAGIC(a,m) do{if((*(u64*)(a))!=(m))printk("%s,%u,%s(): magic %08x at %p corrupted!\n",\
84 __FILE__,__LINE__,__func__,(m),(a));}while(0)
85#define BUF_OFFSET sizeof(u64)
86#define MKCTL_TRAILER sizeof(u64)
87
88#endif
89
90static char *getpage( void )
91{
92 char *r;
93 SOLD("getting page");
94 spin_lock(&timod_pagelock);
95 if (page) {
96 r = page;
97 page = NULL;
98 spin_unlock(&timod_pagelock);
99 SOLD("got cached");
100 return r + BUF_OFFSET;
101 }
102 spin_unlock(&timod_pagelock);
103 SOLD("getting new");
104 r = (char *)__get_free_page(GFP_KERNEL);
105 PUT_MAGIC(r,BUFPAGE_MAGIC);
106 PUT_MAGIC(r+PAGE_SIZE-sizeof(u64),BUFPAGE_MAGIC);
107 return r + BUF_OFFSET;
108}
109
110static void putpage(char *p)
111{
112 SOLD("putting page");
113 p = p - BUF_OFFSET;
114 SCHECK_MAGIC(p,BUFPAGE_MAGIC);
115 SCHECK_MAGIC(p+PAGE_SIZE-sizeof(u64),BUFPAGE_MAGIC);
116 spin_lock(&timod_pagelock);
117 if (page) {
118 spin_unlock(&timod_pagelock);
119 free_page((unsigned long)p);
120 SOLD("freed it");
121 } else {
122 page = p;
123 spin_unlock(&timod_pagelock);
124 SOLD("cached it");
125 }
126}
127
128static struct T_primsg *timod_mkctl(int size)
129{
130 struct T_primsg *it;
131
132 SOLD("creating primsg");
133 it = (struct T_primsg *)mykmalloc(size+sizeof(*it)-sizeof(s32)+2*MKCTL_TRAILER, GFP_KERNEL);
134 if (it) {
135 SOLD("got it");
136 it->pri = MSG_HIPRI;
137 it->length = size;
138 PUT_MAGIC((char*)((u64)(((char *)&it->type)+size+7)&~7),MKCTL_MAGIC);
139 }
140 return it;
141}
142
143static void timod_wake_socket(unsigned int fd)
144{
145 struct socket *sock;
146 struct fdtable *fdt;
147
148 SOLD("wakeing socket");
149 fdt = files_fdtable(current->files);
150 sock = SOCKET_I(fdt->fd[fd]->f_path.dentry->d_inode);
151 wake_up_interruptible(&sock->wait);
152 read_lock(&sock->sk->sk_callback_lock);
153 if (sock->fasync_list && !test_bit(SOCK_ASYNC_WAITDATA, &sock->flags))
154 __kill_fasync(sock->fasync_list, SIGIO, POLL_IN);
155 read_unlock(&sock->sk->sk_callback_lock);
156 SOLD("done");
157}
158
159static void timod_queue(unsigned int fd, struct T_primsg *it)
160{
161 struct sol_socket_struct *sock;
162 struct fdtable *fdt;
163
164 SOLD("queuing primsg");
165 fdt = files_fdtable(current->files);
166 sock = (struct sol_socket_struct *)fdt->fd[fd]->private_data;
167 it->next = sock->pfirst;
168 sock->pfirst = it;
169 if (!sock->plast)
170 sock->plast = it;
171 timod_wake_socket(fd);
172 SOLD("done");
173}
174
175static void timod_queue_end(unsigned int fd, struct T_primsg *it)
176{
177 struct sol_socket_struct *sock;
178 struct fdtable *fdt;
179
180 SOLD("queuing primsg at end");
181 fdt = files_fdtable(current->files);
182 sock = (struct sol_socket_struct *)fdt->fd[fd]->private_data;
183 it->next = NULL;
184 if (sock->plast)
185 sock->plast->next = it;
186 else
187 sock->pfirst = it;
188 sock->plast = it;
189 SOLD("done");
190}
191
192static void timod_error(unsigned int fd, int prim, int terr, int uerr)
193{
194 struct T_primsg *it;
195
196 SOLD("making error");
197 it = timod_mkctl(sizeof(struct T_error_ack));
198 if (it) {
199 struct T_error_ack *err = (struct T_error_ack *)&it->type;
200
201 SOLD("got it");
202 err->PRIM_type = T_ERROR_ACK;
203 err->ERROR_prim = prim;
204 err->TLI_error = terr;
205 err->UNIX_error = uerr; /* FIXME: convert this */
206 timod_queue(fd, it);
207 }
208 SOLD("done");
209}
210
211static void timod_ok(unsigned int fd, int prim)
212{
213 struct T_primsg *it;
214 struct T_ok_ack *ok;
215
216 SOLD("creating ok ack");
217 it = timod_mkctl(sizeof(*ok));
218 if (it) {
219 SOLD("got it");
220 ok = (struct T_ok_ack *)&it->type;
221 ok->PRIM_type = T_OK_ACK;
222 ok->CORRECT_prim = prim;
223 timod_queue(fd, it);
224 }
225 SOLD("done");
226}
227
228static int timod_optmgmt(unsigned int fd, int flag, char __user *opt_buf, int opt_len, int do_ret)
229{
230 int error, failed;
231 int ret_space, ret_len;
232 long args[5];
233 char *ret_pos,*ret_buf;
234 int (*sys_socketcall)(int, unsigned long *) =
235 (int (*)(int, unsigned long *))SYS(socketcall);
236 mm_segment_t old_fs = get_fs();
237
238 SOLD("entry");
239 SOLDD(("fd %u flg %u buf %p len %u doret %u",fd,flag,opt_buf,opt_len,do_ret));
240 if (!do_ret && (!opt_buf || opt_len <= 0))
241 return 0;
242 SOLD("getting page");
243 ret_pos = ret_buf = getpage();
244 ret_space = BUF_SIZE;
245 ret_len = 0;
246
247 error = failed = 0;
248 SOLD("looping");
249 while(opt_len >= sizeof(struct opthdr)) {
250 struct opthdr *opt;
251 int orig_opt_len;
252 SOLD("loop start");
253 opt = (struct opthdr *)ret_pos;
254 if (ret_space < sizeof(struct opthdr)) {
255 failed = TSYSERR;
256 break;
257 }
258 SOLD("getting opthdr");
259 if (copy_from_user(opt, opt_buf, sizeof(struct opthdr)) ||
260 opt->len > opt_len) {
261 failed = TBADOPT;
262 break;
263 }
264 SOLD("got opthdr");
265 if (flag == T_NEGOTIATE) {
266 char *buf;
267
268 SOLD("handling T_NEGOTIATE");
269 buf = ret_pos + sizeof(struct opthdr);
270 if (ret_space < opt->len + sizeof(struct opthdr) ||
271 copy_from_user(buf, opt_buf+sizeof(struct opthdr), opt->len)) {
272 failed = TSYSERR;
273 break;
274 }
275 SOLD("got optdata");
276 args[0] = fd;
277 args[1] = opt->level;
278 args[2] = opt->name;
279 args[3] = (long)buf;
280 args[4] = opt->len;
281 SOLD("calling SETSOCKOPT");
282 set_fs(KERNEL_DS);
283 error = sys_socketcall(SYS_SETSOCKOPT, args);
284 set_fs(old_fs);
285 if (error) {
286 failed = TBADOPT;
287 break;
288 }
289 SOLD("SETSOCKOPT ok");
290 }
291 orig_opt_len = opt->len;
292 opt->len = ret_space - sizeof(struct opthdr);
293 if (opt->len < 0) {
294 failed = TSYSERR;
295 break;
296 }
297 args[0] = fd;
298 args[1] = opt->level;
299 args[2] = opt->name;
300 args[3] = (long)(ret_pos+sizeof(struct opthdr));
301 args[4] = (long)&opt->len;
302 SOLD("calling GETSOCKOPT");
303 set_fs(KERNEL_DS);
304 error = sys_socketcall(SYS_GETSOCKOPT, args);
305 set_fs(old_fs);
306 if (error) {
307 failed = TBADOPT;
308 break;
309 }
310 SOLD("GETSOCKOPT ok");
311 ret_space -= sizeof(struct opthdr) + opt->len;
312 ret_len += sizeof(struct opthdr) + opt->len;
313 ret_pos += sizeof(struct opthdr) + opt->len;
314 opt_len -= sizeof(struct opthdr) + orig_opt_len;
315 opt_buf += sizeof(struct opthdr) + orig_opt_len;
316 SOLD("loop end");
317 }
318 SOLD("loop done");
319 if (do_ret) {
320 SOLD("generating ret msg");
321 if (failed)
322 timod_error(fd, T_OPTMGMT_REQ, failed, -error);
323 else {
324 struct T_primsg *it;
325 it = timod_mkctl(sizeof(struct T_optmgmt_ack) + ret_len);
326 if (it) {
327 struct T_optmgmt_ack *ack =
328 (struct T_optmgmt_ack *)&it->type;
329 SOLD("got primsg");
330 ack->PRIM_type = T_OPTMGMT_ACK;
331 ack->OPT_length = ret_len;
332 ack->OPT_offset = sizeof(struct T_optmgmt_ack);
333 ack->MGMT_flags = (failed ? T_FAILURE : flag);
334 memcpy(((char*)ack)+sizeof(struct T_optmgmt_ack),
335 ret_buf, ret_len);
336 timod_queue(fd, it);
337 }
338 }
339 }
340 SOLDD(("put_page %p\n", ret_buf));
341 putpage(ret_buf);
342 SOLD("done");
343 return 0;
344}
345
346int timod_putmsg(unsigned int fd, char __user *ctl_buf, int ctl_len,
347 char __user *data_buf, int data_len, int flags)
348{
349 int ret, error, terror;
350 char *buf;
351 struct file *filp;
352 struct inode *ino;
353 struct fdtable *fdt;
354 struct sol_socket_struct *sock;
355 mm_segment_t old_fs = get_fs();
356 long args[6];
357 int (*sys_socketcall)(int, unsigned long __user *) =
358 (int (*)(int, unsigned long __user *))SYS(socketcall);
359 int (*sys_sendto)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int) =
360 (int (*)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int))SYS(sendto);
361
362 fdt = files_fdtable(current->files);
363 filp = fdt->fd[fd];
364 ino = filp->f_path.dentry->d_inode;
365 sock = (struct sol_socket_struct *)filp->private_data;
366 SOLD("entry");
367 if (get_user(ret, (int __user *)A(ctl_buf)))
368 return -EFAULT;
369 switch (ret) {
370 case T_BIND_REQ:
371 {
372 struct T_bind_req req;
373
374 SOLDD(("bind %016lx(%016lx)\n", sock, filp));
375 SOLD("T_BIND_REQ");
376 if (sock->state != TS_UNBND) {
377 timod_error(fd, T_BIND_REQ, TOUTSTATE, 0);
378 return 0;
379 }
380 SOLD("state ok");
381 if (copy_from_user(&req, ctl_buf, sizeof(req))) {
382 timod_error(fd, T_BIND_REQ, TSYSERR, EFAULT);
383 return 0;
384 }
385 SOLD("got ctl req");
386 if (req.ADDR_offset && req.ADDR_length) {
387 if (req.ADDR_length > BUF_SIZE) {
388 timod_error(fd, T_BIND_REQ, TSYSERR, EFAULT);
389 return 0;
390 }
391 SOLD("req size ok");
392 buf = getpage();
393 if (copy_from_user(buf, ctl_buf + req.ADDR_offset, req.ADDR_length)) {
394 timod_error(fd, T_BIND_REQ, TSYSERR, EFAULT);
395 putpage(buf);
396 return 0;
397 }
398 SOLD("got ctl data");
399 args[0] = fd;
400 args[1] = (long)buf;
401 args[2] = req.ADDR_length;
402 SOLD("calling BIND");
403 set_fs(KERNEL_DS);
404 error = sys_socketcall(SYS_BIND, args);
405 set_fs(old_fs);
406 putpage(buf);
407 SOLD("BIND returned");
408 } else
409 error = 0;
410 if (!error) {
411 struct T_primsg *it;
412 if (req.CONIND_number) {
413 args[0] = fd;
414 args[1] = req.CONIND_number;
415 SOLD("calling LISTEN");
416 set_fs(KERNEL_DS);
417 error = sys_socketcall(SYS_LISTEN, args);
418 set_fs(old_fs);
419 SOLD("LISTEN done");
420 }
421 it = timod_mkctl(sizeof(struct T_bind_ack)+sizeof(struct sockaddr));
422 if (it) {
423 struct T_bind_ack *ack;
424
425 ack = (struct T_bind_ack *)&it->type;
426 ack->PRIM_type = T_BIND_ACK;
427 ack->ADDR_offset = sizeof(*ack);
428 ack->ADDR_length = sizeof(struct sockaddr);
429 ack->CONIND_number = req.CONIND_number;
430 args[0] = fd;
431 args[1] = (long)(ack+sizeof(*ack));
432 args[2] = (long)&ack->ADDR_length;
433 set_fs(KERNEL_DS);
434 sys_socketcall(SYS_GETSOCKNAME,args);
435 set_fs(old_fs);
436 sock->state = TS_IDLE;
437 timod_ok(fd, T_BIND_REQ);
438 timod_queue_end(fd, it);
439 SOLD("BIND done");
440 return 0;
441 }
442 }
443 SOLD("some error");
444 switch (error) {
445 case -EINVAL:
446 terror = TOUTSTATE;
447 error = 0;
448 break;
449 case -EACCES:
450 terror = TACCES;
451 error = 0;
452 break;
453 case -EADDRNOTAVAIL:
454 case -EADDRINUSE:
455 terror = TNOADDR;
456 error = 0;
457 break;
458 default:
459 terror = TSYSERR;
460 break;
461 }
462 timod_error(fd, T_BIND_REQ, terror, -error);
463 SOLD("BIND done");
464 return 0;
465 }
466 case T_CONN_REQ:
467 {
468 struct T_conn_req req;
469 unsigned short oldflags;
470 struct T_primsg *it;
471 SOLD("T_CONN_REQ");
472 if (sock->state != TS_UNBND && sock->state != TS_IDLE) {
473 timod_error(fd, T_CONN_REQ, TOUTSTATE, 0);
474 return 0;
475 }
476 SOLD("state ok");
477 if (copy_from_user(&req, ctl_buf, sizeof(req))) {
478 timod_error(fd, T_CONN_REQ, TSYSERR, EFAULT);
479 return 0;
480 }
481 SOLD("got ctl req");
482 if (ctl_len > BUF_SIZE) {
483 timod_error(fd, T_CONN_REQ, TSYSERR, EFAULT);
484 return 0;
485 }
486 SOLD("req size ok");
487 buf = getpage();
488 if (copy_from_user(buf, ctl_buf, ctl_len)) {
489 timod_error(fd, T_CONN_REQ, TSYSERR, EFAULT);
490 putpage(buf);
491 return 0;
492 }
493#ifdef DEBUG_SOLARIS
494 {
495 char * ptr = buf;
496 int len = ctl_len;
497 printk("returned data (%d bytes): ",len);
498 while( len-- ) {
499 if (!(len & 7))
500 printk(" ");
501 printk("%02x",(unsigned char)*ptr++);
502 }
503 printk("\n");
504 }
505#endif
506 SOLD("got ctl data");
507 args[0] = fd;
508 args[1] = (long)buf+req.DEST_offset;
509 args[2] = req.DEST_length;
510 oldflags = filp->f_flags;
511 filp->f_flags &= ~O_NONBLOCK;
512 SOLD("calling CONNECT");
513 set_fs(KERNEL_DS);
514 error = sys_socketcall(SYS_CONNECT, args);
515 set_fs(old_fs);
516 filp->f_flags = oldflags;
517 SOLD("CONNECT done");
518 if (!error) {
519 struct T_conn_con *con;
520 SOLD("no error");
521 it = timod_mkctl(ctl_len);
522 if (!it) {
523 putpage(buf);
524 return -ENOMEM;
525 }
526 con = (struct T_conn_con *)&it->type;
527#ifdef DEBUG_SOLARIS
528 {
529 char * ptr = buf;
530 int len = ctl_len;
531 printk("returned data (%d bytes): ",len);
532 while( len-- ) {
533 if (!(len & 7))
534 printk(" ");
535 printk("%02x",(unsigned char)*ptr++);
536 }
537 printk("\n");
538 }
539#endif
540 memcpy(con, buf, ctl_len);
541 SOLD("copied ctl_buf");
542 con->PRIM_type = T_CONN_CON;
543 sock->state = TS_DATA_XFER;
544 } else {
545 struct T_discon_ind *dis;
546 SOLD("some error");
547 it = timod_mkctl(sizeof(*dis));
548 if (!it) {
549 putpage(buf);
550 return -ENOMEM;
551 }
552 SOLD("got primsg");
553 dis = (struct T_discon_ind *)&it->type;
554 dis->PRIM_type = T_DISCON_IND;
555 dis->DISCON_reason = -error; /* FIXME: convert this as in iABI_errors() */
556 dis->SEQ_number = 0;
557 }
558 putpage(buf);
559 timod_ok(fd, T_CONN_REQ);
560 it->pri = 0;
561 timod_queue_end(fd, it);
562 SOLD("CONNECT done");
563 return 0;
564 }
565 case T_OPTMGMT_REQ:
566 {
567 struct T_optmgmt_req req;
568 SOLD("OPTMGMT_REQ");
569 if (copy_from_user(&req, ctl_buf, sizeof(req)))
570 return -EFAULT;
571 SOLD("got req");
572 return timod_optmgmt(fd, req.MGMT_flags,
573 req.OPT_offset > 0 ? ctl_buf + req.OPT_offset : NULL,
574 req.OPT_length, 1);
575 }
576 case T_UNITDATA_REQ:
577 {
578 struct T_unitdata_req req;
579
580 int err;
581 SOLD("T_UNITDATA_REQ");
582 if (sock->state != TS_IDLE && sock->state != TS_DATA_XFER) {
583 timod_error(fd, T_CONN_REQ, TOUTSTATE, 0);
584 return 0;
585 }
586 SOLD("state ok");
587 if (copy_from_user(&req, ctl_buf, sizeof(req))) {
588 timod_error(fd, T_CONN_REQ, TSYSERR, EFAULT);
589 return 0;
590 }
591 SOLD("got ctl req");
592#ifdef DEBUG_SOLARIS
593 {
594 char * ptr = ctl_buf+req.DEST_offset;
595 int len = req.DEST_length;
596 printk("socket address (%d bytes): ",len);
597 while( len-- ) {
598 char c;
599 if (get_user(c,ptr))
600 printk("??");
601 else
602 printk("%02x",(unsigned char)c);
603 ptr++;
604 }
605 printk("\n");
606 }
607#endif
608 err = sys_sendto(fd, data_buf, data_len, 0, req.DEST_length > 0 ? (struct sockaddr __user *)(ctl_buf+req.DEST_offset) : NULL, req.DEST_length);
609 if (err == data_len)
610 return 0;
611 if(err >= 0) {
612 printk("timod: sendto failed to send all the data\n");
613 return 0;
614 }
615 timod_error(fd, T_CONN_REQ, TSYSERR, -err);
616 return 0;
617 }
618 default:
619 printk(KERN_INFO "timod_putmsg: unsupported command %u.\n", ret);
620 break;
621 }
622 return -EINVAL;
623}
624
625int timod_getmsg(unsigned int fd, char __user *ctl_buf, int ctl_maxlen, s32 __user *ctl_len,
626 char __user *data_buf, int data_maxlen, s32 __user *data_len, int *flags_p)
627{
628 int error;
629 int oldflags;
630 struct file *filp;
631 struct inode *ino;
632 struct fdtable *fdt;
633 struct sol_socket_struct *sock;
634 struct T_unitdata_ind udi;
635 mm_segment_t old_fs = get_fs();
636 long args[6];
637 char __user *tmpbuf;
638 int tmplen;
639 int (*sys_socketcall)(int, unsigned long __user *) =
640 (int (*)(int, unsigned long __user *))SYS(socketcall);
641 int (*sys_recvfrom)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *);
642
643 SOLD("entry");
644 SOLDD(("%u %p %d %p %p %d %p %d\n", fd, ctl_buf, ctl_maxlen, ctl_len, data_buf, data_maxlen, data_len, *flags_p));
645 fdt = files_fdtable(current->files);
646 filp = fdt->fd[fd];
647 ino = filp->f_path.dentry->d_inode;
648 sock = (struct sol_socket_struct *)filp->private_data;
649 SOLDD(("%p %p\n", sock->pfirst, sock->pfirst ? sock->pfirst->next : NULL));
650 if ( ctl_maxlen > 0 && !sock->pfirst && SOCKET_I(ino)->type == SOCK_STREAM
651 && sock->state == TS_IDLE) {
652 SOLD("calling LISTEN");
653 args[0] = fd;
654 args[1] = -1;
655 set_fs(KERNEL_DS);
656 sys_socketcall(SYS_LISTEN, args);
657 set_fs(old_fs);
658 SOLD("LISTEN done");
659 }
660 if (!(filp->f_flags & O_NONBLOCK)) {
661 struct poll_wqueues wait_table;
662 poll_table *wait;
663
664 poll_initwait(&wait_table);
665 wait = &wait_table.pt;
666 for(;;) {
667 SOLD("loop");
668 set_current_state(TASK_INTERRUPTIBLE);
669 /* ! ( l<0 || ( l>=0 && ( ! pfirst || (flags == HIPRI && pri != HIPRI) ) ) ) */
670 /* ( ! l<0 && ! ( l>=0 && ( ! pfirst || (flags == HIPRI && pri != HIPRI) ) ) ) */
671 /* ( l>=0 && ( ! l>=0 || ! ( ! pfirst || (flags == HIPRI && pri != HIPRI) ) ) ) */
672 /* ( l>=0 && ( l<0 || ( pfirst && ! (flags == HIPRI && pri != HIPRI) ) ) ) */
673 /* ( l>=0 && ( l<0 || ( pfirst && (flags != HIPRI || pri == HIPRI) ) ) ) */
674 /* ( l>=0 && ( pfirst && (flags != HIPRI || pri == HIPRI) ) ) */
675 if (ctl_maxlen >= 0 && sock->pfirst && (*flags_p != MSG_HIPRI || sock->pfirst->pri == MSG_HIPRI))
676 break;
677 SOLD("cond 1 passed");
678 if (
679 #if 1
680 *flags_p != MSG_HIPRI &&
681 #endif
682 ((filp->f_op->poll(filp, wait) & POLLIN) ||
683 (filp->f_op->poll(filp, NULL) & POLLIN) ||
684 signal_pending(current))
685 ) {
686 break;
687 }
688 if( *flags_p == MSG_HIPRI ) {
689 SOLD("avoiding lockup");
690 break ;
691 }
692 if(wait_table.error) {
693 SOLD("wait-table error");
694 poll_freewait(&wait_table);
695 return wait_table.error;
696 }
697 SOLD("scheduling");
698 schedule();
699 }
700 SOLD("loop done");
701 current->state = TASK_RUNNING;
702 poll_freewait(&wait_table);
703 if (signal_pending(current)) {
704 SOLD("signal pending");
705 return -EINTR;
706 }
707 }
708 if (ctl_maxlen >= 0 && sock->pfirst) {
709 struct T_primsg *it = sock->pfirst;
710 int l = min_t(int, ctl_maxlen, it->length);
711 SCHECK_MAGIC((char*)((u64)(((char *)&it->type)+sock->offset+it->length+7)&~7),MKCTL_MAGIC);
712 SOLD("purting ctl data");
713 if(copy_to_user(ctl_buf,
714 (char*)&it->type + sock->offset, l))
715 return -EFAULT;
716 SOLD("pur it");
717 if(put_user(l, ctl_len))
718 return -EFAULT;
719 SOLD("set ctl_len");
720 *flags_p = it->pri;
721 it->length -= l;
722 if (it->length) {
723 SOLD("more ctl");
724 sock->offset += l;
725 return MORECTL;
726 } else {
727 SOLD("removing message");
728 sock->pfirst = it->next;
729 if (!sock->pfirst)
730 sock->plast = NULL;
731 SOLDD(("getmsg kfree %016lx->%016lx\n", it, sock->pfirst));
732 mykfree(it);
733 sock->offset = 0;
734 SOLD("ctl done");
735 return 0;
736 }
737 }
738 *flags_p = 0;
739 if (ctl_maxlen >= 0) {
740 SOLD("ACCEPT perhaps?");
741 if (SOCKET_I(ino)->type == SOCK_STREAM && sock->state == TS_IDLE) {
742 struct T_conn_ind ind;
743 char *buf = getpage();
744 int len = BUF_SIZE;
745
746 SOLD("trying ACCEPT");
747 if (put_user(ctl_maxlen - sizeof(ind), ctl_len))
748 return -EFAULT;
749 args[0] = fd;
750 args[1] = (long)buf;
751 args[2] = (long)&len;
752 oldflags = filp->f_flags;
753 filp->f_flags |= O_NONBLOCK;
754 SOLD("calling ACCEPT");
755 set_fs(KERNEL_DS);
756 error = sys_socketcall(SYS_ACCEPT, args);
757 set_fs(old_fs);
758 filp->f_flags = oldflags;
759 if (error < 0) {
760 SOLD("some error");
761 putpage(buf);
762 return error;
763 }
764 if (error) {
765 SOLD("connect");
766 putpage(buf);
767 if (sizeof(ind) > ctl_maxlen) {
768 SOLD("generating CONN_IND");
769 ind.PRIM_type = T_CONN_IND;
770 ind.SRC_length = len;
771 ind.SRC_offset = sizeof(ind);
772 ind.OPT_length = ind.OPT_offset = 0;
773 ind.SEQ_number = error;
774 if(copy_to_user(ctl_buf, &ind, sizeof(ind))||
775 put_user(sizeof(ind)+ind.SRC_length,ctl_len))
776 return -EFAULT;
777 SOLD("CONN_IND created");
778 }
779 if (data_maxlen >= 0)
780 put_user(0, data_len);
781 SOLD("CONN_IND done");
782 return 0;
783 }
784 if (len>ctl_maxlen) {
785 SOLD("data don't fit");
786 putpage(buf);
787 return -EFAULT; /* XXX - is this ok ? */
788 }
789 if(copy_to_user(ctl_buf,buf,len) || put_user(len,ctl_len)){
790 SOLD("can't copy data");
791 putpage(buf);
792 return -EFAULT;
793 }
794 SOLD("ACCEPT done");
795 putpage(buf);
796 }
797 }
798 SOLD("checking data req");
799 if (data_maxlen <= 0) {
800 if (data_maxlen == 0)
801 put_user(0, data_len);
802 if (ctl_maxlen >= 0)
803 put_user(0, ctl_len);
804 return -EAGAIN;
805 }
806 SOLD("wants data");
807 if (ctl_maxlen > sizeof(udi) && sock->state == TS_IDLE) {
808 SOLD("udi fits");
809 tmpbuf = ctl_buf + sizeof(udi);
810 tmplen = ctl_maxlen - sizeof(udi);
811 } else {
812 SOLD("udi does not fit");
813 tmpbuf = NULL;
814 tmplen = 0;
815 }
816 if (put_user(tmplen, ctl_len))
817 return -EFAULT;
818 SOLD("set ctl_len");
819 oldflags = filp->f_flags;
820 filp->f_flags |= O_NONBLOCK;
821 SOLD("calling recvfrom");
822 sys_recvfrom = (int (*)(int, void __user *, size_t, unsigned, struct sockaddr __user *, int __user *))SYS(recvfrom);
823 error = sys_recvfrom(fd, data_buf, data_maxlen, 0, (struct sockaddr __user *)tmpbuf, ctl_len);
824 filp->f_flags = oldflags;
825 if (error < 0)
826 return error;
827 SOLD("error >= 0" ) ;
828 if (error && ctl_maxlen > sizeof(udi) && sock->state == TS_IDLE) {
829 SOLD("generating udi");
830 udi.PRIM_type = T_UNITDATA_IND;
831 if (get_user(udi.SRC_length, ctl_len))
832 return -EFAULT;
833 udi.SRC_offset = sizeof(udi);
834 udi.OPT_length = udi.OPT_offset = 0;
835 if (copy_to_user(ctl_buf, &udi, sizeof(udi)) ||
836 put_user(sizeof(udi)+udi.SRC_length, ctl_len))
837 return -EFAULT;
838 SOLD("udi done");
839 } else {
840 if (put_user(0, ctl_len))
841 return -EFAULT;
842 }
843 put_user(error, data_len);
844 SOLD("done");
845 return 0;
846}
847
848asmlinkage int solaris_getmsg(unsigned int fd, u32 arg1, u32 arg2, u32 arg3)
849{
850 struct file *filp;
851 struct inode *ino;
852 struct strbuf __user *ctlptr;
853 struct strbuf __user *datptr;
854 struct strbuf ctl, dat;
855 int __user *flgptr;
856 int flags;
857 int error = -EBADF;
858 struct fdtable *fdt;
859
860 SOLD("entry");
861 lock_kernel();
862 if (fd >= sysctl_nr_open)
863 goto out;
864
865 fdt = files_fdtable(current->files);
866 filp = fdt->fd[fd];
867 if(!filp) goto out;
868
869 ino = filp->f_path.dentry->d_inode;
870 if (!ino || !S_ISSOCK(ino->i_mode))
871 goto out;
872
873 ctlptr = (struct strbuf __user *)A(arg1);
874 datptr = (struct strbuf __user *)A(arg2);
875 flgptr = (int __user *)A(arg3);
876
877 error = -EFAULT;
878
879 if (ctlptr) {
880 if (copy_from_user(&ctl,ctlptr,sizeof(struct strbuf)) ||
881 put_user(-1,&ctlptr->len))
882 goto out;
883 } else
884 ctl.maxlen = -1;
885
886 if (datptr) {
887 if (copy_from_user(&dat,datptr,sizeof(struct strbuf)) ||
888 put_user(-1,&datptr->len))
889 goto out;
890 } else
891 dat.maxlen = -1;
892
893 if (get_user(flags,flgptr))
894 goto out;
895
896 switch (flags) {
897 case 0:
898 case MSG_HIPRI:
899 case MSG_ANY:
900 case MSG_BAND:
901 break;
902 default:
903 error = -EINVAL;
904 goto out;
905 }
906
907 error = timod_getmsg(fd,A(ctl.buf),ctl.maxlen,&ctlptr->len,
908 A(dat.buf),dat.maxlen,&datptr->len,&flags);
909
910 if (!error && put_user(flags,flgptr))
911 error = -EFAULT;
912out:
913 unlock_kernel();
914 SOLD("done");
915 return error;
916}
917
918asmlinkage int solaris_putmsg(unsigned int fd, u32 arg1, u32 arg2, u32 arg3)
919{
920 struct file *filp;
921 struct inode *ino;
922 struct strbuf __user *ctlptr;
923 struct strbuf __user *datptr;
924 struct strbuf ctl, dat;
925 int flags = (int) arg3;
926 int error = -EBADF;
927 struct fdtable *fdt;
928
929 SOLD("entry");
930 lock_kernel();
931 if (fd >= sysctl_nr_open)
932 goto out;
933
934 fdt = files_fdtable(current->files);
935 filp = fdt->fd[fd];
936 if(!filp) goto out;
937
938 ino = filp->f_path.dentry->d_inode;
939 if (!ino) goto out;
940
941 if (!S_ISSOCK(ino->i_mode) &&
942 (imajor(ino) != 30 || iminor(ino) != 1))
943 goto out;
944
945 ctlptr = A(arg1);
946 datptr = A(arg2);
947
948 error = -EFAULT;
949
950 if (ctlptr) {
951 if (copy_from_user(&ctl,ctlptr,sizeof(ctl)))
952 goto out;
953 if (ctl.len < 0 && flags) {
954 error = -EINVAL;
955 goto out;
956 }
957 } else {
958 ctl.len = 0;
959 ctl.buf = 0;
960 }
961
962 if (datptr) {
963 if (copy_from_user(&dat,datptr,sizeof(dat)))
964 goto out;
965 } else {
966 dat.len = 0;
967 dat.buf = 0;
968 }
969
970 error = timod_putmsg(fd,A(ctl.buf),ctl.len,
971 A(dat.buf),dat.len,flags);
972out:
973 unlock_kernel();
974 SOLD("done");
975 return error;
976}