aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-04-21 20:20:53 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-21 20:20:53 -0400
commit8a3227268877b81096d7b7a841aaf51099ad2068 (patch)
tree73d2b9522aa981d46040b5603c824583c1b18694 /arch/sparc64
parente9b62693ae0a1e13ccc97a6792d9a7770c8d1b5b (diff)
parentec98c6b9b47df6df1c1fa6cf3d427414f8c2cf16 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6: [SPARC]: Remove SunOS and Solaris binary support.
Diffstat (limited to 'arch/sparc64')
-rw-r--r--arch/sparc64/Kconfig47
-rw-r--r--arch/sparc64/Makefile1
-rw-r--r--arch/sparc64/defconfig29
-rw-r--r--arch/sparc64/kernel/Makefile9
-rw-r--r--arch/sparc64/kernel/binfmt_aout32.c419
-rw-r--r--arch/sparc64/kernel/entry.S61
-rw-r--r--arch/sparc64/kernel/signal.c1
-rw-r--r--arch/sparc64/kernel/signal32.c300
-rw-r--r--arch/sparc64/kernel/sparc64_ksyms.c41
-rw-r--r--arch/sparc64/kernel/sunos_ioctl32.c275
-rw-r--r--arch/sparc64/kernel/sys_sparc.c38
-rw-r--r--arch/sparc64/kernel/sys_sunos32.c1359
-rw-r--r--arch/sparc64/kernel/systbls.S122
-rw-r--r--arch/sparc64/kernel/systbls.h2
-rw-r--r--arch/sparc64/kernel/ttable.S14
-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
29 files changed, 37 insertions, 8104 deletions
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index 2667a9dee11d..df3eacb5ca15 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -88,9 +88,6 @@ config GENERIC_HARDIRQS_NO__DO_IRQ
88 bool 88 bool
89 def_bool y 89 def_bool y
90 90
91config ARCH_SUPPORTS_AOUT
92 def_bool y
93
94choice 91choice
95 prompt "Kernel page size" 92 prompt "Kernel page size"
96 default SPARC64_PAGE_SIZE_8KB 93 default SPARC64_PAGE_SIZE_8KB
@@ -148,11 +145,6 @@ config HOTPLUG_CPU
148 145
149source "init/Kconfig" 146source "init/Kconfig"
150 147
151config SYSVIPC_COMPAT
152 bool
153 depends on COMPAT && SYSVIPC
154 default y
155
156config GENERIC_HARDIRQS 148config GENERIC_HARDIRQS
157 bool 149 bool
158 default y 150 default y
@@ -380,6 +372,10 @@ config SUN_OPENPROMFS
380 To compile the /proc/openprom support as a module, choose M here: the 372 To compile the /proc/openprom support as a module, choose M here: the
381 module will be called openpromfs. If unsure, choose M. 373 module will be called openpromfs. If unsure, choose M.
382 374
375menu "Executable file formats"
376
377source "fs/Kconfig.binfmt"
378
383config SPARC32_COMPAT 379config SPARC32_COMPAT
384 bool "Kernel support for Linux/Sparc 32bit binary compatibility" 380 bool "Kernel support for Linux/Sparc 32bit binary compatibility"
385 help 381 help
@@ -392,37 +388,10 @@ config COMPAT
392 default y 388 default y
393 select COMPAT_BINFMT_ELF 389 select COMPAT_BINFMT_ELF
394 390
395config BINFMT_AOUT32 391config SYSVIPC_COMPAT
396 bool "Kernel support for 32-bit (ie. SunOS) a.out binaries" 392 bool
397 depends on SPARC32_COMPAT && ARCH_SUPPORTS_AOUT 393 depends on COMPAT && SYSVIPC
398 help 394 default y
399 This allows you to run 32-bit a.out format binaries on your Ultra.
400 If you want to run SunOS binaries (see SunOS binary emulation below)
401 or other a.out binaries, say Y. If unsure, say N.
402
403menu "Executable file formats"
404
405source "fs/Kconfig.binfmt"
406
407config SUNOS_EMUL
408 bool "SunOS binary emulation"
409 depends on BINFMT_AOUT32
410 help
411 This allows you to run most SunOS binaries. If you want to do this,
412 say Y here and place appropriate files in /usr/gnemul/sunos. See
413 <http://www.ultralinux.org/faq.html> for more information. If you
414 want to run SunOS binaries on an Ultra you must also say Y to
415 "Kernel support for 32-bit a.out binaries" above.
416
417config SOLARIS_EMUL
418 tristate "Solaris binary emulation (EXPERIMENTAL)"
419 depends on SPARC32_COMPAT && NET && EXPERIMENTAL
420 help
421 This is experimental code which will enable you to run (many)
422 Solaris binaries on your SPARC Linux machine.
423
424 To compile this code as a module, choose M here: the
425 module will be called solaris.
426 395
427endmenu 396endmenu
428 397
diff --git a/arch/sparc64/Makefile b/arch/sparc64/Makefile
index f0c22f826982..9cb75c852b45 100644
--- a/arch/sparc64/Makefile
+++ b/arch/sparc64/Makefile
@@ -27,7 +27,6 @@ endif
27head-y := arch/sparc64/kernel/head.o arch/sparc64/kernel/init_task.o 27head-y := arch/sparc64/kernel/head.o arch/sparc64/kernel/init_task.o
28 28
29core-y += arch/sparc64/kernel/ arch/sparc64/mm/ 29core-y += arch/sparc64/kernel/ arch/sparc64/mm/
30core-$(CONFIG_SOLARIS_EMUL) += arch/sparc64/solaris/
31core-y += arch/sparc64/math-emu/ 30core-y += arch/sparc64/math-emu/
32libs-y += arch/sparc64/prom/ arch/sparc64/lib/ 31libs-y += arch/sparc64/prom/ arch/sparc64/lib/
33drivers-$(CONFIG_OPROFILE) += arch/sparc64/oprofile/ 32drivers-$(CONFIG_OPROFILE) += arch/sparc64/oprofile/
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index 9d4bd2229493..e1835868ad36 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.25-rc3 3# Linux kernel version: 2.6.25
4# Wed Mar 26 04:33:35 2008 4# Sun Apr 20 01:33:21 2008
5# 5#
6CONFIG_SPARC=y 6CONFIG_SPARC=y
7CONFIG_SPARC64=y 7CONFIG_SPARC64=y
@@ -22,7 +22,6 @@ CONFIG_HAVE_SETUP_PER_CPU_AREA=y
22CONFIG_ARCH_NO_VIRT_TO_BUS=y 22CONFIG_ARCH_NO_VIRT_TO_BUS=y
23CONFIG_OF=y 23CONFIG_OF=y
24CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y 24CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
25CONFIG_ARCH_SUPPORTS_AOUT=y
26CONFIG_SPARC64_PAGE_SIZE_8KB=y 25CONFIG_SPARC64_PAGE_SIZE_8KB=y
27# CONFIG_SPARC64_PAGE_SIZE_64KB is not set 26# CONFIG_SPARC64_PAGE_SIZE_64KB is not set
28# CONFIG_SPARC64_PAGE_SIZE_512KB is not set 27# CONFIG_SPARC64_PAGE_SIZE_512KB is not set
@@ -61,6 +60,7 @@ CONFIG_RT_GROUP_SCHED=y
61CONFIG_USER_SCHED=y 60CONFIG_USER_SCHED=y
62# CONFIG_CGROUP_SCHED is not set 61# CONFIG_CGROUP_SCHED is not set
63CONFIG_SYSFS_DEPRECATED=y 62CONFIG_SYSFS_DEPRECATED=y
63CONFIG_SYSFS_DEPRECATED_V2=y
64CONFIG_RELAY=y 64CONFIG_RELAY=y
65CONFIG_NAMESPACES=y 65CONFIG_NAMESPACES=y
66# CONFIG_UTS_NS is not set 66# CONFIG_UTS_NS is not set
@@ -100,7 +100,9 @@ CONFIG_PROFILING=y
100CONFIG_OPROFILE=m 100CONFIG_OPROFILE=m
101CONFIG_HAVE_OPROFILE=y 101CONFIG_HAVE_OPROFILE=y
102CONFIG_KPROBES=y 102CONFIG_KPROBES=y
103CONFIG_KRETPROBES=y
103CONFIG_HAVE_KPROBES=y 104CONFIG_HAVE_KPROBES=y
105CONFIG_HAVE_KRETPROBES=y
104CONFIG_PROC_PAGE_MONITOR=y 106CONFIG_PROC_PAGE_MONITOR=y
105CONFIG_SLABINFO=y 107CONFIG_SLABINFO=y
106CONFIG_RT_MUTEXES=y 108CONFIG_RT_MUTEXES=y
@@ -131,8 +133,6 @@ CONFIG_DEFAULT_AS=y
131# CONFIG_DEFAULT_NOOP is not set 133# CONFIG_DEFAULT_NOOP is not set
132CONFIG_DEFAULT_IOSCHED="anticipatory" 134CONFIG_DEFAULT_IOSCHED="anticipatory"
133CONFIG_CLASSIC_RCU=y 135CONFIG_CLASSIC_RCU=y
134# CONFIG_PREEMPT_RCU is not set
135CONFIG_SYSVIPC_COMPAT=y
136CONFIG_GENERIC_HARDIRQS=y 136CONFIG_GENERIC_HARDIRQS=y
137 137
138# 138#
@@ -182,9 +182,6 @@ CONFIG_PCI_MSI=y
182# CONFIG_PCI_LEGACY is not set 182# CONFIG_PCI_LEGACY is not set
183# CONFIG_PCI_DEBUG is not set 183# CONFIG_PCI_DEBUG is not set
184CONFIG_SUN_OPENPROMFS=m 184CONFIG_SUN_OPENPROMFS=m
185CONFIG_SPARC32_COMPAT=y
186CONFIG_COMPAT=y
187# CONFIG_BINFMT_AOUT32 is not set
188 185
189# 186#
190# Executable file formats 187# Executable file formats
@@ -192,13 +189,14 @@ CONFIG_COMPAT=y
192CONFIG_BINFMT_ELF=y 189CONFIG_BINFMT_ELF=y
193CONFIG_COMPAT_BINFMT_ELF=y 190CONFIG_COMPAT_BINFMT_ELF=y
194CONFIG_BINFMT_MISC=m 191CONFIG_BINFMT_MISC=m
195CONFIG_SOLARIS_EMUL=y 192CONFIG_SPARC32_COMPAT=y
193CONFIG_COMPAT=y
194CONFIG_SYSVIPC_COMPAT=y
196CONFIG_SCHED_SMT=y 195CONFIG_SCHED_SMT=y
197CONFIG_SCHED_MC=y 196CONFIG_SCHED_MC=y
198# CONFIG_PREEMPT_NONE is not set 197# CONFIG_PREEMPT_NONE is not set
199CONFIG_PREEMPT_VOLUNTARY=y 198CONFIG_PREEMPT_VOLUNTARY=y
200# CONFIG_PREEMPT is not set 199# CONFIG_PREEMPT is not set
201# CONFIG_RCU_TRACE is not set
202# CONFIG_CMDLINE_BOOL is not set 200# CONFIG_CMDLINE_BOOL is not set
203 201
204# 202#
@@ -263,8 +261,10 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=m
263CONFIG_INET6_XFRM_MODE_BEET=m 261CONFIG_INET6_XFRM_MODE_BEET=m
264# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set 262# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
265CONFIG_IPV6_SIT=m 263CONFIG_IPV6_SIT=m
264CONFIG_IPV6_NDISC_NODETYPE=y
266CONFIG_IPV6_TUNNEL=m 265CONFIG_IPV6_TUNNEL=m
267# CONFIG_IPV6_MULTIPLE_TABLES is not set 266# CONFIG_IPV6_MULTIPLE_TABLES is not set
267# CONFIG_IPV6_MROUTE is not set
268# CONFIG_NETWORK_SECMARK is not set 268# CONFIG_NETWORK_SECMARK is not set
269# CONFIG_NETFILTER is not set 269# CONFIG_NETFILTER is not set
270CONFIG_IP_DCCP=m 270CONFIG_IP_DCCP=m
@@ -368,7 +368,7 @@ CONFIG_IDE=y
368CONFIG_BLK_DEV_IDE=y 368CONFIG_BLK_DEV_IDE=y
369 369
370# 370#
371# Please see Documentation/ide.txt for help/info on IDE drives 371# Please see Documentation/ide/ide.txt for help/info on IDE drives
372# 372#
373# CONFIG_BLK_DEV_IDE_SATA is not set 373# CONFIG_BLK_DEV_IDE_SATA is not set
374CONFIG_BLK_DEV_IDEDISK=y 374CONFIG_BLK_DEV_IDEDISK=y
@@ -384,7 +384,6 @@ CONFIG_IDE_PROC_FS=y
384# 384#
385# IDE chipset support/bugfixes 385# IDE chipset support/bugfixes
386# 386#
387CONFIG_IDE_GENERIC=y
388# CONFIG_BLK_DEV_PLATFORM is not set 387# CONFIG_BLK_DEV_PLATFORM is not set
389CONFIG_BLK_DEV_IDEDMA_SFF=y 388CONFIG_BLK_DEV_IDEDMA_SFF=y
390 389
@@ -422,7 +421,7 @@ CONFIG_BLK_DEV_ALI15X3=y
422# CONFIG_BLK_DEV_VIA82CXXX is not set 421# CONFIG_BLK_DEV_VIA82CXXX is not set
423# CONFIG_BLK_DEV_TC86C001 is not set 422# CONFIG_BLK_DEV_TC86C001 is not set
424CONFIG_BLK_DEV_IDEDMA=y 423CONFIG_BLK_DEV_IDEDMA=y
425CONFIG_IDE_ARCH_OBSOLETE_INIT=y 424# CONFIG_BLK_DEV_HD_ONLY is not set
426# CONFIG_BLK_DEV_HD is not set 425# CONFIG_BLK_DEV_HD is not set
427 426
428# 427#
@@ -588,7 +587,6 @@ CONFIG_E1000_NAPI=y
588# CONFIG_SIS190 is not set 587# CONFIG_SIS190 is not set
589# CONFIG_SKGE is not set 588# CONFIG_SKGE is not set
590# CONFIG_SKY2 is not set 589# CONFIG_SKY2 is not set
591# CONFIG_SK98LIN is not set
592# CONFIG_VIA_VELOCITY is not set 590# CONFIG_VIA_VELOCITY is not set
593CONFIG_TIGON3=m 591CONFIG_TIGON3=m
594CONFIG_BNX2=m 592CONFIG_BNX2=m
@@ -613,6 +611,7 @@ CONFIG_NIU=m
613# 611#
614# CONFIG_WLAN_PRE80211 is not set 612# CONFIG_WLAN_PRE80211 is not set
615# CONFIG_WLAN_80211 is not set 613# CONFIG_WLAN_80211 is not set
614# CONFIG_IWLWIFI_LEDS is not set
616 615
617# 616#
618# USB Network Adapters 617# USB Network Adapters
@@ -1472,7 +1471,7 @@ CONFIG_CRYPTO_MICHAEL_MIC=m
1472CONFIG_CRYPTO_CRC32C=m 1471CONFIG_CRYPTO_CRC32C=m
1473CONFIG_CRYPTO_CAMELLIA=m 1472CONFIG_CRYPTO_CAMELLIA=m
1474CONFIG_CRYPTO_TEST=m 1473CONFIG_CRYPTO_TEST=m
1475CONFIG_CRYPTO_AUTHENC=m 1474CONFIG_CRYPTO_AUTHENC=y
1476# CONFIG_CRYPTO_LZO is not set 1475# CONFIG_CRYPTO_LZO is not set
1477CONFIG_CRYPTO_HW=y 1476CONFIG_CRYPTO_HW=y
1478# CONFIG_CRYPTO_DEV_HIFN_795X is not set 1477# CONFIG_CRYPTO_DEV_HIFN_795X is not set
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile
index 459462e80a12..63c6ae0dd273 100644
--- a/arch/sparc64/kernel/Makefile
+++ b/arch/sparc64/kernel/Makefile
@@ -21,7 +21,6 @@ obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o \
21obj-$(CONFIG_PCI_MSI) += pci_msi.o 21obj-$(CONFIG_PCI_MSI) += pci_msi.o
22obj-$(CONFIG_SMP) += smp.o trampoline.o hvtramp.o 22obj-$(CONFIG_SMP) += smp.o trampoline.o hvtramp.o
23obj-$(CONFIG_SPARC32_COMPAT) += sys32.o sys_sparc32.o signal32.o 23obj-$(CONFIG_SPARC32_COMPAT) += sys32.o sys_sparc32.o signal32.o
24obj-$(CONFIG_BINFMT_AOUT32) += binfmt_aout32.o
25obj-$(CONFIG_MODULES) += module.o 24obj-$(CONFIG_MODULES) += module.o
26obj-$(CONFIG_US3_FREQ) += us3_cpufreq.o 25obj-$(CONFIG_US3_FREQ) += us3_cpufreq.o
27obj-$(CONFIG_US2E_FREQ) += us2e_cpufreq.o 26obj-$(CONFIG_US2E_FREQ) += us2e_cpufreq.o
@@ -30,11 +29,3 @@ obj-$(CONFIG_SUN_LDOMS) += ldc.o vio.o viohs.o ds.o
30obj-$(CONFIG_AUDIT) += audit.o 29obj-$(CONFIG_AUDIT) += audit.o
31obj-$(CONFIG_AUDIT)$(CONFIG_SPARC32_COMPAT) += compat_audit.o 30obj-$(CONFIG_AUDIT)$(CONFIG_SPARC32_COMPAT) += compat_audit.o
32obj-y += $(obj-yy) 31obj-y += $(obj-yy)
33
34ifdef CONFIG_SUNOS_EMUL
35 obj-y += sys_sunos32.o sunos_ioctl32.o
36else
37 ifdef CONFIG_SOLARIS_EMUL
38 obj-y += sys_sunos32.o sunos_ioctl32.o
39 endif
40endif
diff --git a/arch/sparc64/kernel/binfmt_aout32.c b/arch/sparc64/kernel/binfmt_aout32.c
deleted file mode 100644
index 9877f2d7672d..000000000000
--- a/arch/sparc64/kernel/binfmt_aout32.c
+++ /dev/null
@@ -1,419 +0,0 @@
1/*
2 * linux/fs/binfmt_aout.c
3 *
4 * Copyright (C) 1991, 1992, 1996 Linus Torvalds
5 *
6 * Hacked a bit by DaveM to make it work with 32-bit SunOS
7 * binaries on the sparc64 port.
8 */
9
10#include <linux/module.h>
11
12#include <linux/sched.h>
13#include <linux/kernel.h>
14#include <linux/mm.h>
15#include <linux/mman.h>
16#include <linux/a.out.h>
17#include <linux/errno.h>
18#include <linux/signal.h>
19#include <linux/string.h>
20#include <linux/fs.h>
21#include <linux/file.h>
22#include <linux/stat.h>
23#include <linux/fcntl.h>
24#include <linux/ptrace.h>
25#include <linux/user.h>
26#include <linux/slab.h>
27#include <linux/binfmts.h>
28#include <linux/personality.h>
29#include <linux/init.h>
30
31#include <asm/system.h>
32#include <asm/uaccess.h>
33#include <asm/pgalloc.h>
34#include <asm/mmu_context.h>
35#include <asm/a.out-core.h>
36
37static int load_aout32_binary(struct linux_binprm *, struct pt_regs * regs);
38static int load_aout32_library(struct file*);
39static int aout32_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit);
40
41static struct linux_binfmt aout32_format = {
42 .module = THIS_MODULE,
43 .load_binary = load_aout32_binary,
44 .load_shlib = load_aout32_library,
45 .core_dump = aout32_core_dump,
46 .min_coredump = PAGE_SIZE,
47};
48
49static void set_brk(unsigned long start, unsigned long end)
50{
51 start = PAGE_ALIGN(start);
52 end = PAGE_ALIGN(end);
53 if (end <= start)
54 return;
55 down_write(&current->mm->mmap_sem);
56 do_brk(start, end - start);
57 up_write(&current->mm->mmap_sem);
58}
59
60/*
61 * These are the only things you should do on a core-file: use only these
62 * macros to write out all the necessary info.
63 */
64
65static int dump_write(struct file *file, const void *addr, int nr)
66{
67 return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
68}
69
70#define DUMP_WRITE(addr, nr) \
71 if (!dump_write(file, (void *)(addr), (nr))) \
72 goto end_coredump;
73
74#define DUMP_SEEK(offset) \
75if (file->f_op->llseek) { \
76 if (file->f_op->llseek(file,(offset),0) != (offset)) \
77 goto end_coredump; \
78} else file->f_pos = (offset)
79
80/*
81 * Routine writes a core dump image in the current directory.
82 * Currently only a stub-function.
83 *
84 * Note that setuid/setgid files won't make a core-dump if the uid/gid
85 * changed due to the set[u|g]id. It's enforced by the "current->mm->dumpable"
86 * field, which also makes sure the core-dumps won't be recursive if the
87 * dumping of the process results in another error..
88 */
89
90static int aout32_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit)
91{
92 mm_segment_t fs;
93 int has_dumped = 0;
94 unsigned long dump_start, dump_size;
95 struct user dump;
96# define START_DATA(u) (u.u_tsize)
97# define START_STACK(u) ((regs->u_regs[UREG_FP]) & ~(PAGE_SIZE - 1))
98
99 fs = get_fs();
100 set_fs(KERNEL_DS);
101 has_dumped = 1;
102 current->flags |= PF_DUMPCORE;
103 strncpy(dump.u_comm, current->comm, sizeof(dump.u_comm));
104 dump.signal = signr;
105 aout_dump_thread(regs, &dump);
106
107/* If the size of the dump file exceeds the rlimit, then see what would happen
108 if we wrote the stack, but not the data area. */
109 if (dump.u_dsize + dump.u_ssize > limit)
110 dump.u_dsize = 0;
111
112/* Make sure we have enough room to write the stack and data areas. */
113 if (dump.u_ssize > limit)
114 dump.u_ssize = 0;
115
116/* make sure we actually have a data and stack area to dump */
117 set_fs(USER_DS);
118 if (!access_ok(VERIFY_READ, (void __user *) START_DATA(dump), dump.u_dsize))
119 dump.u_dsize = 0;
120 if (!access_ok(VERIFY_READ, (void __user *) START_STACK(dump), dump.u_ssize))
121 dump.u_ssize = 0;
122
123 set_fs(KERNEL_DS);
124/* struct user */
125 DUMP_WRITE(&dump,sizeof(dump));
126/* now we start writing out the user space info */
127 set_fs(USER_DS);
128/* Dump the data area */
129 if (dump.u_dsize != 0) {
130 dump_start = START_DATA(dump);
131 dump_size = dump.u_dsize;
132 DUMP_WRITE(dump_start,dump_size);
133 }
134/* Now prepare to dump the stack area */
135 if (dump.u_ssize != 0) {
136 dump_start = START_STACK(dump);
137 dump_size = dump.u_ssize;
138 DUMP_WRITE(dump_start,dump_size);
139 }
140/* Finally dump the task struct. Not be used by gdb, but could be useful */
141 set_fs(KERNEL_DS);
142 DUMP_WRITE(current,sizeof(*current));
143end_coredump:
144 set_fs(fs);
145 return has_dumped;
146}
147
148/*
149 * create_aout32_tables() parses the env- and arg-strings in new user
150 * memory and creates the pointer tables from them, and puts their
151 * addresses on the "stack", returning the new stack pointer value.
152 */
153
154static u32 __user *create_aout32_tables(char __user *p, struct linux_binprm *bprm)
155{
156 u32 __user *argv;
157 u32 __user *envp;
158 u32 __user *sp;
159 int argc = bprm->argc;
160 int envc = bprm->envc;
161
162 sp = (u32 __user *)((-(unsigned long)sizeof(char *))&(unsigned long)p);
163
164 /* This imposes the proper stack alignment for a new process. */
165 sp = (u32 __user *) (((unsigned long) sp) & ~7);
166 if ((envc+argc+3)&1)
167 --sp;
168
169 sp -= envc+1;
170 envp = sp;
171 sp -= argc+1;
172 argv = sp;
173 put_user(argc,--sp);
174 current->mm->arg_start = (unsigned long) p;
175 while (argc-->0) {
176 char c;
177 put_user(((u32)(unsigned long)(p)),argv++);
178 do {
179 get_user(c,p++);
180 } while (c);
181 }
182 put_user(0,argv);
183 current->mm->arg_end = current->mm->env_start = (unsigned long) p;
184 while (envc-->0) {
185 char c;
186 put_user(((u32)(unsigned long)(p)),envp++);
187 do {
188 get_user(c,p++);
189 } while (c);
190 }
191 put_user(0,envp);
192 current->mm->env_end = (unsigned long) p;
193 return sp;
194}
195
196/*
197 * These are the functions used to load a.out style executables and shared
198 * libraries. There is no binary dependent code anywhere else.
199 */
200
201static int load_aout32_binary(struct linux_binprm * bprm, struct pt_regs * regs)
202{
203 struct exec ex;
204 unsigned long error;
205 unsigned long fd_offset;
206 unsigned long rlim;
207 unsigned long orig_thr_flags;
208 int retval;
209
210 ex = *((struct exec *) bprm->buf); /* exec-header */
211 if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC &&
212 N_MAGIC(ex) != QMAGIC && N_MAGIC(ex) != NMAGIC) ||
213 N_TRSIZE(ex) || N_DRSIZE(ex) ||
214 bprm->file->f_path.dentry->d_inode->i_size < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) {
215 return -ENOEXEC;
216 }
217
218 fd_offset = N_TXTOFF(ex);
219
220 /* Check initial limits. This avoids letting people circumvent
221 * size limits imposed on them by creating programs with large
222 * arrays in the data or bss.
223 */
224 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
225 if (rlim >= RLIM_INFINITY)
226 rlim = ~0;
227 if (ex.a_data + ex.a_bss > rlim)
228 return -ENOMEM;
229
230 /* Flush all traces of the currently running executable */
231 retval = flush_old_exec(bprm);
232 if (retval)
233 return retval;
234
235 /* OK, This is the point of no return */
236 set_personality(PER_SUNOS);
237
238 current->mm->end_code = ex.a_text +
239 (current->mm->start_code = N_TXTADDR(ex));
240 current->mm->end_data = ex.a_data +
241 (current->mm->start_data = N_DATADDR(ex));
242 current->mm->brk = ex.a_bss +
243 (current->mm->start_brk = N_BSSADDR(ex));
244 current->mm->free_area_cache = current->mm->mmap_base;
245 current->mm->cached_hole_size = 0;
246
247 current->mm->mmap = NULL;
248 compute_creds(bprm);
249 current->flags &= ~PF_FORKNOEXEC;
250 if (N_MAGIC(ex) == NMAGIC) {
251 loff_t pos = fd_offset;
252 /* Fuck me plenty... */
253 down_write(&current->mm->mmap_sem);
254 error = do_brk(N_TXTADDR(ex), ex.a_text);
255 up_write(&current->mm->mmap_sem);
256 bprm->file->f_op->read(bprm->file, (char __user *)N_TXTADDR(ex),
257 ex.a_text, &pos);
258 down_write(&current->mm->mmap_sem);
259 error = do_brk(N_DATADDR(ex), ex.a_data);
260 up_write(&current->mm->mmap_sem);
261 bprm->file->f_op->read(bprm->file, (char __user *)N_DATADDR(ex),
262 ex.a_data, &pos);
263 goto beyond_if;
264 }
265
266 if (N_MAGIC(ex) == OMAGIC) {
267 loff_t pos = fd_offset;
268 down_write(&current->mm->mmap_sem);
269 do_brk(N_TXTADDR(ex) & PAGE_MASK,
270 ex.a_text+ex.a_data + PAGE_SIZE - 1);
271 up_write(&current->mm->mmap_sem);
272 bprm->file->f_op->read(bprm->file, (char __user *)N_TXTADDR(ex),
273 ex.a_text+ex.a_data, &pos);
274 } else {
275 static unsigned long error_time;
276 if ((ex.a_text & 0xfff || ex.a_data & 0xfff) &&
277 (N_MAGIC(ex) != NMAGIC) && (jiffies-error_time) > 5*HZ)
278 {
279 printk(KERN_NOTICE "executable not page aligned\n");
280 error_time = jiffies;
281 }
282
283 if (!bprm->file->f_op->mmap) {
284 loff_t pos = fd_offset;
285 down_write(&current->mm->mmap_sem);
286 do_brk(0, ex.a_text+ex.a_data);
287 up_write(&current->mm->mmap_sem);
288 bprm->file->f_op->read(bprm->file,
289 (char __user *)N_TXTADDR(ex),
290 ex.a_text+ex.a_data, &pos);
291 goto beyond_if;
292 }
293
294 down_write(&current->mm->mmap_sem);
295 error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,
296 PROT_READ | PROT_EXEC,
297 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
298 fd_offset);
299 up_write(&current->mm->mmap_sem);
300
301 if (error != N_TXTADDR(ex)) {
302 send_sig(SIGKILL, current, 0);
303 return error;
304 }
305
306 down_write(&current->mm->mmap_sem);
307 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
308 PROT_READ | PROT_WRITE | PROT_EXEC,
309 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
310 fd_offset + ex.a_text);
311 up_write(&current->mm->mmap_sem);
312 if (error != N_DATADDR(ex)) {
313 send_sig(SIGKILL, current, 0);
314 return error;
315 }
316 }
317beyond_if:
318 set_binfmt(&aout32_format);
319
320 set_brk(current->mm->start_brk, current->mm->brk);
321
322 /* Make sure STACK_TOP returns the right thing. */
323 orig_thr_flags = current_thread_info()->flags;
324 current_thread_info()->flags |= _TIF_32BIT;
325
326 retval = setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT);
327 if (retval < 0) {
328 current_thread_info()->flags = orig_thr_flags;
329
330 /* Someone check-me: is this error path enough? */
331 send_sig(SIGKILL, current, 0);
332 return retval;
333 }
334
335 current->mm->start_stack =
336 (unsigned long) create_aout32_tables((char __user *)bprm->p, bprm);
337 tsb_context_switch(current->mm);
338
339 start_thread32(regs, ex.a_entry, current->mm->start_stack);
340 if (current->ptrace & PT_PTRACED)
341 send_sig(SIGTRAP, current, 0);
342 return 0;
343}
344
345/* N.B. Move to .h file and use code in fs/binfmt_aout.c? */
346static int load_aout32_library(struct file *file)
347{
348 struct inode * inode;
349 unsigned long bss, start_addr, len;
350 unsigned long error;
351 int retval;
352 struct exec ex;
353
354 inode = file->f_path.dentry->d_inode;
355
356 retval = -ENOEXEC;
357 error = kernel_read(file, 0, (char *) &ex, sizeof(ex));
358 if (error != sizeof(ex))
359 goto out;
360
361 /* We come in here for the regular a.out style of shared libraries */
362 if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != QMAGIC) || N_TRSIZE(ex) ||
363 N_DRSIZE(ex) || ((ex.a_entry & 0xfff) && N_MAGIC(ex) == ZMAGIC) ||
364 inode->i_size < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) {
365 goto out;
366 }
367
368 if (N_MAGIC(ex) == ZMAGIC && N_TXTOFF(ex) &&
369 (N_TXTOFF(ex) < inode->i_sb->s_blocksize)) {
370 printk("N_TXTOFF < BLOCK_SIZE. Please convert library\n");
371 goto out;
372 }
373
374 if (N_FLAGS(ex))
375 goto out;
376
377 /* For QMAGIC, the starting address is 0x20 into the page. We mask
378 this off to get the starting address for the page */
379
380 start_addr = ex.a_entry & 0xfffff000;
381
382 /* Now use mmap to map the library into memory. */
383 down_write(&current->mm->mmap_sem);
384 error = do_mmap(file, start_addr, ex.a_text + ex.a_data,
385 PROT_READ | PROT_WRITE | PROT_EXEC,
386 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
387 N_TXTOFF(ex));
388 up_write(&current->mm->mmap_sem);
389 retval = error;
390 if (error != start_addr)
391 goto out;
392
393 len = PAGE_ALIGN(ex.a_text + ex.a_data);
394 bss = ex.a_text + ex.a_data + ex.a_bss;
395 if (bss > len) {
396 down_write(&current->mm->mmap_sem);
397 error = do_brk(start_addr + len, bss - len);
398 up_write(&current->mm->mmap_sem);
399 retval = error;
400 if (error != start_addr + len)
401 goto out;
402 }
403 retval = 0;
404out:
405 return retval;
406}
407
408static int __init init_aout32_binfmt(void)
409{
410 return register_binfmt(&aout32_format);
411}
412
413static void __exit exit_aout32_binfmt(void)
414{
415 unregister_binfmt(&aout32_format);
416}
417
418module_init(init_aout32_binfmt);
419module_exit(exit_aout32_binfmt);
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
index 49eca4b1cf25..fb43c76bdc26 100644
--- a/arch/sparc64/kernel/entry.S
+++ b/arch/sparc64/kernel/entry.S
@@ -1353,63 +1353,6 @@ breakpoint_trap:
1353 ba,pt %xcc, rtrap 1353 ba,pt %xcc, rtrap
1354 nop 1354 nop
1355 1355
1356#if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \
1357 defined(CONFIG_SOLARIS_EMUL_MODULE)
1358 /* SunOS uses syscall zero as the 'indirect syscall' it looks
1359 * like indir_syscall(scall_num, arg0, arg1, arg2...); etc.
1360 * This is complete brain damage.
1361 */
1362 .globl sunos_indir
1363sunos_indir:
1364 srl %o0, 0, %o0
1365 mov %o7, %l4
1366 cmp %o0, NR_SYSCALLS
1367 blu,a,pt %icc, 1f
1368 sll %o0, 0x2, %o0
1369 sethi %hi(sunos_nosys), %l6
1370 b,pt %xcc, 2f
1371 or %l6, %lo(sunos_nosys), %l6
13721: sethi %hi(sunos_sys_table), %l7
1373 or %l7, %lo(sunos_sys_table), %l7
1374 lduw [%l7 + %o0], %l6
13752: mov %o1, %o0
1376 mov %o2, %o1
1377 mov %o3, %o2
1378 mov %o4, %o3
1379 mov %o5, %o4
1380 call %l6
1381 mov %l4, %o7
1382
1383 .globl sunos_getpid
1384sunos_getpid:
1385 call sys_getppid
1386 nop
1387 call sys_getpid
1388 stx %o0, [%sp + PTREGS_OFF + PT_V9_I1]
1389 b,pt %xcc, ret_sys_call
1390 stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
1391
1392 /* SunOS getuid() returns uid in %o0 and euid in %o1 */
1393 .globl sunos_getuid
1394sunos_getuid:
1395 call sys32_geteuid16
1396 nop
1397 call sys32_getuid16
1398 stx %o0, [%sp + PTREGS_OFF + PT_V9_I1]
1399 b,pt %xcc, ret_sys_call
1400 stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
1401
1402 /* SunOS getgid() returns gid in %o0 and egid in %o1 */
1403 .globl sunos_getgid
1404sunos_getgid:
1405 call sys32_getegid16
1406 nop
1407 call sys32_getgid16
1408 stx %o0, [%sp + PTREGS_OFF + PT_V9_I1]
1409 b,pt %xcc, ret_sys_call
1410 stx %o0, [%sp + PTREGS_OFF + PT_V9_I0]
1411#endif
1412
1413 /* SunOS's execv() call only specifies the argv argument, the 1356 /* SunOS's execv() call only specifies the argv argument, the
1414 * environment settings are the same as the calling processes. 1357 * environment settings are the same as the calling processes.
1415 */ 1358 */
@@ -1591,7 +1534,7 @@ linux_syscall_trace:
1591 mov %i4, %o4 1534 mov %i4, %o4
1592 1535
1593 1536
1594 /* Linux 32-bit and SunOS system calls enter here... */ 1537 /* Linux 32-bit system calls enter here... */
1595 .align 32 1538 .align 32
1596 .globl linux_sparc_syscall32 1539 .globl linux_sparc_syscall32
1597linux_sparc_syscall32: 1540linux_sparc_syscall32:
@@ -1614,7 +1557,7 @@ linux_sparc_syscall32:
1614 srl %i3, 0, %o3 ! IEU0 1557 srl %i3, 0, %o3 ! IEU0
1615 ba,a,pt %xcc, 3f 1558 ba,a,pt %xcc, 3f
1616 1559
1617 /* Linux native and SunOS system calls enter here... */ 1560 /* Linux native system calls enter here... */
1618 .align 32 1561 .align 32
1619 .globl linux_sparc_syscall, ret_sys_call 1562 .globl linux_sparc_syscall, ret_sys_call
1620linux_sparc_syscall: 1563linux_sparc_syscall:
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c
index 9d51956e8e2f..1c47009eb5ec 100644
--- a/arch/sparc64/kernel/signal.c
+++ b/arch/sparc64/kernel/signal.c
@@ -25,7 +25,6 @@
25 25
26#include <asm/uaccess.h> 26#include <asm/uaccess.h>
27#include <asm/ptrace.h> 27#include <asm/ptrace.h>
28#include <asm/svr4.h>
29#include <asm/pgtable.h> 28#include <asm/pgtable.h>
30#include <asm/fpumacro.h> 29#include <asm/fpumacro.h>
31#include <asm/uctx.h> 30#include <asm/uctx.h>
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
index 8c1c121330fb..74e0512f135c 100644
--- a/arch/sparc64/kernel/signal32.c
+++ b/arch/sparc64/kernel/signal32.c
@@ -23,7 +23,6 @@
23 23
24#include <asm/uaccess.h> 24#include <asm/uaccess.h>
25#include <asm/ptrace.h> 25#include <asm/ptrace.h>
26#include <asm/svr4.h>
27#include <asm/pgtable.h> 26#include <asm/pgtable.h>
28#include <asm/psrcompat.h> 27#include <asm/psrcompat.h>
29#include <asm/fpumacro.h> 28#include <asm/fpumacro.h>
@@ -798,281 +797,6 @@ sigsegv:
798 force_sigsegv(signo, current); 797 force_sigsegv(signo, current);
799} 798}
800 799
801/* Setup a Solaris stack frame */
802static void
803setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
804 struct pt_regs *regs, int signr, sigset_t *oldset)
805{
806 svr4_signal_frame_t __user *sfp;
807 svr4_gregset_t __user *gr;
808 svr4_siginfo_t __user *si;
809 svr4_mcontext_t __user *mc;
810 svr4_gwindows_t __user *gw;
811 svr4_ucontext_t __user *uc;
812 svr4_sigset_t setv;
813 unsigned int psr;
814 int i, err;
815
816 synchronize_user_stack();
817 save_and_clear_fpu();
818
819 regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
820 sfp = (svr4_signal_frame_t __user *)
821 get_sigframe(sa, regs,
822 sizeof(struct reg_window32) + SVR4_SF_ALIGNED);
823
824 if (invalid_frame_pointer(sfp, sizeof(*sfp)))
825 do_exit(SIGILL);
826
827 /* Start with a clean frame pointer and fill it */
828 err = clear_user(sfp, sizeof(*sfp));
829
830 /* Setup convenience variables */
831 si = &sfp->si;
832 uc = &sfp->uc;
833 gw = &sfp->gw;
834 mc = &uc->mcontext;
835 gr = &mc->greg;
836
837 /* FIXME: where am I supposed to put this?
838 * sc->sigc_onstack = old_status;
839 * anyways, it does not look like it is used for anything at all.
840 */
841 setv.sigbits[0] = oldset->sig[0];
842 setv.sigbits[1] = (oldset->sig[0] >> 32);
843 if (_NSIG_WORDS >= 2) {
844 setv.sigbits[2] = oldset->sig[1];
845 setv.sigbits[3] = (oldset->sig[1] >> 32);
846 err |= __copy_to_user(&uc->sigmask, &setv, sizeof(svr4_sigset_t));
847 } else
848 err |= __copy_to_user(&uc->sigmask, &setv,
849 2 * sizeof(unsigned int));
850
851 /* Store registers */
852 if (test_thread_flag(TIF_32BIT)) {
853 regs->tpc &= 0xffffffff;
854 regs->tnpc &= 0xffffffff;
855 }
856 err |= __put_user(regs->tpc, &((*gr)[SVR4_PC]));
857 err |= __put_user(regs->tnpc, &((*gr)[SVR4_NPC]));
858 psr = tstate_to_psr(regs->tstate);
859 if (current_thread_info()->fpsaved[0] & FPRS_FEF)
860 psr |= PSR_EF;
861 err |= __put_user(psr, &((*gr)[SVR4_PSR]));
862 err |= __put_user(regs->y, &((*gr)[SVR4_Y]));
863
864 /* Copy g[1..7] and o[0..7] registers */
865 for (i = 0; i < 7; i++)
866 err |= __put_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i);
867 for (i = 0; i < 8; i++)
868 err |= __put_user(regs->u_regs[UREG_I0+i], (&(*gr)[SVR4_O0])+i);
869
870 /* Setup sigaltstack */
871 err |= __put_user(current->sas_ss_sp, &uc->stack.sp);
872 err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &uc->stack.flags);
873 err |= __put_user(current->sas_ss_size, &uc->stack.size);
874
875 /* Save the currently window file: */
876
877 /* 1. Link sfp->uc->gwins to our windows */
878 err |= __put_user(ptr_to_compat(gw), &mc->gwin);
879
880 /* 2. Number of windows to restore at setcontext (): */
881 err |= __put_user(get_thread_wsaved(), &gw->count);
882
883 /* 3. We just pay attention to the gw->count field on setcontext */
884 set_thread_wsaved(0); /* So process is allowed to execute. */
885
886 /* Setup the signal information. Solaris expects a bunch of
887 * information to be passed to the signal handler, we don't provide
888 * that much currently, should use siginfo.
889 */
890 err |= __put_user(signr, &si->siginfo.signo);
891 err |= __put_user(SVR4_SINOINFO, &si->siginfo.code);
892 if (err)
893 goto sigsegv;
894
895 regs->u_regs[UREG_FP] = (unsigned long) sfp;
896 regs->tpc = (unsigned long) sa->sa_handler;
897 regs->tnpc = (regs->tpc + 4);
898 if (test_thread_flag(TIF_32BIT)) {
899 regs->tpc &= 0xffffffff;
900 regs->tnpc &= 0xffffffff;
901 }
902
903 /* Arguments passed to signal handler */
904 if (regs->u_regs[14]){
905 struct reg_window32 __user *rw = (struct reg_window32 __user *)
906 (regs->u_regs[14] & 0x00000000ffffffffUL);
907
908 err |= __put_user(signr, &rw->ins[0]);
909 err |= __put_user((u64)si, &rw->ins[1]);
910 err |= __put_user((u64)uc, &rw->ins[2]);
911 err |= __put_user((u64)sfp, &rw->ins[6]); /* frame pointer */
912 if (err)
913 goto sigsegv;
914
915 regs->u_regs[UREG_I0] = signr;
916 regs->u_regs[UREG_I1] = (u32)(u64) si;
917 regs->u_regs[UREG_I2] = (u32)(u64) uc;
918 }
919 return;
920
921sigsegv:
922 force_sigsegv(signr, current);
923}
924
925asmlinkage int
926svr4_getcontext(svr4_ucontext_t __user *uc, struct pt_regs *regs)
927{
928 svr4_gregset_t __user *gr;
929 svr4_mcontext_t __user *mc;
930 svr4_sigset_t setv;
931 int i, err;
932 u32 psr;
933
934 synchronize_user_stack();
935 save_and_clear_fpu();
936
937 if (get_thread_wsaved())
938 do_exit(SIGSEGV);
939
940 err = clear_user(uc, sizeof(*uc));
941
942 /* Setup convenience variables */
943 mc = &uc->mcontext;
944 gr = &mc->greg;
945
946 setv.sigbits[0] = current->blocked.sig[0];
947 setv.sigbits[1] = (current->blocked.sig[0] >> 32);
948 if (_NSIG_WORDS >= 2) {
949 setv.sigbits[2] = current->blocked.sig[1];
950 setv.sigbits[3] = (current->blocked.sig[1] >> 32);
951 err |= __copy_to_user(&uc->sigmask, &setv, sizeof(svr4_sigset_t));
952 } else
953 err |= __copy_to_user(&uc->sigmask, &setv, 2 * sizeof(unsigned));
954
955 /* Store registers */
956 if (test_thread_flag(TIF_32BIT)) {
957 regs->tpc &= 0xffffffff;
958 regs->tnpc &= 0xffffffff;
959 }
960 err |= __put_user(regs->tpc, &uc->mcontext.greg[SVR4_PC]);
961 err |= __put_user(regs->tnpc, &uc->mcontext.greg[SVR4_NPC]);
962
963 psr = tstate_to_psr(regs->tstate) & ~PSR_EF;
964 if (current_thread_info()->fpsaved[0] & FPRS_FEF)
965 psr |= PSR_EF;
966 err |= __put_user(psr, &uc->mcontext.greg[SVR4_PSR]);
967
968 err |= __put_user(regs->y, &uc->mcontext.greg[SVR4_Y]);
969
970 /* Copy g[1..7] and o[0..7] registers */
971 for (i = 0; i < 7; i++)
972 err |= __put_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i);
973 for (i = 0; i < 8; i++)
974 err |= __put_user(regs->u_regs[UREG_I0+i], (&(*gr)[SVR4_O0])+i);
975
976 /* Setup sigaltstack */
977 err |= __put_user(current->sas_ss_sp, &uc->stack.sp);
978 err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &uc->stack.flags);
979 err |= __put_user(current->sas_ss_size, &uc->stack.size);
980
981 /* The register file is not saved
982 * we have already stuffed all of it with sync_user_stack
983 */
984 return (err ? -EFAULT : 0);
985}
986
987
988/* Set the context for a svr4 application, this is Solaris way to sigreturn */
989asmlinkage int svr4_setcontext(svr4_ucontext_t __user *c, struct pt_regs *regs)
990{
991 svr4_gregset_t __user *gr;
992 mm_segment_t old_fs;
993 u32 pc, npc, psr, u_ss_sp;
994 sigset_t set;
995 svr4_sigset_t setv;
996 int i, err;
997 stack_t st;
998
999 /* Fixme: restore windows, or is this already taken care of in
1000 * svr4_setup_frame when sync_user_windows is done?
1001 */
1002 flush_user_windows();
1003
1004 if (get_thread_wsaved())
1005 goto sigsegv;
1006
1007 if (((unsigned long) c) & 3){
1008 printk("Unaligned structure passed\n");
1009 goto sigsegv;
1010 }
1011
1012 if (!__access_ok(c, sizeof(*c))) {
1013 /* Miguel, add nice debugging msg _here_. ;-) */
1014 goto sigsegv;
1015 }
1016
1017 /* Check for valid PC and nPC */
1018 gr = &c->mcontext.greg;
1019 err = __get_user(pc, &((*gr)[SVR4_PC]));
1020 err |= __get_user(npc, &((*gr)[SVR4_NPC]));
1021 if ((pc | npc) & 3)
1022 goto sigsegv;
1023
1024 /* Retrieve information from passed ucontext */
1025 /* note that nPC is ored a 1, this is used to inform entry.S */
1026 /* that we don't want it to mess with our PC and nPC */
1027
1028 err |= copy_from_user(&setv, &c->sigmask, sizeof(svr4_sigset_t));
1029 set.sig[0] = setv.sigbits[0] | (((long)setv.sigbits[1]) << 32);
1030 if (_NSIG_WORDS >= 2)
1031 set.sig[1] = setv.sigbits[2] | (((long)setv.sigbits[3]) << 32);
1032
1033 err |= __get_user(u_ss_sp, &c->stack.sp);
1034 st.ss_sp = compat_ptr(u_ss_sp);
1035 err |= __get_user(st.ss_flags, &c->stack.flags);
1036 err |= __get_user(st.ss_size, &c->stack.size);
1037 if (err)
1038 goto sigsegv;
1039
1040 /* It is more difficult to avoid calling this function than to
1041 call it and ignore errors. */
1042 old_fs = get_fs();
1043 set_fs(KERNEL_DS);
1044 do_sigaltstack((stack_t __user *) &st, NULL, regs->u_regs[UREG_I6]);
1045 set_fs(old_fs);
1046
1047 sigdelsetmask(&set, ~_BLOCKABLE);
1048 spin_lock_irq(&current->sighand->siglock);
1049 current->blocked = set;
1050 recalc_sigpending();
1051 spin_unlock_irq(&current->sighand->siglock);
1052 regs->tpc = pc;
1053 regs->tnpc = npc | 1;
1054 if (test_thread_flag(TIF_32BIT)) {
1055 regs->tpc &= 0xffffffff;
1056 regs->tnpc &= 0xffffffff;
1057 }
1058 err |= __get_user(regs->y, &((*gr)[SVR4_Y]));
1059 err |= __get_user(psr, &((*gr)[SVR4_PSR]));
1060 regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
1061 regs->tstate |= psr_to_tstate_icc(psr);
1062
1063 /* Restore g[1..7] and o[0..7] registers */
1064 for (i = 0; i < 7; i++)
1065 err |= __get_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i);
1066 for (i = 0; i < 8; i++)
1067 err |= __get_user(regs->u_regs[UREG_I0+i], (&(*gr)[SVR4_O0])+i);
1068 if (err)
1069 goto sigsegv;
1070
1071 return -EINTR;
1072sigsegv:
1073 return -EFAULT;
1074}
1075
1076static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, 800static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
1077 unsigned long signr, sigset_t *oldset, 801 unsigned long signr, sigset_t *oldset,
1078 siginfo_t *info) 802 siginfo_t *info)
@@ -1216,20 +940,14 @@ sigsegv:
1216 940
1217static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka, 941static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka,
1218 siginfo_t *info, 942 siginfo_t *info,
1219 sigset_t *oldset, struct pt_regs *regs, 943 sigset_t *oldset, struct pt_regs *regs)
1220 int svr4_signal)
1221{ 944{
1222 if (svr4_signal) 945 if (ka->sa.sa_flags & SA_SIGINFO)
1223 setup_svr4_frame32(&ka->sa, regs->tpc, regs->tnpc, 946 setup_rt_frame32(ka, regs, signr, oldset, info);
1224 regs, signr, oldset); 947 else if (test_thread_flag(TIF_NEWSIGNALS))
1225 else { 948 new_setup_frame32(ka, regs, signr, oldset);
1226 if (ka->sa.sa_flags & SA_SIGINFO) 949 else
1227 setup_rt_frame32(ka, regs, signr, oldset, info); 950 setup_frame32(&ka->sa, regs, signr, oldset, info);
1228 else if (test_thread_flag(TIF_NEWSIGNALS))
1229 new_setup_frame32(ka, regs, signr, oldset);
1230 else
1231 setup_frame32(&ka->sa, regs, signr, oldset, info);
1232 }
1233 spin_lock_irq(&current->sighand->siglock); 951 spin_lock_irq(&current->sighand->siglock);
1234 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 952 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
1235 if (!(ka->sa.sa_flags & SA_NOMASK)) 953 if (!(ka->sa.sa_flags & SA_NOMASK))
@@ -1270,7 +988,6 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs,
1270 struct signal_deliver_cookie cookie; 988 struct signal_deliver_cookie cookie;
1271 struct k_sigaction ka; 989 struct k_sigaction ka;
1272 int signr; 990 int signr;
1273 int svr4_signal = current->personality == PER_SVR4;
1274 991
1275 cookie.restart_syscall = restart_syscall; 992 cookie.restart_syscall = restart_syscall;
1276 cookie.orig_i0 = orig_i0; 993 cookie.orig_i0 = orig_i0;
@@ -1279,8 +996,7 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs,
1279 if (signr > 0) { 996 if (signr > 0) {
1280 if (cookie.restart_syscall) 997 if (cookie.restart_syscall)
1281 syscall_restart32(orig_i0, regs, &ka.sa); 998 syscall_restart32(orig_i0, regs, &ka.sa);
1282 handle_signal32(signr, &ka, &info, oldset, 999 handle_signal32(signr, &ka, &info, oldset, regs);
1283 regs, svr4_signal);
1284 1000
1285 /* a signal was successfully delivered; the saved 1001 /* a signal was successfully delivered; the saved
1286 * sigmask will have been stored in the signal frame, 1002 * sigmask will have been stored in the signal frame,
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
index 051b8d9cb989..38736460b8db 100644
--- a/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/arch/sparc64/kernel/sparc64_ksyms.c
@@ -33,13 +33,11 @@
33#include <asm/io.h> 33#include <asm/io.h>
34#include <asm/irq.h> 34#include <asm/irq.h>
35#include <asm/idprom.h> 35#include <asm/idprom.h>
36#include <asm/svr4.h>
37#include <asm/elf.h> 36#include <asm/elf.h>
38#include <asm/head.h> 37#include <asm/head.h>
39#include <asm/smp.h> 38#include <asm/smp.h>
40#include <asm/mostek.h> 39#include <asm/mostek.h>
41#include <asm/ptrace.h> 40#include <asm/ptrace.h>
42#include <asm/user.h>
43#include <asm/uaccess.h> 41#include <asm/uaccess.h>
44#include <asm/checksum.h> 42#include <asm/checksum.h>
45#include <asm/fpumacro.h> 43#include <asm/fpumacro.h>
@@ -73,13 +71,8 @@ extern __kernel_size_t strlen(const char *);
73extern void linux_sparc_syscall(void); 71extern void linux_sparc_syscall(void);
74extern void rtrap(void); 72extern void rtrap(void);
75extern void show_regs(struct pt_regs *); 73extern void show_regs(struct pt_regs *);
76extern void solaris_syscall(void);
77extern void syscall_trace(struct pt_regs *, int); 74extern void syscall_trace(struct pt_regs *, int);
78extern u32 sunos_sys_table[], sys_call_table32[];
79extern void tl0_solaris(void);
80extern void sys_sigsuspend(void); 75extern void sys_sigsuspend(void);
81extern int svr4_getcontext(svr4_ucontext_t *uc, struct pt_regs *regs);
82extern int svr4_setcontext(svr4_ucontext_t *uc, struct pt_regs *regs);
83extern int compat_sys_ioctl(unsigned int fd, unsigned int cmd, u32 arg); 76extern int compat_sys_ioctl(unsigned int fd, unsigned int cmd, u32 arg);
84extern int (*handle_mathemu)(struct pt_regs *, struct fpustate *); 77extern int (*handle_mathemu)(struct pt_regs *, struct fpustate *);
85extern long sparc32_open(const char __user * filename, int flags, int mode); 78extern long sparc32_open(const char __user * filename, int flags, int mode);
@@ -90,8 +83,6 @@ extern int __ashrdi3(int, int);
90 83
91extern int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs); 84extern int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs);
92 85
93extern unsigned int sys_call_table[];
94
95extern void xor_vis_2(unsigned long, unsigned long *, unsigned long *); 86extern void xor_vis_2(unsigned long, unsigned long *, unsigned long *);
96extern void xor_vis_3(unsigned long, unsigned long *, unsigned long *, 87extern void xor_vis_3(unsigned long, unsigned long *, unsigned long *,
97 unsigned long *); 88 unsigned long *);
@@ -213,11 +204,6 @@ EXPORT_SYMBOL(pci_dma_supported);
213/* I/O device mmaping on Sparc64. */ 204/* I/O device mmaping on Sparc64. */
214EXPORT_SYMBOL(io_remap_pfn_range); 205EXPORT_SYMBOL(io_remap_pfn_range);
215 206
216#if defined(CONFIG_COMPAT) && defined(CONFIG_NET)
217/* Solaris/SunOS binary compatibility */
218EXPORT_SYMBOL(verify_compat_iovec);
219#endif
220
221EXPORT_SYMBOL(dump_fpu); 207EXPORT_SYMBOL(dump_fpu);
222EXPORT_SYMBOL(put_fs_struct); 208EXPORT_SYMBOL(put_fs_struct);
223 209
@@ -254,30 +240,6 @@ EXPORT_SYMBOL(strlen);
254EXPORT_SYMBOL(__strlen_user); 240EXPORT_SYMBOL(__strlen_user);
255EXPORT_SYMBOL(__strnlen_user); 241EXPORT_SYMBOL(__strnlen_user);
256 242
257#ifdef CONFIG_SOLARIS_EMUL_MODULE
258EXPORT_SYMBOL(linux_sparc_syscall);
259EXPORT_SYMBOL(rtrap);
260EXPORT_SYMBOL(show_regs);
261EXPORT_SYMBOL(solaris_syscall);
262EXPORT_SYMBOL(syscall_trace);
263EXPORT_SYMBOL(sunos_sys_table);
264EXPORT_SYMBOL(sys_call_table32);
265EXPORT_SYMBOL(tl0_solaris);
266EXPORT_SYMBOL(sys_sigsuspend);
267EXPORT_SYMBOL(sys_getppid);
268EXPORT_SYMBOL(sys_getpid);
269EXPORT_SYMBOL(sys_geteuid);
270EXPORT_SYMBOL(sys_getuid);
271EXPORT_SYMBOL(sys_getegid);
272EXPORT_SYMBOL(sysctl_nr_open);
273EXPORT_SYMBOL(sys_getgid);
274EXPORT_SYMBOL(svr4_getcontext);
275EXPORT_SYMBOL(svr4_setcontext);
276EXPORT_SYMBOL(compat_sys_ioctl);
277EXPORT_SYMBOL(sys_ioctl);
278EXPORT_SYMBOL(sparc32_open);
279#endif
280
281/* Special internal versions of library functions. */ 243/* Special internal versions of library functions. */
282EXPORT_SYMBOL(_clear_page); 244EXPORT_SYMBOL(_clear_page);
283EXPORT_SYMBOL(clear_user_page); 245EXPORT_SYMBOL(clear_user_page);
@@ -334,9 +296,6 @@ EXPORT_SYMBOL(do_BUG);
334/* for ns8703 */ 296/* for ns8703 */
335EXPORT_SYMBOL(ns87303_lock); 297EXPORT_SYMBOL(ns87303_lock);
336 298
337/* for solaris compat module */
338EXPORT_SYMBOL_GPL(sys_call_table);
339
340EXPORT_SYMBOL(tick_ops); 299EXPORT_SYMBOL(tick_ops);
341 300
342EXPORT_SYMBOL(xor_vis_2); 301EXPORT_SYMBOL(xor_vis_2);
diff --git a/arch/sparc64/kernel/sunos_ioctl32.c b/arch/sparc64/kernel/sunos_ioctl32.c
deleted file mode 100644
index 75d2bad49839..000000000000
--- a/arch/sparc64/kernel/sunos_ioctl32.c
+++ /dev/null
@@ -1,275 +0,0 @@
1/* $Id: sunos_ioctl32.c,v 1.11 2000/07/30 23:12:24 davem Exp $
2 * sunos_ioctl32.c: SunOS ioctl compatibility on sparc64.
3 *
4 * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
5 * Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
6 */
7
8#include <asm/uaccess.h>
9
10#include <linux/sched.h>
11#include <linux/errno.h>
12#include <linux/string.h>
13#include <linux/termios.h>
14#include <linux/tty.h>
15#include <linux/ioctl.h>
16#include <linux/route.h>
17#include <linux/sockios.h>
18#include <linux/if.h>
19#include <linux/netdevice.h>
20#include <linux/if_arp.h>
21#include <linux/fs.h>
22#include <linux/file.h>
23#include <linux/mm.h>
24#include <linux/smp.h>
25#include <linux/syscalls.h>
26#include <linux/compat.h>
27
28#define SUNOS_NR_OPEN 256
29
30struct rtentry32 {
31 u32 rt_pad1;
32 struct sockaddr rt_dst; /* target address */
33 struct sockaddr rt_gateway; /* gateway addr (RTF_GATEWAY) */
34 struct sockaddr rt_genmask; /* target network mask (IP) */
35 unsigned short rt_flags;
36 short rt_pad2;
37 u32 rt_pad3;
38 unsigned char rt_tos;
39 unsigned char rt_class;
40 short rt_pad4;
41 short rt_metric; /* +1 for binary compatibility! */
42 /* char * */ u32 rt_dev; /* forcing the device at add */
43 u32 rt_mtu; /* per route MTU/Window */
44 u32 rt_window; /* Window clamping */
45 unsigned short rt_irtt; /* Initial RTT */
46
47};
48
49struct ifmap32 {
50 u32 mem_start;
51 u32 mem_end;
52 unsigned short base_addr;
53 unsigned char irq;
54 unsigned char dma;
55 unsigned char port;
56};
57
58struct ifreq32 {
59#define IFHWADDRLEN 6
60#define IFNAMSIZ 16
61 union {
62 char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */
63 } ifr_ifrn;
64 union {
65 struct sockaddr ifru_addr;
66 struct sockaddr ifru_dstaddr;
67 struct sockaddr ifru_broadaddr;
68 struct sockaddr ifru_netmask;
69 struct sockaddr ifru_hwaddr;
70 short ifru_flags;
71 int ifru_ivalue;
72 int ifru_mtu;
73 struct ifmap32 ifru_map;
74 char ifru_slave[IFNAMSIZ]; /* Just fits the size */
75 compat_caddr_t ifru_data;
76 } ifr_ifru;
77};
78
79struct ifconf32 {
80 int ifc_len; /* size of buffer */
81 compat_caddr_t ifcbuf;
82};
83
84extern asmlinkage int compat_sys_ioctl(unsigned int, unsigned int, u32);
85
86asmlinkage int sunos_ioctl (int fd, u32 cmd, u32 arg)
87{
88 int ret = -EBADF;
89
90 if(fd >= SUNOS_NR_OPEN)
91 goto out;
92 if(!fcheck(fd))
93 goto out;
94
95 if(cmd == TIOCSETD) {
96 mm_segment_t old_fs = get_fs();
97 int __user *p;
98 int ntty = N_TTY;
99 int tmp;
100
101 p = (int __user *) (unsigned long) arg;
102 ret = -EFAULT;
103 if(get_user(tmp, p))
104 goto out;
105 if(tmp == 2) {
106 set_fs(KERNEL_DS);
107 ret = sys_ioctl(fd, cmd, (unsigned long) &ntty);
108 set_fs(old_fs);
109 ret = (ret == -EINVAL ? -EOPNOTSUPP : ret);
110 goto out;
111 }
112 }
113 if(cmd == TIOCNOTTY) {
114 ret = sys_setsid();
115 goto out;
116 }
117 switch(cmd) {
118 case _IOW('r', 10, struct rtentry32):
119 ret = compat_sys_ioctl(fd, SIOCADDRT, arg);
120 goto out;
121 case _IOW('r', 11, struct rtentry32):
122 ret = compat_sys_ioctl(fd, SIOCDELRT, arg);
123 goto out;
124
125 case _IOW('i', 12, struct ifreq32):
126 ret = compat_sys_ioctl(fd, SIOCSIFADDR, arg);
127 goto out;
128 case _IOWR('i', 13, struct ifreq32):
129 ret = compat_sys_ioctl(fd, SIOCGIFADDR, arg);
130 goto out;
131 case _IOW('i', 14, struct ifreq32):
132 ret = compat_sys_ioctl(fd, SIOCSIFDSTADDR, arg);
133 goto out;
134 case _IOWR('i', 15, struct ifreq32):
135 ret = compat_sys_ioctl(fd, SIOCGIFDSTADDR, arg);
136 goto out;
137 case _IOW('i', 16, struct ifreq32):
138 ret = compat_sys_ioctl(fd, SIOCSIFFLAGS, arg);
139 goto out;
140 case _IOWR('i', 17, struct ifreq32):
141 ret = compat_sys_ioctl(fd, SIOCGIFFLAGS, arg);
142 goto out;
143 case _IOW('i', 18, struct ifreq32):
144 ret = compat_sys_ioctl(fd, SIOCSIFMEM, arg);
145 goto out;
146 case _IOWR('i', 19, struct ifreq32):
147 ret = compat_sys_ioctl(fd, SIOCGIFMEM, arg);
148 goto out;
149
150 case _IOWR('i', 20, struct ifconf32):
151 ret = compat_sys_ioctl(fd, SIOCGIFCONF, arg);
152 goto out;
153
154 case _IOW('i', 21, struct ifreq32):
155 ret = compat_sys_ioctl(fd, SIOCSIFMTU, arg);
156 goto out;
157
158 case _IOWR('i', 22, struct ifreq32):
159 ret = compat_sys_ioctl(fd, SIOCGIFMTU, arg);
160 goto out;
161
162 case _IOWR('i', 23, struct ifreq32):
163 ret = compat_sys_ioctl(fd, SIOCGIFBRDADDR, arg);
164 goto out;
165 case _IOW('i', 24, struct ifreq32):
166 ret = compat_sys_ioctl(fd, SIOCSIFBRDADDR, arg);
167 goto out;
168 case _IOWR('i', 25, struct ifreq32):
169 ret = compat_sys_ioctl(fd, SIOCGIFNETMASK, arg);
170 goto out;
171 case _IOW('i', 26, struct ifreq32):
172 ret = compat_sys_ioctl(fd, SIOCSIFNETMASK, arg);
173 goto out;
174 case _IOWR('i', 27, struct ifreq32):
175 ret = compat_sys_ioctl(fd, SIOCGIFMETRIC, arg);
176 goto out;
177 case _IOW('i', 28, struct ifreq32):
178 ret = compat_sys_ioctl(fd, SIOCSIFMETRIC, arg);
179 goto out;
180
181 case _IOW('i', 30, struct arpreq):
182 ret = compat_sys_ioctl(fd, SIOCSARP, arg);
183 goto out;
184 case _IOWR('i', 31, struct arpreq):
185 ret = compat_sys_ioctl(fd, SIOCGARP, arg);
186 goto out;
187 case _IOW('i', 32, struct arpreq):
188 ret = compat_sys_ioctl(fd, SIOCDARP, arg);
189 goto out;
190
191 case _IOW('i', 40, struct ifreq32): /* SIOCUPPER */
192 case _IOW('i', 41, struct ifreq32): /* SIOCLOWER */
193 case _IOW('i', 44, struct ifreq32): /* SIOCSETSYNC */
194 case _IOW('i', 45, struct ifreq32): /* SIOCGETSYNC */
195 case _IOW('i', 46, struct ifreq32): /* SIOCSSDSTATS */
196 case _IOW('i', 47, struct ifreq32): /* SIOCSSESTATS */
197 case _IOW('i', 48, struct ifreq32): /* SIOCSPROMISC */
198 ret = -EOPNOTSUPP;
199 goto out;
200
201 case _IOW('i', 49, struct ifreq32):
202 ret = compat_sys_ioctl(fd, SIOCADDMULTI, arg);
203 goto out;
204 case _IOW('i', 50, struct ifreq32):
205 ret = compat_sys_ioctl(fd, SIOCDELMULTI, arg);
206 goto out;
207
208 /* FDDI interface ioctls, unsupported. */
209
210 case _IOW('i', 51, struct ifreq32): /* SIOCFDRESET */
211 case _IOW('i', 52, struct ifreq32): /* SIOCFDSLEEP */
212 case _IOW('i', 53, struct ifreq32): /* SIOCSTRTFMWAR */
213 case _IOW('i', 54, struct ifreq32): /* SIOCLDNSTRTFW */
214 case _IOW('i', 55, struct ifreq32): /* SIOCGETFDSTAT */
215 case _IOW('i', 56, struct ifreq32): /* SIOCFDNMIINT */
216 case _IOW('i', 57, struct ifreq32): /* SIOCFDEXUSER */
217 case _IOW('i', 58, struct ifreq32): /* SIOCFDGNETMAP */
218 case _IOW('i', 59, struct ifreq32): /* SIOCFDGIOCTL */
219 printk("FDDI ioctl, returning EOPNOTSUPP\n");
220 ret = -EOPNOTSUPP;
221 goto out;
222
223 case _IOW('t', 125, int):
224 /* More stupid tty sunos ioctls, just
225 * say it worked.
226 */
227 ret = 0;
228 goto out;
229
230 /* Non posix grp */
231 case _IOW('t', 118, int): {
232 int oldval, newval, __user *ptr;
233
234 cmd = TIOCSPGRP;
235 ptr = (int __user *) (unsigned long) arg;
236 ret = -EFAULT;
237 if(get_user(oldval, ptr))
238 goto out;
239 ret = compat_sys_ioctl(fd, cmd, arg);
240 __get_user(newval, ptr);
241 if(newval == -1) {
242 __put_user(oldval, ptr);
243 ret = -EIO;
244 }
245 if(ret == -ENOTTY)
246 ret = -EIO;
247 goto out;
248 }
249
250 case _IOR('t', 119, int): {
251 int oldval, newval, __user *ptr;
252
253 cmd = TIOCGPGRP;
254 ptr = (int __user *) (unsigned long) arg;
255 ret = -EFAULT;
256 if(get_user(oldval, ptr))
257 goto out;
258 ret = compat_sys_ioctl(fd, cmd, arg);
259 __get_user(newval, ptr);
260 if(newval == -1) {
261 __put_user(oldval, ptr);
262 ret = -EIO;
263 }
264 if(ret == -ENOTTY)
265 ret = -EIO;
266 goto out;
267 }
268 };
269
270 ret = compat_sys_ioctl(fd, cmd, arg);
271 /* so stupid... */
272 ret = (ret == -EINVAL ? -EOPNOTSUPP : ret);
273out:
274 return ret;
275}
diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c
index f952745d0f3d..73ed01ba40dc 100644
--- a/arch/sparc64/kernel/sys_sparc.c
+++ b/arch/sparc64/kernel/sys_sparc.c
@@ -720,44 +720,6 @@ out:
720 return err; 720 return err;
721} 721}
722 722
723asmlinkage long solaris_syscall(struct pt_regs *regs)
724{
725 static int count;
726
727 regs->tpc = regs->tnpc;
728 regs->tnpc += 4;
729 if (test_thread_flag(TIF_32BIT)) {
730 regs->tpc &= 0xffffffff;
731 regs->tnpc &= 0xffffffff;
732 }
733 if (++count <= 5) {
734 printk ("For Solaris binary emulation you need solaris module loaded\n");
735 show_regs (regs);
736 }
737 send_sig(SIGSEGV, current, 1);
738
739 return -ENOSYS;
740}
741
742#ifndef CONFIG_SUNOS_EMUL
743asmlinkage long sunos_syscall(struct pt_regs *regs)
744{
745 static int count;
746
747 regs->tpc = regs->tnpc;
748 regs->tnpc += 4;
749 if (test_thread_flag(TIF_32BIT)) {
750 regs->tpc &= 0xffffffff;
751 regs->tnpc &= 0xffffffff;
752 }
753 if (++count <= 20)
754 printk ("SunOS binary emulation not compiled in\n");
755 force_sig(SIGSEGV, current);
756
757 return -ENOSYS;
758}
759#endif
760
761asmlinkage long sys_utrap_install(utrap_entry_t type, 723asmlinkage long sys_utrap_install(utrap_entry_t type,
762 utrap_handler_t new_p, 724 utrap_handler_t new_p,
763 utrap_handler_t new_d, 725 utrap_handler_t new_d,
diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c
deleted file mode 100644
index e91194fe39d7..000000000000
--- a/arch/sparc64/kernel/sys_sunos32.c
+++ /dev/null
@@ -1,1359 +0,0 @@
1/* $Id: sys_sunos32.c,v 1.64 2002/02/09 19:49:31 davem Exp $
2 * sys_sunos32.c: SunOS binary compatibility layer on sparc64.
3 *
4 * Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
5 * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
6 *
7 * Based upon preliminary work which is:
8 *
9 * Copyright (C) 1995 Adrian M. Rodriguez (adrian@remus.rutgers.edu)
10 */
11
12#include <linux/kernel.h>
13#include <linux/sched.h>
14#include <linux/types.h>
15#include <linux/capability.h>
16#include <linux/compat.h>
17#include <linux/mman.h>
18#include <linux/mm.h>
19#include <linux/swap.h>
20#include <linux/fs.h>
21#include <linux/file.h>
22#include <linux/resource.h>
23#include <linux/ipc.h>
24#include <linux/shm.h>
25#include <linux/msg.h>
26#include <linux/sem.h>
27#include <linux/signal.h>
28#include <linux/uio.h>
29#include <linux/utsname.h>
30#include <linux/major.h>
31#include <linux/stat.h>
32#include <linux/slab.h>
33#include <linux/pagemap.h>
34#include <linux/errno.h>
35#include <linux/smp.h>
36#include <linux/smp_lock.h>
37#include <linux/syscalls.h>
38
39#include <asm/uaccess.h>
40#include <asm/page.h>
41#include <asm/pgtable.h>
42#include <asm/pconf.h>
43#include <asm/idprom.h> /* for gethostid() */
44#include <asm/unistd.h>
45#include <asm/system.h>
46#include <asm/compat_signal.h>
47
48/* For the nfs mount emulation */
49#include <linux/socket.h>
50#include <linux/in.h>
51#include <linux/nfs.h>
52#include <linux/nfs2.h>
53#include <linux/nfs_mount.h>
54
55/* for sunos_select */
56#include <linux/time.h>
57#include <linux/personality.h>
58
59/* For SOCKET_I */
60#include <net/sock.h>
61#include <net/compat.h>
62
63#define SUNOS_NR_OPEN 256
64
65asmlinkage u32 sunos_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u32 off)
66{
67 struct file *file = NULL;
68 unsigned long retval, ret_type;
69
70 if (flags & MAP_NORESERVE) {
71 static int cnt;
72 if (cnt++ < 10)
73 printk("%s: unimplemented SunOS MAP_NORESERVE mmap() flag\n",
74 current->comm);
75 flags &= ~MAP_NORESERVE;
76 }
77 retval = -EBADF;
78 if (!(flags & MAP_ANONYMOUS)) {
79 struct inode * inode;
80 if (fd >= SUNOS_NR_OPEN)
81 goto out;
82 file = fget(fd);
83 if (!file)
84 goto out;
85 inode = file->f_path.dentry->d_inode;
86 if (imajor(inode) == MEM_MAJOR && iminor(inode) == 5) {
87 flags |= MAP_ANONYMOUS;
88 fput(file);
89 file = NULL;
90 }
91 }
92
93 retval = -EINVAL;
94 if (!(flags & MAP_FIXED))
95 addr = 0;
96 else if (len > 0xf0000000 || addr > 0xf0000000 - len)
97 goto out_putf;
98 ret_type = flags & _MAP_NEW;
99 flags &= ~_MAP_NEW;
100
101 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
102 down_write(&current->mm->mmap_sem);
103 retval = do_mmap(file,
104 (unsigned long) addr, (unsigned long) len,
105 (unsigned long) prot, (unsigned long) flags,
106 (unsigned long) off);
107 up_write(&current->mm->mmap_sem);
108 if (!ret_type)
109 retval = ((retval < 0xf0000000) ? 0 : retval);
110out_putf:
111 if (file)
112 fput(file);
113out:
114 return (u32) retval;
115}
116
117asmlinkage int sunos_mctl(u32 addr, u32 len, int function, u32 arg)
118{
119 return 0;
120}
121
122asmlinkage int sunos_brk(u32 baddr)
123{
124 int freepages, retval = -ENOMEM;
125 unsigned long rlim;
126 unsigned long newbrk, oldbrk, brk = (unsigned long) baddr;
127
128 down_write(&current->mm->mmap_sem);
129 if (brk < current->mm->end_code)
130 goto out;
131 newbrk = PAGE_ALIGN(brk);
132 oldbrk = PAGE_ALIGN(current->mm->brk);
133 retval = 0;
134 if (oldbrk == newbrk) {
135 current->mm->brk = brk;
136 goto out;
137 }
138 /* Always allow shrinking brk. */
139 if (brk <= current->mm->brk) {
140 current->mm->brk = brk;
141 do_munmap(current->mm, newbrk, oldbrk-newbrk);
142 goto out;
143 }
144 /* Check against rlimit and stack.. */
145 retval = -ENOMEM;
146 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
147 if (rlim >= RLIM_INFINITY)
148 rlim = ~0;
149 if (brk - current->mm->end_code > rlim)
150 goto out;
151 /* Check against existing mmap mappings. */
152 if (find_vma_intersection(current->mm, oldbrk, newbrk+PAGE_SIZE))
153 goto out;
154 /* stupid algorithm to decide if we have enough memory: while
155 * simple, it hopefully works in most obvious cases.. Easy to
156 * fool it, but this should catch most mistakes.
157 */
158 freepages = global_page_state(NR_FILE_PAGES);
159 freepages >>= 1;
160 freepages += nr_free_pages();
161 freepages += nr_swap_pages;
162 freepages -= num_physpages >> 4;
163 freepages -= (newbrk-oldbrk) >> PAGE_SHIFT;
164 if (freepages < 0)
165 goto out;
166 /* Ok, we have probably got enough memory - let it rip. */
167 current->mm->brk = brk;
168 do_brk(oldbrk, newbrk-oldbrk);
169 retval = 0;
170out:
171 up_write(&current->mm->mmap_sem);
172 return retval;
173}
174
175asmlinkage u32 sunos_sbrk(int increment)
176{
177 int error, oldbrk;
178
179 /* This should do it hopefully... */
180 oldbrk = (int)current->mm->brk;
181 error = sunos_brk(((int) current->mm->brk) + increment);
182 if (!error)
183 error = oldbrk;
184 return error;
185}
186
187asmlinkage u32 sunos_sstk(int increment)
188{
189 printk("%s: Call to sunos_sstk(increment<%d>) is unsupported\n",
190 current->comm, increment);
191
192 return (u32)-1;
193}
194
195/* Give hints to the kernel as to what paging strategy to use...
196 * Completely bogus, don't remind me.
197 */
198#define VA_NORMAL 0 /* Normal vm usage expected */
199#define VA_ABNORMAL 1 /* Abnormal/random vm usage probable */
200#define VA_SEQUENTIAL 2 /* Accesses will be of a sequential nature */
201#define VA_INVALIDATE 3 /* Page table entries should be flushed ??? */
202static char *vstrings[] = {
203 "VA_NORMAL",
204 "VA_ABNORMAL",
205 "VA_SEQUENTIAL",
206 "VA_INVALIDATE",
207};
208
209asmlinkage void sunos_vadvise(u32 strategy)
210{
211 static int count;
212
213 /* I wanna see who uses this... */
214 if (count++ < 5)
215 printk("%s: Advises us to use %s paging strategy\n",
216 current->comm,
217 strategy <= 3 ? vstrings[strategy] : "BOGUS");
218}
219
220/* This just wants the soft limit (ie. rlim_cur element) of the RLIMIT_NOFILE
221 * resource limit and is for backwards compatibility with older sunos
222 * revs.
223 */
224asmlinkage int sunos_getdtablesize(void)
225{
226 return SUNOS_NR_OPEN;
227}
228
229
230#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
231
232asmlinkage u32 sunos_sigblock(u32 blk_mask)
233{
234 u32 old;
235
236 spin_lock_irq(&current->sighand->siglock);
237 old = (u32) current->blocked.sig[0];
238 current->blocked.sig[0] |= (blk_mask & _BLOCKABLE);
239 recalc_sigpending();
240 spin_unlock_irq(&current->sighand->siglock);
241 return old;
242}
243
244asmlinkage u32 sunos_sigsetmask(u32 newmask)
245{
246 u32 retval;
247
248 spin_lock_irq(&current->sighand->siglock);
249 retval = (u32) current->blocked.sig[0];
250 current->blocked.sig[0] = (newmask & _BLOCKABLE);
251 recalc_sigpending();
252 spin_unlock_irq(&current->sighand->siglock);
253 return retval;
254}
255
256/* SunOS getdents is very similar to the newer Linux (iBCS2 compliant) */
257/* getdents system call, the format of the structure just has a different */
258/* layout (d_off+d_ino instead of d_ino+d_off) */
259struct sunos_dirent {
260 s32 d_off;
261 u32 d_ino;
262 u16 d_reclen;
263 u16 d_namlen;
264 char d_name[1];
265};
266
267struct sunos_dirent_callback {
268 struct sunos_dirent __user *curr;
269 struct sunos_dirent __user *previous;
270 int count;
271 int error;
272};
273
274#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))
275#define ROUND_UP(x) (((x)+sizeof(s32)-1) & ~(sizeof(s32)-1))
276
277static int sunos_filldir(void * __buf, const char * name, int namlen,
278 loff_t offset, ino_t ino, unsigned int d_type)
279{
280 struct sunos_dirent __user *dirent;
281 struct sunos_dirent_callback * buf = (struct sunos_dirent_callback *) __buf;
282 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
283 u32 d_ino;
284
285 buf->error = -EINVAL; /* only used if we fail.. */
286 if (reclen > buf->count)
287 return -EINVAL;
288 d_ino = ino;
289 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
290 return -EOVERFLOW;
291 dirent = buf->previous;
292 if (dirent)
293 put_user(offset, &dirent->d_off);
294 dirent = buf->curr;
295 buf->previous = dirent;
296 put_user(d_ino, &dirent->d_ino);
297 put_user(namlen, &dirent->d_namlen);
298 put_user(reclen, &dirent->d_reclen);
299 if (copy_to_user(dirent->d_name, name, namlen))
300 return -EFAULT;
301 put_user(0, dirent->d_name + namlen);
302 dirent = (void __user *) dirent + reclen;
303 buf->curr = dirent;
304 buf->count -= reclen;
305 return 0;
306}
307
308asmlinkage int sunos_getdents(unsigned int fd, void __user *dirent, int cnt)
309{
310 struct file * file;
311 struct sunos_dirent __user *lastdirent;
312 struct sunos_dirent_callback buf;
313 int error = -EBADF;
314
315 if (fd >= SUNOS_NR_OPEN)
316 goto out;
317
318 file = fget(fd);
319 if (!file)
320 goto out;
321
322 error = -EINVAL;
323 if (cnt < (sizeof(struct sunos_dirent) + 255))
324 goto out_putf;
325
326 buf.curr = (struct sunos_dirent __user *) dirent;
327 buf.previous = NULL;
328 buf.count = cnt;
329 buf.error = 0;
330
331 error = vfs_readdir(file, sunos_filldir, &buf);
332 if (error < 0)
333 goto out_putf;
334
335 lastdirent = buf.previous;
336 error = buf.error;
337 if (lastdirent) {
338 put_user(file->f_pos, &lastdirent->d_off);
339 error = cnt - buf.count;
340 }
341
342out_putf:
343 fput(file);
344out:
345 return error;
346}
347
348/* Old sunos getdirentries, severely broken compatibility stuff here. */
349struct sunos_direntry {
350 u32 d_ino;
351 u16 d_reclen;
352 u16 d_namlen;
353 char d_name[1];
354};
355
356struct sunos_direntry_callback {
357 struct sunos_direntry __user *curr;
358 struct sunos_direntry __user *previous;
359 int count;
360 int error;
361};
362
363static int sunos_filldirentry(void * __buf, const char * name, int namlen,
364 loff_t offset, ino_t ino, unsigned int d_type)
365{
366 struct sunos_direntry __user *dirent;
367 struct sunos_direntry_callback * buf =
368 (struct sunos_direntry_callback *) __buf;
369 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
370 u32 d_ino;
371
372 buf->error = -EINVAL; /* only used if we fail.. */
373 if (reclen > buf->count)
374 return -EINVAL;
375 d_ino = ino;
376 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
377 return -EOVERFLOW;
378 dirent = buf->previous;
379 dirent = buf->curr;
380 buf->previous = dirent;
381 put_user(d_ino, &dirent->d_ino);
382 put_user(namlen, &dirent->d_namlen);
383 put_user(reclen, &dirent->d_reclen);
384 if (copy_to_user(dirent->d_name, name, namlen))
385 return -EFAULT;
386 put_user(0, dirent->d_name + namlen);
387 dirent = (void __user *) dirent + reclen;
388 buf->curr = dirent;
389 buf->count -= reclen;
390 return 0;
391}
392
393asmlinkage int sunos_getdirentries(unsigned int fd,
394 void __user *dirent,
395 int cnt,
396 unsigned int __user *basep)
397{
398 struct file * file;
399 struct sunos_direntry __user *lastdirent;
400 int error = -EBADF;
401 struct sunos_direntry_callback buf;
402
403 if (fd >= SUNOS_NR_OPEN)
404 goto out;
405
406 file = fget(fd);
407 if (!file)
408 goto out;
409
410 error = -EINVAL;
411 if (cnt < (sizeof(struct sunos_direntry) + 255))
412 goto out_putf;
413
414 buf.curr = (struct sunos_direntry __user *) dirent;
415 buf.previous = NULL;
416 buf.count = cnt;
417 buf.error = 0;
418
419 error = vfs_readdir(file, sunos_filldirentry, &buf);
420 if (error < 0)
421 goto out_putf;
422
423 lastdirent = buf.previous;
424 error = buf.error;
425 if (lastdirent) {
426 put_user(file->f_pos, basep);
427 error = cnt - buf.count;
428 }
429
430out_putf:
431 fput(file);
432out:
433 return error;
434}
435
436struct sunos_utsname {
437 char sname[9];
438 char nname[9];
439 char nnext[56];
440 char rel[9];
441 char ver[9];
442 char mach[9];
443};
444
445asmlinkage int sunos_uname(struct sunos_utsname __user *name)
446{
447 int ret;
448
449 down_read(&uts_sem);
450 ret = copy_to_user(&name->sname[0], &utsname()->sysname[0],
451 sizeof(name->sname) - 1);
452 ret |= copy_to_user(&name->nname[0], &utsname()->nodename[0],
453 sizeof(name->nname) - 1);
454 ret |= put_user('\0', &name->nname[8]);
455 ret |= copy_to_user(&name->rel[0], &utsname()->release[0],
456 sizeof(name->rel) - 1);
457 ret |= copy_to_user(&name->ver[0], &utsname()->version[0],
458 sizeof(name->ver) - 1);
459 ret |= copy_to_user(&name->mach[0], &utsname()->machine[0],
460 sizeof(name->mach) - 1);
461 up_read(&uts_sem);
462 return (ret ? -EFAULT : 0);
463}
464
465asmlinkage int sunos_nosys(void)
466{
467 struct pt_regs *regs;
468 siginfo_t info;
469 static int cnt;
470
471 regs = current_thread_info()->kregs;
472 if (test_thread_flag(TIF_32BIT)) {
473 regs->tpc &= 0xffffffff;
474 regs->tnpc &= 0xffffffff;
475 }
476 info.si_signo = SIGSYS;
477 info.si_errno = 0;
478 info.si_code = __SI_FAULT|0x100;
479 info.si_addr = (void __user *)regs->tpc;
480 info.si_trapno = regs->u_regs[UREG_G1];
481 send_sig_info(SIGSYS, &info, current);
482 if (cnt++ < 4) {
483 printk("Process makes ni_syscall number %d, register dump:\n",
484 (int) regs->u_regs[UREG_G1]);
485 show_regs(regs);
486 }
487 return -ENOSYS;
488}
489
490/* This is not a real and complete implementation yet, just to keep
491 * the easy SunOS binaries happy.
492 */
493asmlinkage int sunos_fpathconf(int fd, int name)
494{
495 int ret;
496
497 switch(name) {
498 case _PCONF_LINK:
499 ret = LINK_MAX;
500 break;
501 case _PCONF_CANON:
502 ret = MAX_CANON;
503 break;
504 case _PCONF_INPUT:
505 ret = MAX_INPUT;
506 break;
507 case _PCONF_NAME:
508 ret = NAME_MAX;
509 break;
510 case _PCONF_PATH:
511 ret = PATH_MAX;
512 break;
513 case _PCONF_PIPE:
514 ret = PIPE_BUF;
515 break;
516 case _PCONF_CHRESTRICT: /* XXX Investigate XXX */
517 ret = 1;
518 break;
519 case _PCONF_NOTRUNC: /* XXX Investigate XXX */
520 case _PCONF_VDISABLE:
521 ret = 0;
522 break;
523 default:
524 ret = -EINVAL;
525 break;
526 }
527 return ret;
528}
529
530asmlinkage int sunos_pathconf(u32 u_path, int name)
531{
532 int ret;
533
534 ret = sunos_fpathconf(0, name); /* XXX cheese XXX */
535 return ret;
536}
537
538asmlinkage int sunos_select(int width, u32 inp, u32 outp, u32 exp, u32 tvp_x)
539{
540 int ret;
541
542 /* SunOS binaries expect that select won't change the tvp contents */
543 ret = compat_sys_select(width, compat_ptr(inp), compat_ptr(outp),
544 compat_ptr(exp), compat_ptr(tvp_x));
545 if (ret == -EINTR && tvp_x) {
546 struct compat_timeval __user *tvp = compat_ptr(tvp_x);
547 time_t sec, usec;
548
549 __get_user(sec, &tvp->tv_sec);
550 __get_user(usec, &tvp->tv_usec);
551 if (sec == 0 && usec == 0)
552 ret = 0;
553 }
554 return ret;
555}
556
557asmlinkage void sunos_nop(void)
558{
559 return;
560}
561
562#if 0 /* This code doesn't translate user pointers correctly,
563 * disable for now. -DaveM
564 */
565
566/* XXXXXXXXXX SunOS mount/umount. XXXXXXXXXXX */
567#define SMNT_RDONLY 1
568#define SMNT_NOSUID 2
569#define SMNT_NEWTYPE 4
570#define SMNT_GRPID 8
571#define SMNT_REMOUNT 16
572#define SMNT_NOSUB 32
573#define SMNT_MULTI 64
574#define SMNT_SYS5 128
575
576struct sunos_fh_t {
577 char fh_data [NFS_FHSIZE];
578};
579
580struct sunos_nfs_mount_args {
581 struct sockaddr_in *addr; /* file server address */
582 struct nfs_fh *fh; /* File handle to be mounted */
583 int flags; /* flags */
584 int wsize; /* write size in bytes */
585 int rsize; /* read size in bytes */
586 int timeo; /* initial timeout in .1 secs */
587 int retrans; /* times to retry send */
588 char *hostname; /* server's hostname */
589 int acregmin; /* attr cache file min secs */
590 int acregmax; /* attr cache file max secs */
591 int acdirmin; /* attr cache dir min secs */
592 int acdirmax; /* attr cache dir max secs */
593 char *netname; /* server's netname */
594};
595
596
597/* Bind the socket on a local reserved port and connect it to the
598 * remote server. This on Linux/i386 is done by the mount program,
599 * not by the kernel.
600 */
601/* XXXXXXXXXXXXXXXXXXXX */
602static int
603sunos_nfs_get_server_fd (int fd, struct sockaddr_in *addr)
604{
605 struct sockaddr_in local;
606 struct sockaddr_in server;
607 int try_port;
608 int ret;
609 struct socket *socket;
610 struct inode *inode;
611 struct file *file;
612
613 file = fget(fd);
614 if (!file)
615 return 0;
616
617 inode = file->f_path.dentry->d_inode;
618
619 socket = SOCKET_I(inode);
620 local.sin_family = AF_INET;
621 local.sin_addr.s_addr = htonl(INADDR_ANY);
622
623 /* IPPORT_RESERVED = 1024, can't find the definition in the kernel */
624 try_port = 1024;
625 do {
626 local.sin_port = htons (--try_port);
627 ret = socket->ops->bind(socket, (struct sockaddr*)&local,
628 sizeof(local));
629 } while (ret && try_port > (1024 / 2));
630
631 if (ret) {
632 fput(file);
633 return 0;
634 }
635
636 server.sin_family = AF_INET;
637 server.sin_addr = addr->sin_addr;
638 server.sin_port = NFS_PORT;
639
640 /* Call sys_connect */
641 ret = socket->ops->connect (socket, (struct sockaddr *) &server,
642 sizeof (server), file->f_flags);
643 fput(file);
644 if (ret < 0)
645 return 0;
646 return 1;
647}
648
649/* XXXXXXXXXXXXXXXXXXXX */
650static int get_default (int value, int def_value)
651{
652 if (value)
653 return value;
654 else
655 return def_value;
656}
657
658/* XXXXXXXXXXXXXXXXXXXX */
659static int sunos_nfs_mount(char *dir_name, int linux_flags, void __user *data)
660{
661 int server_fd, err;
662 char *the_name, *mount_page;
663 struct nfs_mount_data linux_nfs_mount;
664 struct sunos_nfs_mount_args sunos_mount;
665
666 /* Ok, here comes the fun part: Linux's nfs mount needs a
667 * socket connection to the server, but SunOS mount does not
668 * require this, so we use the information on the destination
669 * address to create a socket and bind it to a reserved
670 * port on this system
671 */
672 if (copy_from_user(&sunos_mount, data, sizeof(sunos_mount)))
673 return -EFAULT;
674
675 server_fd = sys_socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
676 if (server_fd < 0)
677 return -ENXIO;
678
679 if (copy_from_user(&linux_nfs_mount.addr, sunos_mount.addr,
680 sizeof(*sunos_mount.addr)) ||
681 copy_from_user(&linux_nfs_mount.root, sunos_mount.fh,
682 sizeof(*sunos_mount.fh))) {
683 sys_close (server_fd);
684 return -EFAULT;
685 }
686
687 if (!sunos_nfs_get_server_fd (server_fd, &linux_nfs_mount.addr)){
688 sys_close (server_fd);
689 return -ENXIO;
690 }
691
692 /* Now, bind it to a locally reserved port */
693 linux_nfs_mount.version = NFS_MOUNT_VERSION;
694 linux_nfs_mount.flags = sunos_mount.flags;
695 linux_nfs_mount.fd = server_fd;
696
697 linux_nfs_mount.rsize = get_default (sunos_mount.rsize, 8192);
698 linux_nfs_mount.wsize = get_default (sunos_mount.wsize, 8192);
699 linux_nfs_mount.timeo = get_default (sunos_mount.timeo, 10);
700 linux_nfs_mount.retrans = sunos_mount.retrans;
701
702 linux_nfs_mount.acregmin = sunos_mount.acregmin;
703 linux_nfs_mount.acregmax = sunos_mount.acregmax;
704 linux_nfs_mount.acdirmin = sunos_mount.acdirmin;
705 linux_nfs_mount.acdirmax = sunos_mount.acdirmax;
706
707 the_name = getname(sunos_mount.hostname);
708 if (IS_ERR(the_name))
709 return PTR_ERR(the_name);
710
711 strlcpy(linux_nfs_mount.hostname, the_name,
712 sizeof(linux_nfs_mount.hostname));
713 putname (the_name);
714
715 mount_page = (char *) get_zeroed_page(GFP_KERNEL);
716 if (!mount_page)
717 return -ENOMEM;
718
719 memcpy(mount_page, &linux_nfs_mount, sizeof(linux_nfs_mount));
720
721 err = do_mount("", dir_name, "nfs", linux_flags, mount_page);
722
723 free_page((unsigned long) mount_page);
724 return err;
725}
726
727/* XXXXXXXXXXXXXXXXXXXX */
728asmlinkage int
729sunos_mount(char *type, char *dir, int flags, void *data)
730{
731 int linux_flags = 0;
732 int ret = -EINVAL;
733 char *dev_fname = 0;
734 char *dir_page, *type_page;
735
736 if (!capable (CAP_SYS_ADMIN))
737 return -EPERM;
738
739 /* We don't handle the integer fs type */
740 if ((flags & SMNT_NEWTYPE) == 0)
741 goto out;
742
743 /* Do not allow for those flags we don't support */
744 if (flags & (SMNT_GRPID|SMNT_NOSUB|SMNT_MULTI|SMNT_SYS5))
745 goto out;
746
747 if (flags & SMNT_REMOUNT)
748 linux_flags |= MS_REMOUNT;
749 if (flags & SMNT_RDONLY)
750 linux_flags |= MS_RDONLY;
751 if (flags & SMNT_NOSUID)
752 linux_flags |= MS_NOSUID;
753
754 dir_page = getname(dir);
755 ret = PTR_ERR(dir_page);
756 if (IS_ERR(dir_page))
757 goto out;
758
759 type_page = getname(type);
760 ret = PTR_ERR(type_page);
761 if (IS_ERR(type_page))
762 goto out1;
763
764 if (strcmp(type_page, "ext2") == 0) {
765 dev_fname = getname(data);
766 } else if (strcmp(type_page, "iso9660") == 0) {
767 dev_fname = getname(data);
768 } else if (strcmp(type_page, "minix") == 0) {
769 dev_fname = getname(data);
770 } else if (strcmp(type_page, "nfs") == 0) {
771 ret = sunos_nfs_mount (dir_page, flags, data);
772 goto out2;
773 } else if (strcmp(type_page, "ufs") == 0) {
774 printk("Warning: UFS filesystem mounts unsupported.\n");
775 ret = -ENODEV;
776 goto out2;
777 } else if (strcmp(type_page, "proc")) {
778 ret = -ENODEV;
779 goto out2;
780 }
781 ret = PTR_ERR(dev_fname);
782 if (IS_ERR(dev_fname))
783 goto out2;
784 lock_kernel();
785 ret = do_mount(dev_fname, dir_page, type_page, linux_flags, NULL);
786 unlock_kernel();
787 if (dev_fname)
788 putname(dev_fname);
789out2:
790 putname(type_page);
791out1:
792 putname(dir_page);
793out:
794 return ret;
795}
796#endif
797
798asmlinkage int sunos_setpgrp(pid_t pid, pid_t pgid)
799{
800 int ret;
801
802 /* So stupid... */
803 if ((!pid || pid == current->pid) &&
804 !pgid) {
805 sys_setsid();
806 ret = 0;
807 } else {
808 ret = sys_setpgid(pid, pgid);
809 }
810 return ret;
811}
812
813/* So stupid... */
814extern long compat_sys_wait4(compat_pid_t, compat_uint_t __user *, int,
815 struct compat_rusage __user *);
816
817asmlinkage int sunos_wait4(compat_pid_t pid, compat_uint_t __user *stat_addr, int options, struct compat_rusage __user *ru)
818{
819 int ret;
820
821 ret = compat_sys_wait4((pid ? pid : ((compat_pid_t)-1)),
822 stat_addr, options, ru);
823 return ret;
824}
825
826asmlinkage int sunos_killpg(int pgrp, int sig)
827{
828 int ret;
829
830 rcu_read_lock();
831 ret = -EINVAL;
832 if (pgrp > 0)
833 ret = kill_pgrp(find_vpid(pgrp), sig, 0);
834 rcu_read_unlock();
835
836 return ret;
837}
838
839asmlinkage int sunos_audit(void)
840{
841 printk ("sys_audit\n");
842 return -1;
843}
844
845asmlinkage u32 sunos_gethostid(void)
846{
847 u32 ret;
848
849 ret = (((u32)idprom->id_machtype << 24) | ((u32)idprom->id_sernum));
850
851 return ret;
852}
853
854/* sysconf options, for SunOS compatibility */
855#define _SC_ARG_MAX 1
856#define _SC_CHILD_MAX 2
857#define _SC_CLK_TCK 3
858#define _SC_NGROUPS_MAX 4
859#define _SC_OPEN_MAX 5
860#define _SC_JOB_CONTROL 6
861#define _SC_SAVED_IDS 7
862#define _SC_VERSION 8
863
864asmlinkage s32 sunos_sysconf (int name)
865{
866 s32 ret;
867
868 switch (name){
869 case _SC_ARG_MAX:
870 ret = ARG_MAX;
871 break;
872 case _SC_CHILD_MAX:
873 ret = current->signal->rlim[RLIMIT_NPROC].rlim_cur;
874 break;
875 case _SC_CLK_TCK:
876 ret = HZ;
877 break;
878 case _SC_NGROUPS_MAX:
879 ret = NGROUPS_MAX;
880 break;
881 case _SC_OPEN_MAX:
882 ret = current->signal->rlim[RLIMIT_NOFILE].rlim_cur;
883 break;
884 case _SC_JOB_CONTROL:
885 ret = 1; /* yes, we do support job control */
886 break;
887 case _SC_SAVED_IDS:
888 ret = 1; /* yes, we do support saved uids */
889 break;
890 case _SC_VERSION:
891 /* mhm, POSIX_VERSION is in /usr/include/unistd.h
892 * should it go on /usr/include/linux?
893 */
894 ret = 199009;
895 break;
896 default:
897 ret = -1;
898 break;
899 };
900 return ret;
901}
902
903asmlinkage int sunos_semsys(int op, u32 arg1, u32 arg2, u32 arg3, void __user *ptr)
904{
905 union semun arg4;
906 int ret;
907
908 switch (op) {
909 case 0:
910 /* Most arguments match on a 1:1 basis but cmd doesn't */
911 switch(arg3) {
912 case 4:
913 arg3=GETPID; break;
914 case 5:
915 arg3=GETVAL; break;
916 case 6:
917 arg3=GETALL; break;
918 case 3:
919 arg3=GETNCNT; break;
920 case 7:
921 arg3=GETZCNT; break;
922 case 8:
923 arg3=SETVAL; break;
924 case 9:
925 arg3=SETALL; break;
926 }
927 /* sys_semctl(): */
928 /* value to modify semaphore to */
929 arg4.__pad = ptr;
930 ret = sys_semctl((int)arg1, (int)arg2, (int)arg3, arg4);
931 break;
932 case 1:
933 /* sys_semget(): */
934 ret = sys_semget((key_t)arg1, (int)arg2, (int)arg3);
935 break;
936 case 2:
937 /* sys_semop(): */
938 ret = sys_semop((int)arg1, (struct sembuf __user *)(unsigned long)arg2,
939 (unsigned int) arg3);
940 break;
941 default:
942 ret = -EINVAL;
943 break;
944 };
945 return ret;
946}
947
948struct msgbuf32 {
949 s32 mtype;
950 char mtext[1];
951};
952
953struct ipc_perm32
954{
955 key_t key;
956 compat_uid_t uid;
957 compat_gid_t gid;
958 compat_uid_t cuid;
959 compat_gid_t cgid;
960 compat_mode_t mode;
961 unsigned short seq;
962};
963
964struct msqid_ds32
965{
966 struct ipc_perm32 msg_perm;
967 u32 msg_first;
968 u32 msg_last;
969 compat_time_t msg_stime;
970 compat_time_t msg_rtime;
971 compat_time_t msg_ctime;
972 u32 wwait;
973 u32 rwait;
974 unsigned short msg_cbytes;
975 unsigned short msg_qnum;
976 unsigned short msg_qbytes;
977 compat_ipc_pid_t msg_lspid;
978 compat_ipc_pid_t msg_lrpid;
979};
980
981static inline int sunos_msqid_get(struct msqid_ds32 __user *user,
982 struct msqid_ds *kern)
983{
984 if (get_user(kern->msg_perm.key, &user->msg_perm.key) ||
985 __get_user(kern->msg_perm.uid, &user->msg_perm.uid) ||
986 __get_user(kern->msg_perm.gid, &user->msg_perm.gid) ||
987 __get_user(kern->msg_perm.cuid, &user->msg_perm.cuid) ||
988 __get_user(kern->msg_perm.cgid, &user->msg_perm.cgid) ||
989 __get_user(kern->msg_stime, &user->msg_stime) ||
990 __get_user(kern->msg_rtime, &user->msg_rtime) ||
991 __get_user(kern->msg_ctime, &user->msg_ctime) ||
992 __get_user(kern->msg_ctime, &user->msg_cbytes) ||
993 __get_user(kern->msg_ctime, &user->msg_qnum) ||
994 __get_user(kern->msg_ctime, &user->msg_qbytes) ||
995 __get_user(kern->msg_ctime, &user->msg_lspid) ||
996 __get_user(kern->msg_ctime, &user->msg_lrpid))
997 return -EFAULT;
998 return 0;
999}
1000
1001static inline int sunos_msqid_put(struct msqid_ds32 __user *user,
1002 struct msqid_ds *kern)
1003{
1004 if (put_user(kern->msg_perm.key, &user->msg_perm.key) ||
1005 __put_user(kern->msg_perm.uid, &user->msg_perm.uid) ||
1006 __put_user(kern->msg_perm.gid, &user->msg_perm.gid) ||
1007 __put_user(kern->msg_perm.cuid, &user->msg_perm.cuid) ||
1008 __put_user(kern->msg_perm.cgid, &user->msg_perm.cgid) ||
1009 __put_user(kern->msg_stime, &user->msg_stime) ||
1010 __put_user(kern->msg_rtime, &user->msg_rtime) ||
1011 __put_user(kern->msg_ctime, &user->msg_ctime) ||
1012 __put_user(kern->msg_ctime, &user->msg_cbytes) ||
1013 __put_user(kern->msg_ctime, &user->msg_qnum) ||
1014 __put_user(kern->msg_ctime, &user->msg_qbytes) ||
1015 __put_user(kern->msg_ctime, &user->msg_lspid) ||
1016 __put_user(kern->msg_ctime, &user->msg_lrpid))
1017 return -EFAULT;
1018 return 0;
1019}
1020
1021static inline int sunos_msgbuf_get(struct msgbuf32 __user *user, struct msgbuf *kern, int len)
1022{
1023 if (get_user(kern->mtype, &user->mtype) ||
1024 __copy_from_user(kern->mtext, &user->mtext, len))
1025 return -EFAULT;
1026 return 0;
1027}
1028
1029static inline int sunos_msgbuf_put(struct msgbuf32 __user *user, struct msgbuf *kern, int len)
1030{
1031 if (put_user(kern->mtype, &user->mtype) ||
1032 __copy_to_user(user->mtext, kern->mtext, len))
1033 return -EFAULT;
1034 return 0;
1035}
1036
1037asmlinkage int sunos_msgsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
1038{
1039 struct sparc_stackf32 __user *sp;
1040 struct msqid_ds kds;
1041 struct msgbuf *kmbuf;
1042 mm_segment_t old_fs = get_fs();
1043 u32 arg5;
1044 int rval;
1045
1046 switch(op) {
1047 case 0:
1048 rval = sys_msgget((key_t)arg1, (int)arg2);
1049 break;
1050 case 1:
1051 if (!sunos_msqid_get((struct msqid_ds32 __user *)(unsigned long)arg3, &kds)) {
1052 set_fs(KERNEL_DS);
1053 rval = sys_msgctl((int)arg1, (int)arg2,
1054 (struct msqid_ds __user *)(unsigned long)arg3);
1055 set_fs(old_fs);
1056 if (!rval)
1057 rval = sunos_msqid_put((struct msqid_ds32 __user *)(unsigned long)arg3,
1058 &kds);
1059 } else
1060 rval = -EFAULT;
1061 break;
1062 case 2:
1063 rval = -EFAULT;
1064 kmbuf = kmalloc(sizeof(struct msgbuf) + arg3,
1065 GFP_KERNEL);
1066 if (!kmbuf)
1067 break;
1068 sp = (struct sparc_stackf32 __user *)
1069 (current_thread_info()->kregs->u_regs[UREG_FP] & 0xffffffffUL);
1070 if (get_user(arg5, &sp->xxargs[0])) {
1071 rval = -EFAULT;
1072 kfree(kmbuf);
1073 break;
1074 }
1075 set_fs(KERNEL_DS);
1076 rval = sys_msgrcv((int)arg1, (struct msgbuf __user *) kmbuf,
1077 (size_t)arg3,
1078 (long)arg4, (int)arg5);
1079 set_fs(old_fs);
1080 if (!rval)
1081 rval = sunos_msgbuf_put((struct msgbuf32 __user *)(unsigned long)arg2,
1082 kmbuf, arg3);
1083 kfree(kmbuf);
1084 break;
1085 case 3:
1086 rval = -EFAULT;
1087 kmbuf = kmalloc(sizeof(struct msgbuf) + arg3,
1088 GFP_KERNEL);
1089 if (!kmbuf || sunos_msgbuf_get((struct msgbuf32 __user *)(unsigned long)arg2,
1090 kmbuf, arg3))
1091 break;
1092 set_fs(KERNEL_DS);
1093 rval = sys_msgsnd((int)arg1, (struct msgbuf __user *) kmbuf,
1094 (size_t)arg3, (int)arg4);
1095 set_fs(old_fs);
1096 kfree(kmbuf);
1097 break;
1098 default:
1099 rval = -EINVAL;
1100 break;
1101 }
1102 return rval;
1103}
1104
1105struct shmid_ds32 {
1106 struct ipc_perm32 shm_perm;
1107 int shm_segsz;
1108 compat_time_t shm_atime;
1109 compat_time_t shm_dtime;
1110 compat_time_t shm_ctime;
1111 compat_ipc_pid_t shm_cpid;
1112 compat_ipc_pid_t shm_lpid;
1113 unsigned short shm_nattch;
1114};
1115
1116static inline int sunos_shmid_get(struct shmid_ds32 __user *user,
1117 struct shmid_ds *kern)
1118{
1119 if (get_user(kern->shm_perm.key, &user->shm_perm.key) ||
1120 __get_user(kern->shm_perm.uid, &user->shm_perm.uid) ||
1121 __get_user(kern->shm_perm.gid, &user->shm_perm.gid) ||
1122 __get_user(kern->shm_perm.cuid, &user->shm_perm.cuid) ||
1123 __get_user(kern->shm_perm.cgid, &user->shm_perm.cgid) ||
1124 __get_user(kern->shm_segsz, &user->shm_segsz) ||
1125 __get_user(kern->shm_atime, &user->shm_atime) ||
1126 __get_user(kern->shm_dtime, &user->shm_dtime) ||
1127 __get_user(kern->shm_ctime, &user->shm_ctime) ||
1128 __get_user(kern->shm_cpid, &user->shm_cpid) ||
1129 __get_user(kern->shm_lpid, &user->shm_lpid) ||
1130 __get_user(kern->shm_nattch, &user->shm_nattch))
1131 return -EFAULT;
1132 return 0;
1133}
1134
1135static inline int sunos_shmid_put(struct shmid_ds32 __user *user,
1136 struct shmid_ds *kern)
1137{
1138 if (put_user(kern->shm_perm.key, &user->shm_perm.key) ||
1139 __put_user(kern->shm_perm.uid, &user->shm_perm.uid) ||
1140 __put_user(kern->shm_perm.gid, &user->shm_perm.gid) ||
1141 __put_user(kern->shm_perm.cuid, &user->shm_perm.cuid) ||
1142 __put_user(kern->shm_perm.cgid, &user->shm_perm.cgid) ||
1143 __put_user(kern->shm_segsz, &user->shm_segsz) ||
1144 __put_user(kern->shm_atime, &user->shm_atime) ||
1145 __put_user(kern->shm_dtime, &user->shm_dtime) ||
1146 __put_user(kern->shm_ctime, &user->shm_ctime) ||
1147 __put_user(kern->shm_cpid, &user->shm_cpid) ||
1148 __put_user(kern->shm_lpid, &user->shm_lpid) ||
1149 __put_user(kern->shm_nattch, &user->shm_nattch))
1150 return -EFAULT;
1151 return 0;
1152}
1153
1154asmlinkage int sunos_shmsys(int op, u32 arg1, u32 arg2, u32 arg3)
1155{
1156 struct shmid_ds ksds;
1157 unsigned long raddr;
1158 mm_segment_t old_fs = get_fs();
1159 int rval;
1160
1161 switch(op) {
1162 case 0:
1163 /* do_shmat(): attach a shared memory area */
1164 rval = do_shmat((int)arg1,(char __user *)(unsigned long)arg2,(int)arg3,&raddr);
1165 if (!rval)
1166 rval = (int) raddr;
1167 break;
1168 case 1:
1169 /* sys_shmctl(): modify shared memory area attr. */
1170 if (!sunos_shmid_get((struct shmid_ds32 __user *)(unsigned long)arg3, &ksds)) {
1171 set_fs(KERNEL_DS);
1172 rval = sys_shmctl((int) arg1,(int) arg2,
1173 (struct shmid_ds __user *) &ksds);
1174 set_fs(old_fs);
1175 if (!rval)
1176 rval = sunos_shmid_put((struct shmid_ds32 __user *)(unsigned long)arg3,
1177 &ksds);
1178 } else
1179 rval = -EFAULT;
1180 break;
1181 case 2:
1182 /* sys_shmdt(): detach a shared memory area */
1183 rval = sys_shmdt((char __user *)(unsigned long)arg1);
1184 break;
1185 case 3:
1186 /* sys_shmget(): get a shared memory area */
1187 rval = sys_shmget((key_t)arg1,(int)arg2,(int)arg3);
1188 break;
1189 default:
1190 rval = -EINVAL;
1191 break;
1192 };
1193 return rval;
1194}
1195
1196extern asmlinkage long sparc32_open(const char __user * filename, int flags, int mode);
1197
1198asmlinkage int sunos_open(u32 fname, int flags, int mode)
1199{
1200 const char __user *filename = compat_ptr(fname);
1201
1202 return sparc32_open(filename, flags, mode);
1203}
1204
1205#define SUNOS_EWOULDBLOCK 35
1206
1207/* see the sunos man page read(2v) for an explanation
1208 of this garbage. We use O_NDELAY to mark
1209 file descriptors that have been set non-blocking
1210 using 4.2BSD style calls. (tridge) */
1211
1212static inline int check_nonblock(int ret, int fd)
1213{
1214 if (ret == -EAGAIN) {
1215 struct file * file = fget(fd);
1216 if (file) {
1217 if (file->f_flags & O_NDELAY)
1218 ret = -SUNOS_EWOULDBLOCK;
1219 fput(file);
1220 }
1221 }
1222 return ret;
1223}
1224
1225asmlinkage int sunos_read(unsigned int fd, char __user *buf, u32 count)
1226{
1227 int ret;
1228
1229 ret = check_nonblock(sys_read(fd, buf, count), fd);
1230 return ret;
1231}
1232
1233asmlinkage int sunos_readv(u32 fd, void __user *vector, s32 count)
1234{
1235 int ret;
1236
1237 ret = check_nonblock(compat_sys_readv(fd, vector, count), fd);
1238 return ret;
1239}
1240
1241asmlinkage int sunos_write(unsigned int fd, char __user *buf, u32 count)
1242{
1243 int ret;
1244
1245 ret = check_nonblock(sys_write(fd, buf, count), fd);
1246 return ret;
1247}
1248
1249asmlinkage int sunos_writev(u32 fd, void __user *vector, s32 count)
1250{
1251 int ret;
1252
1253 ret = check_nonblock(compat_sys_writev(fd, vector, count), fd);
1254 return ret;
1255}
1256
1257asmlinkage int sunos_recv(u32 __fd, void __user *ubuf, int size, unsigned flags)
1258{
1259 int ret, fd = (int) __fd;
1260
1261 ret = check_nonblock(sys_recv(fd, ubuf, size, flags), fd);
1262 return ret;
1263}
1264
1265asmlinkage int sunos_send(u32 __fd, void __user *buff, int len, unsigned flags)
1266{
1267 int ret, fd = (int) __fd;
1268
1269 ret = check_nonblock(sys_send(fd, buff, len, flags), fd);
1270 return ret;
1271}
1272
1273asmlinkage int sunos_accept(u32 __fd, struct sockaddr __user *sa, int __user *addrlen)
1274{
1275 int ret, fd = (int) __fd;
1276
1277 while (1) {
1278 ret = check_nonblock(sys_accept(fd, sa, addrlen), fd);
1279 if (ret != -ENETUNREACH && ret != -EHOSTUNREACH)
1280 break;
1281 }
1282 return ret;
1283}
1284
1285#define SUNOS_SV_INTERRUPT 2
1286
1287asmlinkage int sunos_sigaction (int sig,
1288 struct old_sigaction32 __user *act,
1289 struct old_sigaction32 __user *oact)
1290{
1291 struct k_sigaction new_ka, old_ka;
1292 int ret;
1293
1294 if (act) {
1295 compat_old_sigset_t mask;
1296 u32 u_handler;
1297
1298 if (get_user(u_handler, &act->sa_handler) ||
1299 __get_user(new_ka.sa.sa_flags, &act->sa_flags))
1300 return -EFAULT;
1301 new_ka.sa.sa_handler = compat_ptr(u_handler);
1302 __get_user(mask, &act->sa_mask);
1303 new_ka.sa.sa_restorer = NULL;
1304 new_ka.ka_restorer = NULL;
1305 siginitset(&new_ka.sa.sa_mask, mask);
1306 new_ka.sa.sa_flags ^= SUNOS_SV_INTERRUPT;
1307 }
1308
1309 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
1310
1311 if (!ret && oact) {
1312 old_ka.sa.sa_flags ^= SUNOS_SV_INTERRUPT;
1313 if (put_user(ptr_to_compat(old_ka.sa.sa_handler), &oact->sa_handler) ||
1314 __put_user(old_ka.sa.sa_flags, &oact->sa_flags))
1315 return -EFAULT;
1316 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
1317 }
1318
1319 return ret;
1320}
1321
1322asmlinkage int sunos_setsockopt(u32 __fd, u32 __level, u32 __optname,
1323 char __user *optval, u32 __optlen)
1324{
1325 int fd = (int) __fd;
1326 int level = (int) __level;
1327 int optname = (int) __optname;
1328 int optlen = (int) __optlen;
1329 int tr_opt = optname;
1330 int ret;
1331
1332 if (level == SOL_IP) {
1333 /* Multicast socketopts (ttl, membership) */
1334 if (tr_opt >=2 && tr_opt <= 6)
1335 tr_opt += 30;
1336 }
1337 ret = sys_setsockopt(fd, level, tr_opt,
1338 optval, optlen);
1339 return ret;
1340}
1341
1342asmlinkage int sunos_getsockopt(u32 __fd, u32 __level, u32 __optname,
1343 char __user *optval, int __user *optlen)
1344{
1345 int fd = (int) __fd;
1346 int level = (int) __level;
1347 int optname = (int) __optname;
1348 int tr_opt = optname;
1349 int ret;
1350
1351 if (level == SOL_IP) {
1352 /* Multicast socketopts (ttl, membership) */
1353 if (tr_opt >=2 && tr_opt <= 6)
1354 tr_opt += 30;
1355 }
1356 ret = compat_sys_getsockopt(fd, level, tr_opt,
1357 optval, optlen);
1358 return ret;
1359}
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S
index 6b9b718e24af..a4fef2ba1ae1 100644
--- a/arch/sparc64/kernel/systbls.S
+++ b/arch/sparc64/kernel/systbls.S
@@ -155,125 +155,3 @@ sys_call_table:
155 .word sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait 155 .word sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait
156/*310*/ .word sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate 156/*310*/ .word sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate
157 .word sys_timerfd_settime, sys_timerfd_gettime 157 .word sys_timerfd_settime, sys_timerfd_gettime
158
159#if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \
160 defined(CONFIG_SOLARIS_EMUL_MODULE)
161 /* Now the 32-bit SunOS syscall table. */
162
163 .align 4
164 .globl sunos_sys_table
165sunos_sys_table:
166/*0*/ .word sunos_indir, sys32_exit, sys_fork
167 .word sunos_read, sunos_write, sunos_open
168 .word sys_close, sunos_wait4, sys_creat
169 .word sys_link, sys_unlink, sunos_execv
170 .word sys_chdir, sunos_nosys, sys32_mknod
171 .word sys_chmod, sys32_lchown16, sunos_brk
172 .word sunos_nosys, sys32_lseek, sunos_getpid
173 .word sunos_nosys, sunos_nosys, sunos_nosys
174 .word sunos_getuid, sunos_nosys, sys_ptrace
175 .word sunos_nosys, sunos_nosys, sunos_nosys
176 .word sunos_nosys, sunos_nosys, sunos_nosys
177 .word sys_access, sunos_nosys, sunos_nosys
178 .word sys_sync, sys_kill, compat_sys_newstat
179 .word sunos_nosys, compat_sys_newlstat, sys_dup
180 .word sys_pipe, sunos_nosys, sunos_nosys
181 .word sunos_nosys, sunos_nosys, sunos_getgid
182 .word sunos_nosys, sunos_nosys
183/*50*/ .word sunos_nosys, sys_acct, sunos_nosys
184 .word sunos_mctl, sunos_ioctl, sys_reboot
185 .word sunos_nosys, sys_symlink, sys_readlink
186 .word sys32_execve, sys_umask, sys_chroot
187 .word compat_sys_newfstat, sunos_nosys, sys_getpagesize
188 .word sys_msync, sys_vfork, sunos_nosys
189 .word sunos_nosys, sunos_sbrk, sunos_sstk
190 .word sunos_mmap, sunos_vadvise, sys_munmap
191 .word sys_mprotect, sys_madvise, sys_vhangup
192 .word sunos_nosys, sys_mincore, sys32_getgroups16
193 .word sys32_setgroups16, sys_getpgrp, sunos_setpgrp
194 .word compat_sys_setitimer, sunos_nosys, sys_swapon
195 .word compat_sys_getitimer, sys_gethostname, sys_sethostname
196 .word sunos_getdtablesize, sys_dup2, sunos_nop
197 .word compat_sys_fcntl, sunos_select, sunos_nop
198 .word sys_fsync, sys32_setpriority, sys32_socket
199 .word sys32_connect, sunos_accept
200/*100*/ .word sys_getpriority, sunos_send, sunos_recv
201 .word sunos_nosys, sys32_bind, sunos_setsockopt
202 .word sys32_listen, sunos_nosys, sunos_sigaction
203 .word sunos_sigblock, sunos_sigsetmask, sys_sigpause
204 .word sys32_sigstack, sys32_recvmsg, sys32_sendmsg
205 .word sunos_nosys, sys32_gettimeofday, compat_sys_getrusage
206 .word sunos_getsockopt, sunos_nosys, sunos_readv
207 .word sunos_writev, sys32_settimeofday, sys32_fchown16
208 .word sys_fchmod, sys32_recvfrom, sys32_setreuid16
209 .word sys32_setregid16, sys_rename, sys_truncate
210 .word sys_ftruncate, sys_flock, sunos_nosys
211 .word sys32_sendto, sys32_shutdown, sys32_socketpair
212 .word sys_mkdir, sys_rmdir, sys32_utimes
213 .word sys32_sigreturn, sunos_nosys, sys32_getpeername
214 .word sunos_gethostid, sunos_nosys, compat_sys_getrlimit
215 .word compat_sys_setrlimit, sunos_killpg, sunos_nosys
216 .word sunos_nosys, sunos_nosys
217/*150*/ .word sys32_getsockname, sunos_nosys, sunos_nosys
218 .word sys_poll, sunos_nosys, sunos_nosys
219 .word sunos_getdirentries, compat_sys_statfs, compat_sys_fstatfs
220 .word sys_oldumount, sunos_nosys, sunos_nosys
221 .word sys_getdomainname, sys_setdomainname
222 .word sunos_nosys, sys_quotactl, sunos_nosys
223 .word sunos_nosys, sys_ustat, sunos_semsys
224 .word sunos_nosys, sunos_shmsys, sunos_audit
225 .word sunos_nosys, sunos_getdents, sys_setsid
226 .word sys_fchdir, sunos_nosys, sunos_nosys
227 .word sunos_nosys, sunos_nosys, sunos_nosys
228 .word sunos_nosys, compat_sys_sigpending, sunos_nosys
229 .word sys_setpgid, sunos_pathconf, sunos_fpathconf
230 .word sunos_sysconf, sunos_uname, sunos_nosys
231 .word sunos_nosys, sunos_nosys, sunos_nosys
232 .word sunos_nosys, sunos_nosys, sunos_nosys
233 .word sunos_nosys, sunos_nosys, sunos_nosys
234/*200*/ .word sunos_nosys, sunos_nosys, sunos_nosys
235 .word sunos_nosys, sunos_nosys, sunos_nosys
236 .word sunos_nosys, sunos_nosys, sunos_nosys
237 .word sunos_nosys, sunos_nosys, sunos_nosys
238 .word sunos_nosys, sunos_nosys, sunos_nosys
239 .word sunos_nosys, sunos_nosys, sunos_nosys
240 .word sunos_nosys, sunos_nosys, sunos_nosys
241 .word sunos_nosys, sunos_nosys, sunos_nosys
242 .word sunos_nosys, sunos_nosys, sunos_nosys
243 .word sunos_nosys, sunos_nosys, sunos_nosys
244 .word sunos_nosys, sunos_nosys, sunos_nosys
245 .word sunos_nosys, sunos_nosys, sunos_nosys
246 .word sunos_nosys, sunos_nosys, sunos_nosys
247 .word sunos_nosys, sunos_nosys, sunos_nosys
248 .word sunos_nosys, sunos_nosys, sunos_nosys
249 .word sunos_nosys, sunos_nosys, sunos_nosys
250 .word sunos_nosys, sunos_nosys
251/*250*/ .word sunos_nosys, sunos_nosys, sunos_nosys
252 .word sunos_nosys, sunos_nosys, sunos_nosys
253 .word sunos_nosys, sunos_nosys, sunos_nosys
254 .word sunos_nosys
255/*260*/ .word sunos_nosys, sunos_nosys, sunos_nosys
256 .word sunos_nosys, sunos_nosys, sunos_nosys
257 .word sunos_nosys, sunos_nosys, sunos_nosys
258 .word sunos_nosys
259/*270*/ .word sunos_nosys, sunos_nosys, sunos_nosys
260 .word sunos_nosys, sunos_nosys, sunos_nosys
261 .word sunos_nosys, sunos_nosys, sunos_nosys
262 .word sunos_nosys
263/*280*/ .word sunos_nosys, sunos_nosys, sunos_nosys
264 .word sunos_nosys, sunos_nosys, sunos_nosys
265 .word sunos_nosys, sunos_nosys, sunos_nosys
266 .word sunos_nosys
267/*290*/ .word sunos_nosys, sunos_nosys, sunos_nosys
268 .word sunos_nosys, sunos_nosys, sunos_nosys
269 .word sunos_nosys, sunos_nosys, sunos_nosys
270 .word sunos_nosys
271/*300*/ .word sunos_nosys, sunos_nosys, sunos_nosys
272 .word sunos_nosys, sunos_nosys, sunos_nosys
273 .word sunos_nosys, sunos_nosys, sunos_nosys
274 .word sunos_nosys
275/*310*/ .word sunos_nosys, sunos_nosys, sunos_nosys
276 .word sunos_nosys, sunos_nosys, sunos_nosys
277 .word sunos_nosys
278
279#endif
diff --git a/arch/sparc64/kernel/systbls.h b/arch/sparc64/kernel/systbls.h
index 8a0d20a35d0c..bc9f5dac4069 100644
--- a/arch/sparc64/kernel/systbls.h
+++ b/arch/sparc64/kernel/systbls.h
@@ -27,8 +27,6 @@ extern asmlinkage unsigned long sys64_mremap(unsigned long addr,
27 unsigned long new_addr); 27 unsigned long new_addr);
28extern asmlinkage unsigned long c_sys_nis_syscall(struct pt_regs *regs); 28extern asmlinkage unsigned long c_sys_nis_syscall(struct pt_regs *regs);
29extern asmlinkage long sys_getdomainname(char __user *name, int len); 29extern asmlinkage long sys_getdomainname(char __user *name, int len);
30extern asmlinkage long solaris_syscall(struct pt_regs *regs);
31extern asmlinkage long sunos_syscall(struct pt_regs *regs);
32extern asmlinkage long sys_utrap_install(utrap_entry_t type, 30extern asmlinkage long sys_utrap_install(utrap_entry_t type,
33 utrap_handler_t new_p, 31 utrap_handler_t new_p,
34 utrap_handler_t new_d, 32 utrap_handler_t new_d,
diff --git a/arch/sparc64/kernel/ttable.S b/arch/sparc64/kernel/ttable.S
index 7575aa371da8..b0de4c00b11a 100644
--- a/arch/sparc64/kernel/ttable.S
+++ b/arch/sparc64/kernel/ttable.S
@@ -117,16 +117,13 @@ tl0_f4o: FILL_4_OTHER
117tl0_f5o: FILL_5_OTHER 117tl0_f5o: FILL_5_OTHER
118tl0_f6o: FILL_6_OTHER 118tl0_f6o: FILL_6_OTHER
119tl0_f7o: FILL_7_OTHER 119tl0_f7o: FILL_7_OTHER
120tl0_sunos: SUNOS_SYSCALL_TRAP 120tl0_resv100: BTRAP(0x100)
121tl0_bkpt: BREAKPOINT_TRAP 121tl0_bkpt: BREAKPOINT_TRAP
122tl0_divz: TRAP(do_div0) 122tl0_divz: TRAP(do_div0)
123tl0_flushw: FLUSH_WINDOW_TRAP 123tl0_flushw: FLUSH_WINDOW_TRAP
124tl0_resv104: BTRAP(0x104) BTRAP(0x105) BTRAP(0x106) BTRAP(0x107) 124tl0_resv104: BTRAP(0x104) BTRAP(0x105) BTRAP(0x106) BTRAP(0x107) BTRAP(0x108)
125 .globl tl0_solaris 125tl0_resv109: BTRAP(0x109) BTRAP(0x10a) BTRAP(0x10b) BTRAP(0x10c) BTRAP(0x10d)
126tl0_solaris: SOLARIS_SYSCALL_TRAP 126tl0_resv10e: BTRAP(0x10e) BTRAP(0x10f)
127tl0_resv109: BTRAP(0x109)
128tl0_resv10a: BTRAP(0x10a) BTRAP(0x10b) BTRAP(0x10c) BTRAP(0x10d) BTRAP(0x10e)
129tl0_resv10f: BTRAP(0x10f)
130tl0_linux32: LINUX_32BIT_SYSCALL_TRAP 127tl0_linux32: LINUX_32BIT_SYSCALL_TRAP
131tl0_oldlinux64: LINUX_64BIT_SYSCALL_TRAP 128tl0_oldlinux64: LINUX_64BIT_SYSCALL_TRAP
132tl0_resv112: TRAP_UTRAP(UT_TRAP_INSTRUCTION_18,0x112) TRAP_UTRAP(UT_TRAP_INSTRUCTION_19,0x113) 129tl0_resv112: TRAP_UTRAP(UT_TRAP_INSTRUCTION_18,0x112) TRAP_UTRAP(UT_TRAP_INSTRUCTION_19,0x113)
@@ -139,8 +136,7 @@ tl0_resv11e: TRAP_UTRAP(UT_TRAP_INSTRUCTION_30,0x11e) TRAP_UTRAP(UT_TRAP_INSTRUC
139tl0_getcc: GETCC_TRAP 136tl0_getcc: GETCC_TRAP
140tl0_setcc: SETCC_TRAP 137tl0_setcc: SETCC_TRAP
141tl0_getpsr: TRAP(do_getpsr) 138tl0_getpsr: TRAP(do_getpsr)
142tl0_resv123: BTRAP(0x123) BTRAP(0x124) BTRAP(0x125) BTRAP(0x126) 139tl0_resv123: BTRAP(0x123) BTRAP(0x124) BTRAP(0x125) BTRAP(0x126) BTRAP(0x127)
143tl0_solindir: INDIRECT_SOLARIS_SYSCALL(156)
144tl0_resv128: BTRAP(0x128) BTRAP(0x129) BTRAP(0x12a) BTRAP(0x12b) BTRAP(0x12c) 140tl0_resv128: BTRAP(0x128) BTRAP(0x129) BTRAP(0x12a) BTRAP(0x12b) BTRAP(0x12c)
145tl0_resv12d: BTRAP(0x12d) BTRAP(0x12e) BTRAP(0x12f) BTRAP(0x130) BTRAP(0x131) 141tl0_resv12d: BTRAP(0x12d) BTRAP(0x12e) BTRAP(0x12f) BTRAP(0x130) BTRAP(0x131)
146tl0_resv132: BTRAP(0x132) BTRAP(0x133) BTRAP(0x134) BTRAP(0x135) BTRAP(0x136) 142tl0_resv132: BTRAP(0x132) BTRAP(0x133) BTRAP(0x134) BTRAP(0x135) BTRAP(0x136)
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}