summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-07-29 03:58:24 +0000
committerRalf Baechle <ralf@linux-mips.org>1997-07-29 03:58:24 +0000
commit1c5c0c934f91fbce2825acbb849e98781e774c1d (patch)
tree12b5ae03516d4103bc070e4579ae1f7f71c27d24 /arch
parent4fe70c31de87823ac9e804f4795589ba74dc6971 (diff)
Merge with 2.1.47. Some more cleanup and module fixes.
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/config.in5
-rw-r--r--arch/i386/boot/setup.S68
-rw-r--r--arch/i386/config.in5
-rw-r--r--arch/i386/defconfig2
-rw-r--r--arch/i386/kernel/setup.c15
-rw-r--r--arch/mips/Makefile3
-rw-r--r--arch/mips/config.in9
-rw-r--r--arch/mips/defconfig3
-rw-r--r--arch/mips/kernel/mips_ksyms.c33
-rw-r--r--arch/mips/mm/fault.c3
-rw-r--r--arch/sparc64/kernel/sys32.S10
-rw-r--r--arch/sparc64/kernel/sys_sparc32.c276
12 files changed, 366 insertions, 66 deletions
diff --git a/arch/alpha/config.in b/arch/alpha/config.in
index 774686ebd..6ac472f08 100644
--- a/arch/alpha/config.in
+++ b/arch/alpha/config.in
@@ -99,7 +99,10 @@ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
tristate 'Kernel support for JAVA binaries' CONFIG_BINFMT_JAVA
fi
tristate 'Kernel support for Linux/Intel ELF binaries' CONFIG_BINFMT_EM86
-tristate 'Parallel port support' CONFIG_PNP_PARPORT
+tristate 'Parallel port support' CONFIG_PARPORT
+if [ "$CONFIG_PARPORT" != "n" ]; then
+ dep_tristate ' PC-style hardware' CONFIG_PARPORT_PC $CONFIG_PARPORT
+fi
endmenu
source drivers/pnp/Config.in
diff --git a/arch/i386/boot/setup.S b/arch/i386/boot/setup.S
index 32d852efc..7553ce943 100644
--- a/arch/i386/boot/setup.S
+++ b/arch/i386/boot/setup.S
@@ -26,6 +26,10 @@
!
! Video handling moved to video.S by Martin Mares, March 1996
! <mj@k332.feld.cvut.cz>
+!
+! Extended memory detection scheme retwiddled by orc@pell.chi.il.us (david
+! parsons) to avoid loadlin confusion, July 1997
+!
#define __ASSEMBLY__
#include <linux/config.h>
@@ -241,53 +245,39 @@ loader_panic_mess:
loader_ok:
! Get memory size (extended mem, kB)
-#ifdef STANDARD_MEMORY_BIOS_CALL
- mov ah,#0x88
- int 0x15
- mov [2],ax
-#else
- push ax
- push cx
- push dx
- ! which bootloader ?
- seg cs
- mov al,byte ptr type_of_loader
- and al,#0xf0
- cmp al,#0x10
- jne try_xe801 ! not Loadlin
- seg cs
- cmp byte ptr type_of_loader,#0x16
- jbe oldstylemem ! Loadlin <= 1.6 don't like that
-try_xe801:
- mov ax,#0xe801
- int 0x15
- jc oldstylemem
+#ifndef STANDARD_MEMORY_BIOS_CALL
+ push ebx
+
+ xor ebx,ebx ! preload new memory slot with 0k
+ mov [0x1e0], ebx
+
+ mov ax,#0xe801
+ int 0x15
+ jc oldstylemem
-! memory size is (ax+(64*bx)) * 1024; we store bx+(ax/64)
+! memory size is in 1k chunksizes, to avoid confusing loadlin.
+! we store the 0xe801 memory size in a completely different place,
+! because it will most likely be longer than 16 bits.
+! (use 1e0 because that's what Larry Augustine uses in his
+! alternative new memory detection scheme, and it's sensible
+! to write everything into the same place.)
- mov [2],bx ! store extended memory size
- xor dx,dx
- mov cx,#64 ! convert lower memory size from K into
- div cx ! 64k chunks.
+ and ebx, #0xffff ! clear sign extend
+ shl ebx, 6 ! and go from 64k to 1k chunks
+ mov [0x1e0],ebx ! store extended memory size
- add [2],ax ! add lower memory into total size.
- jmp gotmem
+ and eax, #0xffff ! clear sign extend
+ add [0x1e0],eax ! and add lower memory into total size.
+
+ ! and fall into the old memory detection code to populate the
+ ! compatability slot.
+ pop ebx
oldstylemem:
+#endif
mov ah,#0x88
int 0x15
- or ax,ax ! some BIOSes report ZERO for 64meg
- mov word ptr [2],#0x400
- jz gotmem
- mov cx,#64 ! got memory size in kbytes, so we need to
- xor dx,dx ! adjust to 64k chunks for the system.
- div cx
mov [2],ax
-gotmem:
- pop dx
- pop cx
- pop ax
-#endif
! Set the keyboard repeat rate to the max
diff --git a/arch/i386/config.in b/arch/i386/config.in
index 1612b614f..887407c61 100644
--- a/arch/i386/config.in
+++ b/arch/i386/config.in
@@ -46,7 +46,10 @@ choice 'Processor type' \
PPro CONFIG_M686" Pentium
bool 'Video mode selection support' CONFIG_VIDEO_SELECT
-tristate 'Parallel port support' CONFIG_PNP_PARPORT
+tristate 'Parallel port support' CONFIG_PARPORT
+if [ "$CONFIG_PARPORT" != "n" ]; then
+ dep_tristate ' PC-style hardware' CONFIG_PARPORT_PC $CONFIG_PARPORT
+fi
endmenu
diff --git a/arch/i386/defconfig b/arch/i386/defconfig
index 6e7700c91..430d6b971 100644
--- a/arch/i386/defconfig
+++ b/arch/i386/defconfig
@@ -31,7 +31,7 @@ CONFIG_BINFMT_MISC=y
# CONFIG_M586 is not set
CONFIG_M686=y
# CONFIG_VIDEO_SELECT is not set
-# CONFIG_PNP_PARPORT is not set
+# CONFIG_PARPORT is not set
#
# Plug and Play support
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 4dd8edf76..d4800f987 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -92,6 +92,9 @@ extern char empty_zero_page[PAGE_SIZE];
*/
#define PARAM empty_zero_page
#define EXT_MEM_K (*(unsigned short *) (PARAM+2))
+#ifndef STANDARD_MEMORY_BIOS_CALL
+#define ALT_MEM_K (*(unsigned long *) (PARAM+0x1e0))
+#endif
#ifdef CONFIG_APM
#define APM_BIOS_INFO (*(struct apm_bios_info *) (PARAM+64))
#endif
@@ -120,6 +123,7 @@ __initfunc(void setup_arch(char **cmdline_p,
unsigned long * memory_start_p, unsigned long * memory_end_p))
{
unsigned long memory_start, memory_end;
+ unsigned long memory_alt_end;
char c = ' ', *to = command_line, *from = COMMAND_LINE;
int len = 0;
static unsigned char smptrap=0;
@@ -143,10 +147,15 @@ __initfunc(void setup_arch(char **cmdline_p,
BIOS_revision = SYS_DESC_TABLE.table[2];
}
aux_device_present = AUX_DEVICE_INFO;
-#ifdef STANDARD_MEMORY_BIOS_CALL
memory_end = (1<<20) + (EXT_MEM_K<<10);
-#else
- memory_end = (1<<20) + (EXT_MEM_K*64L*1024L); /* 64kb chunks */
+#ifndef STANDARD_MEMORY_BIOS_CALL
+ memory_alt_end = (1<<20) + (ALT_MEM_K<<10);
+ if (memory_alt_end > memory_end) {
+ printk("Memory: sized by int13 0e801h\n");
+ memory_end = memory_alt_end;
+ }
+ else
+ printk("Memory: sized by int13 088h\n");
#endif
memory_end &= PAGE_MASK;
#ifdef CONFIG_BLK_DEV_RAM
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 40c325e1a..516baec29 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -13,7 +13,7 @@
# Copyright (C) 1994, 1995, 1996 by Ralf Baechle
# DECStation modifications by Paul M. Antoine, 1996
#
-# $Id: Makefile,v 1.5 1997/06/28 23:39:36 ralf Exp $
+# $Id: Makefile,v 1.5 1997/07/01 08:54:40 ralf Exp $
#
#
@@ -36,6 +36,7 @@ endif
endif
LINKFLAGS = -static -N
+MODFLAGS += -mlong-calls
#
# The new ELF GCC uses -G0 -mabicalls -fpic as default. We don't need PIC
diff --git a/arch/mips/config.in b/arch/mips/config.in
index e4259537f..642eac1aa 100644
--- a/arch/mips/config.in
+++ b/arch/mips/config.in
@@ -83,7 +83,7 @@ bool 'System V IPC' CONFIG_SYSVIPC
bool 'Sysctl support' CONFIG_SYSCTL
if [ "$CONFIG_SGI" != "y" ]; then
- tristate 'Parallel port support' CONFIG_PNP_PARPORT
+ tristate 'Parallel port support' CONFIG_PARPORT
fi
endmenu
@@ -96,12 +96,7 @@ if [ "$CONFIG_MODULES" = "y" ]; then
bool 'Kernel daemon support (e.g. autoload of modules)' CONFIG_KERNELD
fi
-#
-# All SGI block devices are SCSI based AFAIK. -davem
-#
-if [ "$CONFIG_SGI" != "y" ]; then
- source drivers/block/Config.in
-fi
+source drivers/block/Config.in
if [ "$CONFIG_NET" = "y" ]; then
source net/Config.in
diff --git a/arch/mips/defconfig b/arch/mips/defconfig
index aec1c97bf..b1892eba6 100644
--- a/arch/mips/defconfig
+++ b/arch/mips/defconfig
@@ -38,7 +38,7 @@ CONFIG_BINFMT_ELF=y
CONFIG_NET=y
CONFIG_SYSVIPC=y
CONFIG_SYSCTL=y
-# CONFIG_PNP_PARPORT is not set
+# CONFIG_PARPORT is not set
#
# Loadable module support
@@ -133,6 +133,7 @@ CONFIG_PCNET32=y
# CONFIG_NET_POCKET is not set
# CONFIG_FDDI is not set
# CONFIG_DLCI is not set
+# CONFIG_PLIP is not set
# CONFIG_PPP is not set
# CONFIG_NET_RADIO is not set
# CONFIG_SLIP is not set
diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c
index abcb1946e..d6657ac89 100644
--- a/arch/mips/kernel/mips_ksyms.c
+++ b/arch/mips/kernel/mips_ksyms.c
@@ -5,40 +5,69 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 1996 by Ralf Baechle
+ * Copyright (C) 1996, 1997 by Ralf Baechle
+ *
+ * $Id: mips_ksyms.c,v 1.2 1997/07/26 19:31:40 ralf Exp $
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
+#include <linux/in6.h>
+
+#include <asm/checksum.h>
#include <asm/dma.h>
#include <asm/floppy.h>
#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/sgihpc.h>
#include <asm/softirq.h>
+#include <asm/uaccess.h>
EXPORT_SYMBOL(EISA_bus);
/*
* String functions
*/
+EXPORT_SYMBOL_NOVERS(bcopy);
+EXPORT_SYMBOL_NOVERS(memcmp);
EXPORT_SYMBOL_NOVERS(memset);
EXPORT_SYMBOL_NOVERS(memcpy);
EXPORT_SYMBOL_NOVERS(memmove);
-EXPORT_SYMBOL_NOVERS(bcopy);
+EXPORT_SYMBOL_NOVERS(strcat);
+EXPORT_SYMBOL_NOVERS(strchr);
+EXPORT_SYMBOL_NOVERS(strlen);
+EXPORT_SYMBOL_NOVERS(strncat);
+EXPORT_SYMBOL_NOVERS(strnlen);
+EXPORT_SYMBOL_NOVERS(strrchr);
+EXPORT_SYMBOL_NOVERS(strtok);
+EXPORT_SYMBOL(clear_page);
EXPORT_SYMBOL(__mips_bh_counter);
EXPORT_SYMBOL(local_irq_count);
+/*
+ * Userspace access stuff.
+ */
+EXPORT_SYMBOL(__copy_user);
+EXPORT_SYMBOL(active_ds);
+
/* Networking helper routines. */
EXPORT_SYMBOL(csum_partial_copy);
/*
* Functions to control caches.
*/
+EXPORT_SYMBOL(flush_page_to_ram);
EXPORT_SYMBOL(fd_cacheflush);
/*
* Base address of ports for Intel style I/O.
*/
EXPORT_SYMBOL(port_base);
+
+#ifdef CONFIG_SGI
+EXPORT_SYMBOL(hpc3c0);
+#endif
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index f1ebab648..72e13336b 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -117,7 +117,8 @@ bad_area:
* terminate things with extreme prejudice.
*/
printk(KERN_ALERT "Unable to handle kernel paging request at virtual "
- "address %08lx, epc == %08lx\n", address, regs->cp0_epc);
+ "address %08lx, epc == %08lx, ra == %08lx\n",
+ address, regs->cp0_epc, regs->regs[31]);
die_if_kernel("Oops", regs, writeaccess);
do_exit(SIGKILL);
out:
diff --git a/arch/sparc64/kernel/sys32.S b/arch/sparc64/kernel/sys32.S
index ddd726069..ca0faec5d 100644
--- a/arch/sparc64/kernel/sys32.S
+++ b/arch/sparc64/kernel/sys32.S
@@ -1,4 +1,4 @@
-/* $Id: sys32.S,v 1.1 1997/07/18 06:26:42 ralf Exp $
+/* $Id: sys32.S,v 1.2 1997/07/25 01:50:47 ralf Exp $
* sys32.S: I-cache tricks for 32-bit compatability layer simple
* conversions.
*
@@ -306,7 +306,7 @@ sys32_settimeofday:
.globl sys32_sched_setparam, sys32_sched_getparam, sys32_signal
.globl sys32_reboot, sys32_acct, sys32_newuname, sys32_olduname
.globl sys32_sethostname, sys32_gethostname, sys32_setdomainname
- .globl sys32_time, sys32_swapoff, sys32_swapon, sys32_nfsservctl
+ .globl sys32_time, sys32_swapoff, sys32_swapon
.globl sys32_create_module, sys32_init_module, sys32_delete_module
sys32_bdflush:
sra %o1, 0, %o1
@@ -419,9 +419,3 @@ sys32_swapon:
mov %o7, %g1
call sys_swapon
mov %g1, %o7
-sys32_nfsservctl:
- srl %o1, 0, %o1
- mov %o7, %g1
- srl %o2, 0, %o2
- call sys_nfsservctl
- mov %g1, %o7
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index 1f607da98..b6ca9448c 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc32.c,v 1.43 1997/07/17 02:20:45 davem Exp $
+/* $Id: sys_sparc32.c,v 1.44 1997/07/20 09:18:47 davem Exp $
* sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
*
* Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -32,6 +32,12 @@
#include <linux/quota.h>
#include <linux/file.h>
#include <linux/module.h>
+#include <linux/sunrpc/svc.h>
+#include <linux/nfsd/nfsd.h>
+#include <linux/nfsd/cache.h>
+#include <linux/nfsd/xdr.h>
+#include <linux/nfsd/syscall.h>
+#include <linux/module.h>
#include <asm/types.h>
#include <asm/poll.h>
@@ -2519,3 +2525,271 @@ sys_get_kernel_syms(struct kernel_sym *table)
}
#endif /* CONFIG_MODULES */
+
+/* Stuff for NFS server syscalls... */
+struct nfsctl_svc32 {
+ u16 svc32_port;
+ s32 svc32_nthreads;
+};
+
+struct nfsctl_client32 {
+ s8 cl32_ident[NFSCLNT_IDMAX+1];
+ s32 cl32_naddr;
+ struct in_addr cl32_addrlist[NFSCLNT_ADDRMAX];
+ s32 cl32_fhkeytype;
+ s32 cl32_fhkeylen;
+ u8 cl32_fhkey[NFSCLNT_KEYMAX];
+};
+
+struct nfsctl_export32 {
+ s8 ex32_client[NFSCLNT_IDMAX+1];
+ s8 ex32_path[NFS_MAXPATHLEN+1];
+ __kernel_dev_t32 ex32_dev;
+ __kernel_ino_t32 ex32_ino;
+ s32 ex32_flags;
+ __kernel_uid_t32 ex32_anon_uid;
+ __kernel_gid_t32 ex32_anon_gid;
+};
+
+struct nfsctl_uidmap32 {
+ u32 ug32_ident; /* char * */
+ __kernel_uid_t32 ug32_uidbase;
+ s32 ug32_uidlen;
+ u32 ug32_udimap; /* uid_t * */
+ __kernel_uid_t32 ug32_gidbase;
+ s32 ug32_gidlen;
+ u32 ug32_gdimap; /* gid_t * */
+};
+
+struct nfsctl_fhparm32 {
+ struct sockaddr gf32_addr;
+ __kernel_dev_t32 gf32_dev;
+ __kernel_ino_t32 gf32_ino;
+ s32 gf32_version;
+};
+
+struct nfsctl_arg32 {
+ s32 ca32_version; /* safeguard */
+ union {
+ struct nfsctl_svc32 u32_svc;
+ struct nfsctl_client32 u32_client;
+ struct nfsctl_export32 u32_export;
+ struct nfsctl_uidmap32 u32_umap;
+ struct nfsctl_fhparm32 u32_getfh;
+ u32 u32_debug;
+ } u;
+#define ca32_svc u.u32_svc
+#define ca32_client u.u32_client
+#define ca32_export u.u32_export
+#define ca32_umap u.u32_umap
+#define ca32_getfh u.u32_getfh
+#define ca32_authd u.u32_authd
+#define ca32_debug u.u32_debug
+};
+
+union nfsctl_res32 {
+ struct knfs_fh cr32_getfh;
+ u32 cr32_debug;
+};
+
+static int nfs_svc32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
+{
+ if(__get_user(karg->ca_version, &arg32->ca32_version) ||
+ __get_user(karg->ca_svc.svc_port, &arg32->ca32_svc.svc32_port) ||
+ __get_user(karg->ca_svc.svc_nthreads, &arg32->ca32_svc.svc32_nthreads))
+ return -EFAULT;
+ return 0;
+}
+
+static int nfs_clnt32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
+{
+ if(__get_user(karg->ca_version, &arg32->ca32_version) ||
+ copy_from_user(&karg->ca_client.cl_ident[0],
+ &arg32->ca32_client.cl32_ident[0],
+ NFSCLNT_IDMAX) ||
+ __get_user(karg->ca_client.cl_naddr, &arg32->ca32_client.cl32_naddr) ||
+ copy_from_user(&karg->ca_client.cl_addrlist[0],
+ &arg32->ca32_client.cl32_addrlist[0],
+ (sizeof(struct in_addr) * NFSCLNT_ADDRMAX)) ||
+ __get_user(karg->ca_client.cl_fhkeytype,
+ &arg32->ca32_client.cl32_fhkeytype) ||
+ __get_user(karg->ca_client.cl_fhkeylen,
+ &arg32->ca32_client.cl32_fhkeylen) ||
+ copy_from_user(&karg->ca_client.cl_fhkey[0],
+ &arg32->ca32_client.cl32_fhkey[0],
+ NFSCLNT_KEYMAX))
+ return -EFAULT;
+ return 0;
+}
+
+static int nfs_exp32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
+{
+ if(__get_user(karg->ca_version, &arg32->ca32_version) ||
+ copy_from_user(&karg->ca_export.ex_client[0],
+ &arg32->ca32_export.ex32_client[0],
+ NFSCLNT_IDMAX) ||
+ copy_from_user(&karg->ca_export.ex_path[0],
+ &arg32->ca32_export.ex32_path[0],
+ NFS_MAXPATHLEN) ||
+ __get_user(karg->ca_export.ex_dev,
+ &arg32->ca32_export.ex32_dev) ||
+ __get_user(karg->ca_export.ex_ino,
+ &arg32->ca32_export.ex32_ino) ||
+ __get_user(karg->ca_export.ex_flags,
+ &arg32->ca32_export.ex32_flags) ||
+ __get_user(karg->ca_export.ex_anon_uid,
+ &arg32->ca32_export.ex32_anon_uid) ||
+ __get_user(karg->ca_export.ex_anon_gid,
+ &arg32->ca32_export.ex32_anon_gid))
+ return -EFAULT;
+ return 0;
+}
+
+static int nfs_uud32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
+{
+ u32 uaddr;
+ int i;
+
+ memset(karg, 0, sizeof(*karg));
+ if(__get_user(karg->ca_version, &arg32->ca32_version))
+ return -EFAULT;
+ karg->ca_umap.ug_ident = (char *)get_free_page(GFP_USER);
+ if(!karg->ca_umap.ug_ident)
+ return -ENOMEM;
+ if(__get_user(uaddr, &arg32->ca32_umap.ug32_ident))
+ return -EFAULT;
+ if(strncpy_from_user(karg->ca_umap.ug_ident,
+ (char *)A(uaddr), PAGE_SIZE) <= 0)
+ return -EFAULT;
+ if(__get_user(karg->ca_umap.ug_uidbase,
+ &arg32->ca32_umap.ug32_uidbase) ||
+ __get_user(karg->ca_umap.ug_uidlen,
+ &arg32->ca32_umap.ug32_uidlen) ||
+ __get_user(uaddr, &arg32->ca32_umap.ug32_udimap))
+ return -EFAULT;
+ karg->ca_umap.ug_udimap = kmalloc((sizeof(uid_t) * karg->ca_umap.ug_uidlen),
+ GFP_USER);
+ if(!karg->ca_umap.ug_udimap)
+ return -EFAULT;
+ for(i = 0; i < karg->ca_umap.ug_uidlen; i++)
+ if(__get_user(karg->ca_umap.ug_udimap[i],
+ &(((__kernel_uid_t32 *)A(uaddr))[i])))
+ return -EFAULT;
+ if(__get_user(karg->ca_umap.ug_gidbase,
+ &arg32->ca32_umap.ug32_gidbase) ||
+ __get_user(karg->ca_umap.ug_uidlen,
+ &arg32->ca32_umap.ug32_gidlen) ||
+ __get_user(uaddr, &arg32->ca32_umap.ug32_gdimap))
+ return -EFAULT;
+ karg->ca_umap.ug_gdimap = kmalloc((sizeof(gid_t) * karg->ca_umap.ug_uidlen),
+ GFP_USER);
+ if(!karg->ca_umap.ug_gdimap)
+ return -EFAULT;
+ for(i = 0; i < karg->ca_umap.ug_gidlen; i++)
+ if(__get_user(karg->ca_umap.ug_gdimap[i],
+ &(((__kernel_gid_t32 *)A(uaddr))[i])))
+ return -EFAULT;
+
+ /* Success! */
+ return 0;
+}
+
+static int nfs_getfh32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
+{
+ if(__get_user(karg->ca_version, &arg32->ca32_version) ||
+ copy_from_user(&karg->ca_getfh.gf_addr,
+ &arg32->ca32_getfh.gf32_addr,
+ (sizeof(struct sockaddr))) ||
+ __get_user(karg->ca_getfh.gf_dev,
+ &arg32->ca32_getfh.gf32_dev) ||
+ __get_user(karg->ca_getfh.gf_ino,
+ &arg32->ca32_getfh.gf32_ino) ||
+ __get_user(karg->ca_getfh.gf_version,
+ &arg32->ca32_getfh.gf32_version))
+ return -EFAULT;
+ return 0;
+}
+
+static int nfs_getfh32_res_trans(union nfsctl_res *kres, union nfsctl_res32 *res32)
+{
+ if(copy_to_user(&res32->cr32_getfh,
+ &kres->cr_getfh,
+ sizeof(res32->cr32_getfh)) ||
+ __put_user(kres->cr_debug, &res32->cr32_debug))
+ return -EFAULT;
+ return 0;
+}
+
+extern asmlinkage int sys_nfsservctl(int cmd,
+ struct nfsctl_arg *arg,
+ union nfsctl_res *resp);
+
+int asmlinkage sys32_nfsservctl(int cmd, u32 u_argp, u32 u_resp)
+{
+ struct nfsctl_arg32 *arg32 = (struct nfsctl_arg32 *)A(u_argp);
+ union nfsctl_res32 *res32 = (union nfsctl_res32 *)A(u_resp);
+ struct nfsctl_arg *karg = NULL;
+ union nfsctl_res *kres = NULL;
+ unsigned long oldfs;
+ int err;
+
+ karg = kmalloc(sizeof(*karg), GFP_USER);
+ if(!karg)
+ return -ENOMEM;
+ if(res32) {
+ kres = kmalloc(sizeof(*kres), GFP_USER);
+ if(!kres) {
+ kfree(karg);
+ return -ENOMEM;
+ }
+ }
+ switch(cmd) {
+ case NFSCTL_SVC:
+ err = nfs_svc32_trans(karg, arg32);
+ break;
+ case NFSCTL_ADDCLIENT:
+ err = nfs_clnt32_trans(karg, arg32);
+ break;
+ case NFSCTL_DELCLIENT:
+ err = nfs_clnt32_trans(karg, arg32);
+ break;
+ case NFSCTL_EXPORT:
+ err = nfs_exp32_trans(karg, arg32);
+ break;
+ /* This one is unimplemented, be we're ready for it. */
+ case NFSCTL_UGIDUPDATE:
+ err = nfs_uud32_trans(karg, arg32);
+ break;
+ case NFSCTL_GETFH:
+ err = nfs_getfh32_trans(karg, arg32);
+ break;
+ default:
+ err = -EINVAL;
+ break;
+ }
+ if(err)
+ goto done;
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_nfsservctl(cmd, karg, kres);
+ set_fs(oldfs);
+
+ if(!err && cmd == NFSCTL_GETFH)
+ err = nfs_getfh32_res_trans(kres, res32);
+
+done:
+ if(karg) {
+ if(cmd == NFSCTL_UGIDUPDATE) {
+ if(karg->ca_umap.ug_ident)
+ kfree(karg->ca_umap.ug_ident);
+ if(karg->ca_umap.ug_udimap)
+ kfree(karg->ca_umap.ug_udimap);
+ if(karg->ca_umap.ug_gdimap)
+ kfree(karg->ca_umap.ug_gdimap);
+ }
+ kfree(karg);
+ }
+ if(kres)
+ kfree(kres);
+ return err;
+}