/* Functions for the Linux module syscall interface. Copyright 1996, 1997 Linux International. Contributed by Richard Henderson This file is part of the Linux modutils. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ident "$Id: sys_cm.c,v 1.1.1.1 1998/01/06 20:51:08 ewt Exp $" #include #include #include "module.h" /* Kernel headers before 2.1.mumble need this on the Alpha to get _syscall* defined. */ #define __LIBRARY__ #include /*======================================================================*/ #if defined(__i386__) || defined(__m68k__) #define __NR__create_module __NR_create_module static inline _syscall2(long, _create_module, const char *, name, size_t, size) unsigned long create_module(const char *name, size_t size) { /* Why all this fuss? In linux 2.1, the address returned by create module point in kernel space which is now mapped at the top of user space (at 0xc0000000 on i386). This looks like a negative number for a long. The normal syscall macro of linux 2.0 (and all libc compile with linux 2.0 or below) consider that the return value is a negative number and consider it is an error number (A kernel convention, return value are positive or negative, indicating the error number). By checking the value of errno, we know if we have been fooled by the syscall2 macro and we fix it. */ long ret = _create_module(name, size); if (ret == -1 && errno > 125) { ret = -errno; errno = 0; } return ret; } #elif defined(__alpha__) /* Alpha doesn't have the same problem, exactly, but a bug in older kernels fails to clear the error flag. Clear it here explicitly. */ #define __NR__create_module __NR_create_module static inline _syscall4(unsigned long, _create_module, const char *, name, size_t, size, size_t, dummy, size_t, err); unsigned long create_module(const char *name, size_t size) { return _create_module(name, size, 0, 0); } #else /* Sparc, MIPS, (and Alpha, but that's another problem) don't mistake return values for errors due to the nature of the system call. */ _syscall2(unsigned long, create_module, const char *, name, size_t, size) #endif