diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1997-07-29 03:58:24 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1997-07-29 03:58:24 +0000 |
commit | 1c5c0c934f91fbce2825acbb849e98781e774c1d (patch) | |
tree | 12b5ae03516d4103bc070e4579ae1f7f71c27d24 /arch | |
parent | 4fe70c31de87823ac9e804f4795589ba74dc6971 (diff) |
Merge with 2.1.47. Some more cleanup and module fixes.
Diffstat (limited to 'arch')
-rw-r--r-- | arch/alpha/config.in | 5 | ||||
-rw-r--r-- | arch/i386/boot/setup.S | 68 | ||||
-rw-r--r-- | arch/i386/config.in | 5 | ||||
-rw-r--r-- | arch/i386/defconfig | 2 | ||||
-rw-r--r-- | arch/i386/kernel/setup.c | 15 | ||||
-rw-r--r-- | arch/mips/Makefile | 3 | ||||
-rw-r--r-- | arch/mips/config.in | 9 | ||||
-rw-r--r-- | arch/mips/defconfig | 3 | ||||
-rw-r--r-- | arch/mips/kernel/mips_ksyms.c | 33 | ||||
-rw-r--r-- | arch/mips/mm/fault.c | 3 | ||||
-rw-r--r-- | arch/sparc64/kernel/sys32.S | 10 | ||||
-rw-r--r-- | arch/sparc64/kernel/sys_sparc32.c | 276 |
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; +} |