blob: 6f675a5bb7194b855e26e81a2f29a01687b507e2 [file] [log] [blame]
diff -u --recursive --new-file pl12/linux/README linux/README
--- pl12/linux/README Sun Aug 15 14:26:24 1993
+++ linux/README Mon Aug 16 22:18:24 1993
@@ -1,7 +1,13 @@
- Linux kernel release 0.99 patchlevel 12
+ Linux kernel release 0.99 patchlevel 13
-These are the release notes for linux version 0.99.12. Read them
+[ Just to show everybody that I have no personal integrity at all, this
+release is dedicated to Martin Mueller and Sebastian Hetze just because
+they wrote the German Linux Anwenderhandbuch. The fact that they sent
+me some of the money they made on selling it has nothing at all to do
+with the dedication. Oh, no. That would be crass. ]
+
+These are the release notes for linux version 0.99.13. Read them
carefully, as they tell you what's new, explain how to install the
kernel, and what to do if something goes wrong.
diff -u --recursive --new-file pl12/linux/config.in linux/config.in
--- pl12/linux/config.in Sun Aug 15 11:24:56 1993
+++ linux/config.in Sat Sep 4 15:17:42 1993
@@ -13,6 +13,10 @@
bool 'System V IPC' CONFIG_SYSVIPC y
bool 'Use -m486 flag for 486-specific optimizations' CONFIG_M486 y
*
+* Program binary formats
+*
+bool 'Elf executables' CONFIG_BINFMT_ELF y
+*
* SCSI support
*
bool 'SCSI support?' CONFIG_SCSI n
@@ -49,14 +53,14 @@
bool 'SLIP (serial line) support' CONFIG_SLIP n
bool 'PLIP (parallel port) support' CONFIG_PLIP n
bool 'NE2000/NE1000 support' CONFIG_NE2000 y
-bool 'WD80*3 support' CONFIG_WD80x3 y
+bool 'WD80*3 support' CONFIG_WD80x3 n
#bool '3c501 support' CONFIG_EL1 n
bool '3c503 support' CONFIG_EL2 y
#bool '3c509 support' CONFIG_EL3 n
-bool 'HP PCLAN support' CONFIG_HPLAN y
-bool 'AT1500 and NE2100 support' CONFIG_AT1500 y
+bool 'HP PCLAN support' CONFIG_HPLAN n
+bool 'AT1500 and NE2100 support' CONFIG_AT1500 n
#bool 'DEPCA support' CONFIG_DEPCA n
-bool 'D-Link DE600 pocket adaptor support' CONFIG_DE600 y
+bool 'D-Link DE600 pocket adaptor support' CONFIG_DE600 n
#bool 'AT-LAN-TEC pocket adaptor support' CONFIG_ATP n
#bool 'EtherExpress support' CONFIG_EEXPRESS n
fi
@@ -79,7 +83,7 @@
*
bool 'Keyboard meta-key sends ESC-prefix' CONFIG_KBD_META y
bool 'Keyboard Num Lock on by default' CONFIG_KBD_NUML y
-bool 'Logitech busmouse support' CONFIG_BUSMOUSE n
+bool 'Logitech busmouse support' CONFIG_BUSMOUSE y
bool 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE n
bool 'Microsoft busmouse support' CONFIG_MS_BUSMOUSE n
bool 'ATIXL busmouse support' CONFIG_ATIXL_BUSMOUSE n
@@ -95,5 +99,5 @@
bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC n
bool 'Kernel profiling support' CONFIG_PROFILE n
if [ "$CONFIG_SCSI" = "y" ]
-bool 'Verbose scsi error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS n
+bool 'Verbose scsi error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS y
fi
diff -u --recursive --new-file pl12/linux/fs/Makefile linux/fs/Makefile
--- pl12/linux/fs/Makefile Sun Mar 7 16:21:10 1993
+++ linux/fs/Makefile Fri Aug 20 08:59:30 1993
@@ -34,6 +34,9 @@
FS_SUBDIRS := $(FS_SUBDIRS) xiafs
endif
+ifdef CONFIG_BINFMT_ELF
+BINFMTS := $(BINFMTS) binfmt_elf.o
+endif
.c.s:
$(CC) $(CFLAGS) -S $<
@@ -44,7 +47,7 @@
OBJS= open.o read_write.o inode.o devices.o file_table.o buffer.o super.o \
block_dev.o stat.o exec.o pipe.o namei.o fcntl.o ioctl.o \
- select.o fifo.o locks.o filesystems.o
+ select.o fifo.o locks.o filesystems.o $(BINFMTS)
all: fs.o filesystems.a
diff -u --recursive --new-file pl12/linux/fs/binfmt_elf.c linux/fs/binfmt_elf.c
--- pl12/linux/fs/binfmt_elf.c
+++ linux/fs/binfmt_elf.c Sat Sep 4 03:36:30 1993
@@ -0,0 +1,368 @@
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/a.out.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/binfmts.h>
+#include <asm/segment.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+
+asmlinkage int sys_exit(int exit_code);
+asmlinkage int sys_close(unsigned fd);
+asmlinkage int sys_open(const char *, int, int);
+
+/*
+ * These are the functions used to load ELF style executables and shared
+ * libraries. There is no binary dependent code anywhere else.
+ */
+
+#include <linux/elf.h>
+
+int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
+{
+ struct elfhdr elf_ex;
+ struct file * file;
+ struct exec ex;
+ struct inode *interpreter_inode;
+ int i;
+ int old_fs;
+ int error;
+ struct elf_phdr * elf_ppnt, *elf_phdata;
+ int elf_exec_fileno;
+ unsigned int elf_bss, k, elf_brk;
+ int retval;
+ char * elf_interpreter;
+ unsigned int elf_entry;
+ int status;
+ unsigned int start_code, end_code, end_data;
+ unsigned int elf_stack;
+ char passed_fileno[6];
+
+ status = 0;
+ elf_ex = *((struct elfhdr *) bprm->buf); /* exec-header */
+
+ if (elf_ex.e_ident[0] != 0x7f ||
+ strncmp(&elf_ex.e_ident[1], "ELF",3) != 0)
+ return -ENOEXEC;
+
+
+ /* First of all, some simple consistency checks */
+ if(elf_ex.e_type != ET_EXEC ||
+ (elf_ex.e_machine != EM_386 && elf_ex.e_machine != EM_486) ||
+ (!bprm->inode->i_op || !bprm->inode->i_op->default_file_ops ||
+ !bprm->inode->i_op->default_file_ops->mmap)){
+ return -ENOEXEC;
+ };
+
+ /* Now read in all of the header information */
+
+ elf_phdata = (struct elf_phdr *) kmalloc(elf_ex.e_phentsize *
+ elf_ex.e_phnum, GFP_KERNEL);
+
+ old_fs = get_fs();
+ set_fs(get_ds());
+ retval = read_exec(bprm->inode, elf_ex.e_phoff, (char *) elf_phdata,
+ elf_ex.e_phentsize * elf_ex.e_phnum);
+ set_fs(old_fs);
+ if (retval < 0) {
+ kfree (elf_phdata);
+ return retval;
+ }
+
+ elf_ppnt = elf_phdata;
+
+ elf_bss = 0;
+ elf_brk = 0;
+
+ elf_exec_fileno = open_inode(bprm->inode, O_RDONLY);
+
+ if (elf_exec_fileno < 0) {
+ kfree (elf_phdata);
+ return elf_exec_fileno;
+ }
+
+ file = current->filp[elf_exec_fileno];
+
+ elf_stack = 0xffffffff;
+ elf_interpreter = NULL;
+ start_code = 0;
+ end_code = 0;
+ end_data = 0;
+
+ old_fs = get_fs();
+ set_fs(get_ds());
+
+ for(i=0;i < elf_ex.e_phnum; i++){
+ if(elf_ppnt->p_type == PT_INTERP) {
+ /* This is the program interpreter used for shared libraries -
+ for now assume that this is an a.out format binary */
+
+ elf_interpreter = (char *) kmalloc(elf_ppnt->p_filesz,
+ GFP_KERNEL);
+
+ retval = read_exec(bprm->inode,elf_ppnt->p_offset,elf_interpreter,
+ elf_ppnt->p_filesz);
+ printk("Using ELF interpreter %s\n", elf_interpreter);
+ if(retval >= 0)
+ retval = namei(elf_interpreter, &interpreter_inode);
+ if(retval >= 0)
+ retval = read_exec(interpreter_inode,0,bprm->buf,128);
+
+ if(retval >= 0){
+ ex = *((struct exec *) bprm->buf); /* exec-header */
+
+#if 0
+ printk("Interpreter: %x %x %x\n",N_MAGIC(ex), ex.a_text,ex.a_data);
+#endif
+ };
+ };
+ elf_ppnt++;
+ };
+
+ set_fs(old_fs);
+
+ /* Some simple consistency checks for the interpreter */
+ if(elf_interpreter){
+ if(retval < 0) {
+ kfree(elf_interpreter);
+ kfree(elf_phdata);
+ return -ELIBACC;
+ };
+ if((N_MAGIC(ex) != OMAGIC) && (N_MAGIC(ex) != ZMAGIC)) {
+ kfree(elf_interpreter);
+ kfree(elf_phdata);
+ return -ELIBBAD;
+ };
+ }
+
+ /* OK, we are done with that, now set up the arg stuff,
+ and then start this sucker up */
+
+ if (!bprm->sh_bang) {
+ char * passed_p;
+
+ sprintf(passed_fileno, "%d", elf_exec_fileno);
+ passed_p = passed_fileno;
+
+ if(elf_interpreter) {
+ bprm->p = copy_strings(1,&passed_p,bprm->page,bprm->p,2);
+ bprm->argc++;
+ };
+ if (!bprm->p) {
+ if(elf_interpreter) {
+ kfree(elf_interpreter);
+ }
+ kfree (elf_phdata);
+ return -E2BIG;
+ }
+ }
+
+ /* OK, This is the point of no return */
+ flush_old_exec(bprm);
+
+ current->end_data = 0;
+ current->end_code = 0;
+ current->start_mmap = ELF_START_MMAP;
+ current->mmap = NULL;
+ elf_entry = (unsigned int) elf_ex.e_entry;
+
+ /* Do this so that we can load the interpreter, if need be. We will
+ change some of these later */
+ current->rss = 0;
+ bprm->p += change_ldt(0, bprm->page);
+ current->start_stack = bprm->p;
+
+ /* Now we do a little grungy work by mmaping the ELF image into
+ the correct location in memory. At this point, we assume that
+ the image should be loaded at fixed address, not at a variable
+ address. */
+
+ old_fs = get_fs();
+ set_fs(get_ds());
+
+ elf_ppnt = elf_phdata;
+ for(i=0;i < elf_ex.e_phnum; i++){
+
+ if(elf_ppnt->p_type == PT_INTERP) {
+ /* Set these up so that we are able to load the interpreter */
+ current->brk = ex.a_bss +
+ (current->end_data = ex.a_data +
+ (current->end_code = ex.a_text));
+ elf_entry = ex.a_entry;
+
+ /* Now load the interpreter into user address space */
+ set_fs(old_fs);
+
+ if (N_MAGIC(ex) == OMAGIC) {
+ retval = read_exec(interpreter_inode, 32, (char *) 0,
+ ex.a_text+ex.a_data);
+ iput(interpreter_inode);
+ } else if (N_MAGIC(ex) == ZMAGIC) {
+ retval = read_exec(interpreter_inode, 1024, (char *) 0,
+ ex.a_text+ex.a_data);
+ iput(interpreter_inode);
+ } else
+ retval = -1;
+
+ old_fs = get_fs();
+ set_fs(get_ds());
+
+ if(retval >= 0)
+ zeromap_page_range((ex.a_text + ex.a_data + 0xfff) &
+ 0xfffff000, ex.a_bss, PAGE_COPY);
+ kfree(elf_interpreter);
+
+ if(retval < 0) {
+ kfree(elf_phdata);
+ send_sig(SIGSEGV, current, 0);
+ return 0;
+ };
+ };
+
+
+ if(elf_ppnt->p_type == PT_LOAD) {
+ error = do_mmap(file,
+ elf_ppnt->p_vaddr & 0xfffff000,
+ elf_ppnt->p_filesz + (elf_ppnt->p_vaddr & 0xfff),
+ PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_FIXED | MAP_PRIVATE,
+ elf_ppnt->p_offset & 0xfffff000);
+
+#ifdef LOW_ELF_STACK
+ if(elf_ppnt->p_vaddr & 0xfffff000 < elf_stack)
+ elf_stack = elf_ppnt->p_vaddr & 0xfffff000;
+#endif
+
+ k = elf_ppnt->p_vaddr;
+ if(k > start_code) start_code = k;
+ k = elf_ppnt->p_vaddr + elf_ppnt->p_filesz;
+ if(k > elf_bss) elf_bss = k;
+ if((elf_ppnt->p_flags | PROT_WRITE) && end_code < k)
+ end_code = k;
+ if(end_data < k) end_data = k;
+ k = elf_ppnt->p_vaddr + elf_ppnt->p_memsz;
+ if(k > elf_brk) elf_brk = k;
+
+ if(status == 0xffffffff) {
+ set_fs(old_fs);
+ kfree(elf_phdata);
+ send_sig(SIGSEGV, current, 0);
+ return 0;
+ };
+ };
+ elf_ppnt++;
+ };
+ set_fs(old_fs);
+
+ kfree(elf_phdata);
+
+ if(!elf_interpreter) sys_close(elf_exec_fileno);
+ current->elf_executable = 1;
+ current->executable = bprm->inode;
+ bprm->inode->i_count++;
+#ifdef LOW_ELF_STACK
+ current->start_stack = p = elf_stack - 4;
+#endif
+ bprm->p -= MAX_ARG_PAGES*PAGE_SIZE;
+ bprm->p = (unsigned long) create_tables((char *)bprm->p,bprm->argc,bprm->envc);
+ if(elf_interpreter) current->arg_start += strlen(passed_fileno) + 1;
+ current->start_brk = current->brk = elf_brk;
+ current->end_code = end_code;
+ current->start_code = start_code;
+ current->start_stack = bprm->p;
+ current->suid = current->euid = bprm->e_uid;
+ current->sgid = current->egid = bprm->e_gid;
+ zeromap_page_range((elf_bss + 0xfff) & 0xfffff000, elf_brk - elf_bss,
+ PAGE_COPY);
+ regs->eip = elf_entry; /* eip, magic happens :-) */
+ regs->esp = bprm->p; /* stack pointer */
+ if (current->flags & PF_PTRACED)
+ send_sig(SIGTRAP, current, 0);
+
+ return 0;
+}
+
+
+int load_elf_library(int fd){
+ struct file * file;
+ struct elfhdr elf_ex;
+ struct elf_phdr *elf_phdata = NULL;
+ struct inode * inode;
+ unsigned int len;
+ int old_fs, retval;
+ unsigned int bss;
+ int error;
+ int i,j;
+
+ len = 0;
+ file = current->filp[fd];
+ inode = file->f_inode;
+
+ set_fs(KERNEL_DS);
+ if (file->f_op->read(inode, file, (char *) &elf_ex, sizeof(elf_ex)) != sizeof(elf_ex)) {
+ sys_close(fd);
+ return -EACCES;
+ }
+ set_fs(USER_DS);
+
+ if (elf_ex.e_ident[0] != 0x7f ||
+ strncmp(&elf_ex.e_ident[1], "ELF",3) != 0)
+ return -ENOEXEC;
+
+ /* First of all, some simple consistency checks */
+ if(elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 ||
+ (elf_ex.e_machine != EM_386 && elf_ex.e_machine != EM_486) ||
+ (!inode->i_op || !inode->i_op->bmap ||
+ !inode->i_op->default_file_ops->mmap)){
+ return -ENOEXEC;
+ };
+
+ /* Now read in all of the header information */
+
+ if(sizeof(struct elf_phdr) * elf_ex.e_phnum > PAGE_SIZE)
+ return -ENOEXEC;
+
+ elf_phdata = (struct elf_phdr *)
+ kmalloc(sizeof(struct elf_phdr) * elf_ex.e_phnum, GFP_KERNEL);
+
+ old_fs = get_fs();
+ set_fs(get_ds());
+ retval = read_exec(inode, elf_ex.e_phoff, (char *) elf_phdata,
+ sizeof(struct elf_phdr) * elf_ex.e_phnum);
+ set_fs(old_fs);
+
+ j = 0;
+ for(i=0; i<elf_ex.e_phnum; i++)
+ if((elf_phdata + i)->p_type == PT_LOAD) j++;
+
+ if(j != 1) {
+ kfree(elf_phdata);
+ return -ENOEXEC;
+ };
+
+ while(elf_phdata->p_type != PT_LOAD) elf_phdata++;
+
+ /* Now use mmap to map the library into memory. */
+ error = do_mmap(file,
+ elf_phdata->p_vaddr & 0xfffff000,
+ elf_phdata->p_filesz + (elf_phdata->p_vaddr & 0xfff),
+ PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_FIXED | MAP_PRIVATE,
+ elf_phdata->p_offset & 0xfffff000);
+
+ sys_close(fd);
+ if (error != elf_phdata->p_vaddr & 0xfffff000) {
+ kfree(elf_phdata);
+ return error;
+ }
+ len = (elf_phdata->p_filesz + elf_phdata->p_vaddr+ 0xfff) & 0xfffff000;
+ bss = elf_phdata->p_memsz + elf_phdata->p_vaddr;
+ if (bss > len)
+ zeromap_page_range(len, bss-len, PAGE_COPY);
+ kfree(elf_phdata);
+ return 0;
+}
diff -u --recursive --new-file pl12/linux/fs/buffer.c linux/fs/buffer.c
--- pl12/linux/fs/buffer.c Sat Aug 14 23:47:21 1993
+++ linux/fs/buffer.c Sat Sep 4 03:36:30 1993
@@ -160,7 +160,7 @@
return sync_buffers(dev, 1);
}
-extern "C" int sys_sync(void)
+asmlinkage int sys_sync(void)
{
sync_dev(0);
return 0;
@@ -171,7 +171,7 @@
return fsync_dev(inode->i_dev);
}
-extern "C" int sys_fsync(unsigned int fd)
+asmlinkage int sys_fsync(unsigned int fd)
{
struct file * file;
struct inode * inode;
diff -u --recursive --new-file pl12/linux/fs/exec.c linux/fs/exec.c
--- pl12/linux/fs/exec.c Sun Aug 15 11:33:07 1993
+++ linux/fs/exec.c Sat Sep 4 03:36:30 1993
@@ -44,13 +44,13 @@
#include <asm/segment.h>
#include <asm/system.h>
-extern "C" int sys_exit(int exit_code);
-extern "C" int sys_close(unsigned fd);
-extern "C" int sys_open(const char *, int, int);
+asmlinkage int sys_exit(int exit_code);
+asmlinkage int sys_close(unsigned fd);
+asmlinkage int sys_open(const char *, int, int);
extern void shm_exit (void);
-static int open_inode(struct inode * inode, int mode)
+int open_inode(struct inode * inode, int mode)
{
int error, fd;
struct file *f, **fpp;
@@ -225,7 +225,7 @@
*
* Also note that we take the address to load from from the file itself.
*/
-extern "C" int sys_uselib(const char * library)
+asmlinkage int sys_uselib(const char * library)
{
int fd, retval;
struct file * file;
@@ -316,7 +316,7 @@
* it is expensive to load a segment register, we try to avoid calling
* set_fs() unless we absolutely have to.
*/
-static unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
+unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
unsigned long p, int from_kmem)
{
char *tmp, *pag = NULL;
@@ -459,7 +459,7 @@
current->mmap = NULL;
while (mpnt) {
mpnt1 = mpnt->vm_next;
- if (mpnt->vm_ops->close)
+ if (mpnt->vm_ops && mpnt->vm_ops->close)
mpnt->vm_ops->close(mpnt);
kfree(mpnt);
mpnt = mpnt1;
@@ -649,6 +649,7 @@
}
}
+ bprm.sh_bang = sh_bang;
fmt = formats;
do {
int (*fn)(struct linux_binprm *, struct pt_regs *) = fmt->load_binary;
@@ -672,7 +673,7 @@
/*
* sys_execve() executes a new program.
*/
-extern "C" int sys_execve(struct pt_regs regs)
+asmlinkage int sys_execve(struct pt_regs regs)
{
int error;
char * filename;
@@ -694,9 +695,16 @@
struct pt_regs * regs);
extern int load_aout_library(int fd);
+extern int load_elf_binary(struct linux_binprm *,
+ struct pt_regs * regs);
+extern int load_elf_library(int fd);
+
/* Here are the actual binaries that will be accepted */
struct linux_binfmt formats[] = {
{load_aout_binary, load_aout_library},
+#ifdef CONFIG_BINFMT_ELF
+ {load_elf_binary, load_elf_library},
+#endif
{NULL, NULL}
};
@@ -713,17 +721,20 @@
unsigned long p = bprm->p;
ex = *((struct exec *) bprm->buf); /* exec-header */
- if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC) ||
+ if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC &&
+ N_MAGIC(ex) != QMAGIC) ||
ex.a_trsize || ex.a_drsize ||
bprm->inode->i_size < ex.a_text+ex.a_data+ex.a_syms+N_TXTOFF(ex)) {
return -ENOEXEC;
}
- if (N_MAGIC(ex) == ZMAGIC && N_TXTOFF(ex) &&
+
+ if (N_MAGIC(ex) == ZMAGIC &&
(N_TXTOFF(ex) < bprm->inode->i_sb->s_blocksize)) {
printk("N_TXTOFF < BLOCK_SIZE. Please convert binary.");
return -ENOEXEC;
}
- if (N_TXTOFF(ex) != BLOCK_SIZE && N_MAGIC(ex) != OMAGIC) {
+
+ if (N_TXTOFF(ex) != BLOCK_SIZE && N_MAGIC(ex) == ZMAGIC) {
printk("N_TXTOFF != BLOCK_SIZE. See a.out.h.");
return -ENOEXEC;
}
@@ -732,7 +743,10 @@
flush_old_exec(bprm);
current->start_brk = current->brk = ex.a_bss +
(current->end_data = ex.a_data +
- (current->end_code = ex.a_text));
+ (current->end_code = N_TXTADDR(ex) + ex.a_text));
+
+ current->start_code += N_TXTADDR(ex);
+
current->rss = 0;
current->suid = current->euid = bprm->e_uid;
current->mmap = NULL;
@@ -751,23 +765,25 @@
file = current->filp[fd];
if (!file->f_op || !file->f_op->mmap) {
sys_close(fd);
- read_exec(bprm->inode, 1024, (char *) 0, ex.a_text+ex.a_data);
+ read_exec(bprm->inode, N_TXTOFF(ex),
+ (char *) N_TXTADDR(ex), ex.a_text+ex.a_data);
goto beyond_if;
}
- error = do_mmap(file, 0, ex.a_text,
+ error = do_mmap(file, N_TXTADDR(ex), ex.a_text,
PROT_READ | PROT_EXEC,
MAP_FIXED | MAP_SHARED, N_TXTOFF(ex));
- if (error != 0) {
+
+ if (error != N_TXTADDR(ex)) {
sys_close(fd);
send_sig(SIGSEGV, current, 0);
return 0;
};
- error = do_mmap(file, ex.a_text, ex.a_data,
+ error = do_mmap(file, N_TXTADDR(ex) + ex.a_text, ex.a_data,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_FIXED | MAP_PRIVATE, N_TXTOFF(ex) + ex.a_text);
sys_close(fd);
- if (error != ex.a_text) {
+ if (error != N_TXTADDR(ex) + ex.a_text) {
send_sig(SIGSEGV, current, 0);
return 0;
};
@@ -775,7 +791,7 @@
bprm->inode->i_count++;
}
beyond_if:
- zeromap_page_range((ex.a_text + ex.a_data + 0xfff) & 0xfffff000,ex.a_bss, PAGE_COPY);
+ zeromap_page_range((N_TXTADDR(ex) + ex.a_text + ex.a_data + 0xfff) & 0xfffff000,ex.a_bss, PAGE_COPY);
p += change_ldt(ex.a_text,bprm->page);
p -= MAX_ARG_PAGES*PAGE_SIZE;
p = (unsigned long) create_tables((char *)p,bprm->argc,bprm->envc);
@@ -795,6 +811,7 @@
struct inode * inode;
unsigned int len;
unsigned int bss;
+ unsigned int start_addr;
int error;
file = current->filp[fd];
@@ -807,8 +824,8 @@
set_fs(USER_DS);
/* We come in here for the regular a.out style of shared libraries */
- if (N_MAGIC(ex) != ZMAGIC || ex.a_trsize ||
- ex.a_drsize || ex.a_entry & 0xfff ||
+ if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != QMAGIC) || ex.a_trsize ||
+ ex.a_drsize || ((ex.a_entry & 0xfff) && N_MAGIC(ex) == ZMAGIC) ||
inode->i_size < ex.a_text+ex.a_data+ex.a_syms+N_TXTOFF(ex)) {
return -ENOEXEC;
}
@@ -818,15 +835,22 @@
return -ENOEXEC;
}
+ if (N_FLAGS(ex)) return -ENOEXEC;
+
+ /* For QMAGIC, the starting address is 0x20 into the page. We mask
+ this off to get the starting address for the page */
+
+ start_addr = ex.a_entry & 0xfffff000;
+
/* Now use mmap to map the library into memory. */
- error = do_mmap(file, ex.a_entry, ex.a_text + ex.a_data,
+ error = do_mmap(file, start_addr, ex.a_text + ex.a_data,
PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE,
N_TXTOFF(ex));
- if (error != ex.a_entry)
+ if (error != start_addr)
return error;
len = (ex.a_text + ex.a_data + 0xfff) & 0xfffff000;
bss = ex.a_text + ex.a_data + ex.a_bss;
if (bss > len)
- zeromap_page_range(ex.a_entry + len, bss-len, PAGE_COPY);
+ zeromap_page_range(start_addr + len, bss-len, PAGE_COPY);
return 0;
}
diff -u --recursive --new-file pl12/linux/fs/ext2/namei.c linux/fs/ext2/namei.c
--- pl12/linux/fs/ext2/namei.c Thu Aug 12 20:54:00 1993
+++ linux/fs/ext2/namei.c Sat Aug 21 19:21:56 1993
@@ -937,6 +937,8 @@
new_inode->i_nlink--;
new_inode->i_dirt = 1;
}
+ old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
+ old_dir->i_dirt = 1;
old_bh->b_dirt = 1;
new_bh->b_dirt = 1;
if (dir_bh) {
diff -u --recursive --new-file pl12/linux/fs/fcntl.c linux/fs/fcntl.c
--- pl12/linux/fs/fcntl.c Wed Jul 7 10:39:21 1993
+++ linux/fs/fcntl.c Sat Sep 4 03:36:30 1993
@@ -35,7 +35,7 @@
return arg;
}
-extern "C" int sys_dup2(unsigned int oldfd, unsigned int newfd)
+asmlinkage int sys_dup2(unsigned int oldfd, unsigned int newfd)
{
if (oldfd >= NR_OPEN || !current->filp[oldfd])
return -EBADF;
@@ -58,12 +58,12 @@
return dupfd(oldfd,newfd);
}
-extern "C" int sys_dup(unsigned int fildes)
+asmlinkage int sys_dup(unsigned int fildes)
{
return dupfd(fildes,0);
}
-extern "C" int sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
+asmlinkage int sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
{
struct file * filp;
diff -u --recursive --new-file pl12/linux/fs/file_table.c linux/fs/file_table.c
--- pl12/linux/fs/file_table.c Mon Aug 9 17:41:22 1993
+++ linux/fs/file_table.c Tue Aug 17 18:32:13 1993
@@ -45,7 +45,7 @@
struct file * file;
int i;
- file = (struct file*) __get_free_page(GFP_BUFFER);
+ file = (struct file *) get_free_page(GFP_KERNEL);
if (!file)
return;
diff -u --recursive --new-file pl12/linux/fs/inode.c linux/fs/inode.c
--- pl12/linux/fs/inode.c Mon Aug 9 17:41:22 1993
+++ linux/fs/inode.c Tue Aug 17 18:41:05 1993
@@ -87,7 +87,7 @@
struct inode * inode;
int i;
- if(!(inode = (struct inode*) get_free_page(GFP_KERNEL)))
+ if (!(inode = (struct inode*) get_free_page(GFP_KERNEL)))
return;
i=PAGE_SIZE / sizeof(struct inode);
diff -u --recursive --new-file pl12/linux/fs/ioctl.c linux/fs/ioctl.c
--- pl12/linux/fs/ioctl.c Sat Jul 3 01:07:31 1993
+++ linux/fs/ioctl.c Sat Sep 4 03:36:30 1993
@@ -54,7 +54,7 @@
}
-extern "C" int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
{
struct file * filp;
int on;
diff -u --recursive --new-file pl12/linux/fs/namei.c linux/fs/namei.c
--- pl12/linux/fs/namei.c Mon Aug 9 18:02:29 1993
+++ linux/fs/namei.c Sat Sep 4 03:36:30 1993
@@ -266,7 +266,7 @@
*
* namei for open - this is in fact almost the whole open-routine.
*
- * Note that the low bits of "flag" aren't the same asin the open
+ * Note that the low bits of "flag" aren't the same as in the open
* system call - they are 00 - no permissions needed
* 01 - read permission needed
* 10 - write permission needed
@@ -369,6 +369,8 @@
return -ETXTBSY;
}
for(mpnt = (*p)->mmap; mpnt; mpnt = mpnt->vm_next) {
+ if (mpnt->vm_page_prot & PAGE_RW)
+ continue;
if (inode == mpnt->vm_inode) {
iput(inode);
return -ETXTBSY;
@@ -376,6 +378,16 @@
}
}
}
+ if (flag & O_TRUNC) {
+ inode->i_size = 0;
+ if (inode->i_op && inode->i_op->truncate)
+ inode->i_op->truncate(inode);
+ if ((error = notify_change(NOTIFY_SIZE, inode))) {
+ iput(inode);
+ return error;
+ }
+ inode->i_dirt = 1;
+ }
*res_inode = inode;
return 0;
}
@@ -409,7 +421,7 @@
return dir->i_op->mknod(dir,basename,namelen,mode,dev);
}
-extern "C" int sys_mknod(const char * filename, int mode, dev_t dev)
+asmlinkage int sys_mknod(const char * filename, int mode, dev_t dev)
{
int error;
char * tmp;
@@ -452,7 +464,7 @@
return dir->i_op->mkdir(dir,basename,namelen,mode);
}
-extern "C" int sys_mkdir(const char * pathname, int mode)
+asmlinkage int sys_mkdir(const char * pathname, int mode)
{
int error;
char * tmp;
@@ -493,7 +505,7 @@
return dir->i_op->rmdir(dir,basename,namelen);
}
-extern "C" int sys_rmdir(const char * pathname)
+asmlinkage int sys_rmdir(const char * pathname)
{
int error;
char * tmp;
@@ -534,7 +546,7 @@
return dir->i_op->unlink(dir,basename,namelen);
}
-extern "C" int sys_unlink(const char * pathname)
+asmlinkage int sys_unlink(const char * pathname)
{
int error;
char * tmp;
@@ -575,7 +587,7 @@
return dir->i_op->symlink(dir,basename,namelen,oldname);
}
-extern "C" int sys_symlink(const char * oldname, const char * newname)
+asmlinkage int sys_symlink(const char * oldname, const char * newname)
{
int error;
char * from, * to;
@@ -631,7 +643,7 @@
return dir->i_op->link(oldinode, dir, basename, namelen);
}
-extern "C" int sys_link(const char * oldname, const char * newname)
+asmlinkage int sys_link(const char * oldname, const char * newname)
{
int error;
char * to;
@@ -703,7 +715,7 @@
new_dir, new_base, new_len);
}
-extern "C" int sys_rename(const char * oldname, const char * newname)
+asmlinkage int sys_rename(const char * oldname, const char * newname)
{
int error;
char * from, * to;
diff -u --recursive --new-file pl12/linux/fs/nfs/mmap.c linux/fs/nfs/mmap.c
--- pl12/linux/fs/nfs/mmap.c Sun Aug 15 11:46:03 1993
+++ linux/fs/nfs/mmap.c Sat Aug 21 10:31:31 1993
@@ -50,11 +50,9 @@
{
struct vm_area_struct * mpnt;
- if (off & (inode->i_sb->s_blocksize - 1))
+ if (prot & PAGE_RW) /* only PAGE_COW or read-only supported now */
return -EINVAL;
- if (len > high_memory || off > high_memory - len) /* avoid overflow */
- return -ENXIO;
- if (get_limit(USER_DS) != TASK_SIZE)
+ if (off & (inode->i_sb->s_blocksize - 1))
return -EINVAL;
if (!inode->i_sb || !S_ISREG(inode->i_mode))
return -EACCES;
@@ -79,10 +77,6 @@
mpnt->vm_ops = &nfs_file_mmap;
mpnt->vm_next = current->mmap;
current->mmap = mpnt;
-#if 0
- printk("VFS: Loaded mmap at %08x - %08x\n",
- mpnt->vm_start, mpnt->vm_end);
-#endif
return 0;
}
diff -u --recursive --new-file pl12/linux/fs/open.c linux/fs/open.c
--- pl12/linux/fs/open.c Mon Aug 9 18:02:29 1993
+++ linux/fs/open.c Sat Sep 4 03:35:17 1993
@@ -21,12 +21,12 @@
extern void fcntl_remove_locks(struct task_struct *, struct file *);
-extern "C" int sys_ustat(int dev, struct ustat * ubuf)
+asmlinkage int sys_ustat(int dev, struct ustat * ubuf)
{
return -ENOSYS;
}
-extern "C" int sys_statfs(const char * path, struct statfs * buf)
+asmlinkage int sys_statfs(const char * path, struct statfs * buf)
{
struct inode * inode;
int error;
@@ -46,7 +46,7 @@
return 0;
}
-extern "C" int sys_fstatfs(unsigned int fd, struct statfs * buf)
+asmlinkage int sys_fstatfs(unsigned int fd, struct statfs * buf)
{
struct inode * inode;
struct file * file;
@@ -65,7 +65,7 @@
return 0;
}
-extern "C" int sys_truncate(const char * path, unsigned int length)
+asmlinkage int sys_truncate(const char * path, unsigned int length)
{
struct inode * inode;
int error;
@@ -91,7 +91,7 @@
return error;
}
-extern "C" int sys_ftruncate(unsigned int fd, unsigned int length)
+asmlinkage int sys_ftruncate(unsigned int fd, unsigned int length)
{
struct inode * inode;
struct file * file;
@@ -114,7 +114,7 @@
* must be owner or have write permission.
* Else, update from *times, must be owner or super user.
*/
-extern "C" int sys_utime(char * filename, struct utimbuf * times)
+asmlinkage int sys_utime(char * filename, struct utimbuf * times)
{
struct inode * inode;
long actime,modtime;
@@ -155,7 +155,7 @@
* XXX we should use the real ids for checking _all_ components of the
* path. Now we only use them for the final component of the path.
*/
-extern "C" int sys_access(const char * filename,int mode)
+asmlinkage int sys_access(const char * filename,int mode)
{
struct inode * inode;
int res, i_mode;
@@ -189,7 +189,7 @@
return -EACCES;
}
-extern "C" int sys_chdir(const char * filename)
+asmlinkage int sys_chdir(const char * filename)
{
struct inode * inode;
int error;
@@ -210,7 +210,7 @@
return (0);
}
-extern "C" int sys_chroot(const char * filename)
+asmlinkage int sys_chroot(const char * filename)
{
struct inode * inode;
int error;
@@ -231,7 +231,7 @@
return (0);
}
-extern "C" int sys_fchmod(unsigned int fd, mode_t mode)
+asmlinkage int sys_fchmod(unsigned int fd, mode_t mode)
{
struct inode * inode;
struct file * file;
@@ -252,7 +252,7 @@
return notify_change(NOTIFY_MODE, inode);
}
-extern "C" int sys_chmod(const char * filename, mode_t mode)
+asmlinkage int sys_chmod(const char * filename, mode_t mode)
{
struct inode * inode;
int error;
@@ -278,7 +278,7 @@
return error;
}
-extern "C" int sys_fchown(unsigned int fd, uid_t user, gid_t group)
+asmlinkage int sys_fchown(unsigned int fd, uid_t user, gid_t group)
{
struct inode * inode;
struct file * file;
@@ -305,7 +305,7 @@
return -EPERM;
}
-extern "C" int sys_chown(const char * filename, uid_t user, gid_t group)
+asmlinkage int sys_chown(const char * filename, uid_t user, gid_t group)
{
struct inode * inode;
int error;
@@ -378,18 +378,7 @@
f->f_count--;
return error;
}
- if (flag & O_TRUNC) {
- inode->i_size = 0;
- if (inode->i_op && inode->i_op->truncate)
- inode->i_op->truncate(inode);
- if ((error = notify_change(NOTIFY_SIZE, inode))) {
- iput(inode);
- current->filp[fd] = NULL;
- f->f_count--;
- return error;
- }
- inode->i_dirt = 1;
- }
+
f->f_inode = inode;
f->f_pos = 0;
f->f_reada = 0;
@@ -409,7 +398,7 @@
return (fd);
}
-extern "C" int sys_open(const char * filename,int flags,int mode)
+asmlinkage int sys_open(const char * filename,int flags,int mode)
{
char * tmp;
int error;
@@ -422,7 +411,7 @@
return error;
}
-extern "C" int sys_creat(const char * pathname, int mode)
+asmlinkage int sys_creat(const char * pathname, int mode)
{
return sys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode);
}
@@ -450,7 +439,7 @@
return 0;
}
-extern "C" int sys_close(unsigned int fd)
+asmlinkage int sys_close(unsigned int fd)
{
struct file * filp;
@@ -467,7 +456,7 @@
* This routine simulates a hangup on the tty, to arrange that users
* are given clean terminals at login time.
*/
-extern "C" int sys_vhangup(void)
+asmlinkage int sys_vhangup(void)
{
struct tty_struct *tty;
diff -u --recursive --new-file pl12/linux/fs/pipe.c linux/fs/pipe.c
--- pl12/linux/fs/pipe.c Sun Jul 18 18:19:42 1993
+++ linux/fs/pipe.c Sat Sep 4 03:36:30 1993
@@ -288,7 +288,7 @@
NULL /* permission */
};
-extern "C" int sys_pipe(unsigned long * fildes)
+asmlinkage int sys_pipe(unsigned long * fildes)
{
struct inode * inode;
struct file * f[2];
diff -u --recursive --new-file pl12/linux/fs/proc/array.c linux/fs/proc/array.c
--- pl12/linux/fs/proc/array.c Mon Aug 9 18:02:29 1993
+++ linux/fs/proc/array.c Fri Aug 20 09:40:57 1993
@@ -194,7 +194,7 @@
if (vsize) {
eip = KSTK_EIP(vsize);
esp = KSTK_ESP(vsize);
- vsize = (*p)->brk + PAGE_SIZE-1;
+ vsize = (*p)->brk - (*p)->start_code + PAGE_SIZE-1;
if (esp)
vsize += TASK_SIZE - esp;
}
@@ -264,7 +264,7 @@
return 0;
tpag = (*p)->end_code / PAGE_SIZE;
if ((*p)->state != TASK_ZOMBIE) {
- pagedir = PAGE_DIR_OFFSET((*p)->tss.cr3,(*p)->start_code);
+ pagedir = (unsigned long *) (*p)->tss.cr3;
for (i = 0; i < 0x300; ++i) {
if ((ptbl = pagedir[i]) == 0) {
tpag -= PTRS_PER_PAGE;
diff -u --recursive --new-file pl12/linux/fs/proc/kmsg.c linux/fs/proc/kmsg.c
--- pl12/linux/fs/proc/kmsg.c Sat Jul 3 01:31:56 1993
+++ linux/fs/proc/kmsg.c Sat Sep 4 03:39:22 1993
@@ -17,7 +17,7 @@
extern unsigned long log_size;
extern struct wait_queue * log_wait;
-extern "C" int sys_syslog(int type, char * bug, int count);
+asmlinkage int sys_syslog(int type, char * bug, int count);
static int kmsg_open(struct inode * inode, struct file * file)
{
diff -u --recursive --new-file pl12/linux/fs/read_write.c linux/fs/read_write.c
--- pl12/linux/fs/read_write.c Sat Jul 3 01:05:39 1993
+++ linux/fs/read_write.c Sat Sep 4 03:36:30 1993
@@ -16,7 +16,7 @@
* Count is not yet used: but we'll probably support reading several entries
* at once in the future. Use count=1 in the library for future expansions.
*/
-extern "C" int sys_readdir(unsigned int fd, struct dirent * dirent, unsigned int count)
+asmlinkage int sys_readdir(unsigned int fd, struct dirent * dirent, unsigned int count)
{
int error;
struct file * file;
@@ -34,7 +34,7 @@
return error;
}
-extern "C" int sys_lseek(unsigned int fd, off_t offset, unsigned int origin)
+asmlinkage int sys_lseek(unsigned int fd, off_t offset, unsigned int origin)
{
struct file * file;
int tmp = -1;
@@ -67,7 +67,7 @@
return file->f_pos;
}
-extern "C" int sys_read(unsigned int fd,char * buf,unsigned int count)
+asmlinkage int sys_read(unsigned int fd,char * buf,unsigned int count)
{
int error;
struct file * file;
@@ -87,7 +87,7 @@
return file->f_op->read(inode,file,buf,count);
}
-extern "C" int sys_write(unsigned int fd,char * buf,unsigned int count)
+asmlinkage int sys_write(unsigned int fd,char * buf,unsigned int count)
{
int error;
struct file * file;
diff -u --recursive --new-file pl12/linux/fs/select.c linux/fs/select.c
--- pl12/linux/fs/select.c Mon Aug 9 18:02:30 1993
+++ linux/fs/select.c Sat Sep 4 03:36:30 1993
@@ -192,7 +192,7 @@
* Update: ERESTARTSYS breaks at least the xview clock binary, so
* I'm trying ERESTARTNOHAND which restart only when you want to.
*/
-extern "C" int sys_select( unsigned long *buffer )
+asmlinkage int sys_select( unsigned long *buffer )
{
/* Perform the select(nd, in, out, ex, tv) system call. */
int i;
diff -u --recursive --new-file pl12/linux/fs/stat.c linux/fs/stat.c
--- pl12/linux/fs/stat.c Sat Jul 3 01:04:26 1993
+++ linux/fs/stat.c Sat Sep 4 03:36:30 1993
@@ -86,7 +86,7 @@
memcpy_tofs(statbuf,&tmp,sizeof(tmp));
}
-extern "C" int sys_stat(char * filename, struct old_stat * statbuf)
+asmlinkage int sys_stat(char * filename, struct old_stat * statbuf)
{
struct inode * inode;
int error;
@@ -102,7 +102,7 @@
return 0;
}
-extern "C" int sys_newstat(char * filename, struct new_stat * statbuf)
+asmlinkage int sys_newstat(char * filename, struct new_stat * statbuf)
{
struct inode * inode;
int error;
@@ -118,7 +118,7 @@
return 0;
}
-extern "C" int sys_lstat(char * filename, struct old_stat * statbuf)
+asmlinkage int sys_lstat(char * filename, struct old_stat * statbuf)
{
struct inode * inode;
int error;
@@ -134,7 +134,7 @@
return 0;
}
-extern "C" int sys_newlstat(char * filename, struct new_stat * statbuf)
+asmlinkage int sys_newlstat(char * filename, struct new_stat * statbuf)
{
struct inode * inode;
int error;
@@ -150,7 +150,7 @@
return 0;
}
-extern "C" int sys_fstat(unsigned int fd, struct old_stat * statbuf)
+asmlinkage int sys_fstat(unsigned int fd, struct old_stat * statbuf)
{
struct file * f;
struct inode * inode;
@@ -165,7 +165,7 @@
return 0;
}
-extern "C" int sys_newfstat(unsigned int fd, struct new_stat * statbuf)
+asmlinkage int sys_newfstat(unsigned int fd, struct new_stat * statbuf)
{
struct file * f;
struct inode * inode;
@@ -180,7 +180,7 @@
return 0;
}
-extern "C" int sys_readlink(const char * path, char * buf, int bufsiz)
+asmlinkage int sys_readlink(const char * path, char * buf, int bufsiz)
{
struct inode * inode;
int error;
diff -u --recursive --new-file pl12/linux/fs/super.c linux/fs/super.c
--- pl12/linux/fs/super.c Wed Aug 11 20:56:05 1993
+++ linux/fs/super.c Sat Sep 4 03:36:30 1993
@@ -243,7 +243,7 @@
* functions, they should be faked here. -- jrs
*/
-extern "C" int sys_umount(char * name)
+asmlinkage int sys_umount(char * name)
{
struct inode * inode;
dev_t dev;
@@ -390,7 +390,7 @@
* isn't present, the flags and data info isn't used, as the syscall assumes we
* are talking to an older version that didn't understand them.
*/
-extern "C" int sys_mount(char * dev_name, char * dir_name, char * type,
+asmlinkage int sys_mount(char * dev_name, char * dir_name, char * type,
unsigned long new_flags, void * data)
{
struct file_system_type * fstype;
diff -u --recursive --new-file pl12/linux/ibcs/emulate.c linux/ibcs/emulate.c
--- pl12/linux/ibcs/emulate.c Sat Jul 3 00:36:31 1993
+++ linux/ibcs/emulate.c Sat Sep 4 14:29:34 1993
@@ -20,7 +20,7 @@
#include <asm/segment.h>
#include <asm/system.h>
-extern "C" void iABI_emulate(struct pt_regs * regs)
+asmlinkage void iABI_emulate(struct pt_regs * regs)
{
printk("lcall 7,xxx: eax = %08x\n",regs->eax);
}
diff -u --recursive --new-file pl12/linux/include/asm/irq.h linux/include/asm/irq.h
--- pl12/linux/include/asm/irq.h Sun Jul 18 17:19:24 1993
+++ linux/include/asm/irq.h Sat Sep 4 03:00:24 1993
@@ -8,6 +8,8 @@
*/
#include <linux/segment.h>
+#include <linux/linkage.h>
+
#define __STR(x) #x
#define STR(x) __STR(x)
@@ -117,9 +119,9 @@
#define BAD_IRQ_NAME(nr) IRQ_NAME2(bad_IRQ##nr)
#define BUILD_IRQ(chip,nr,mask) \
-extern "C" void IRQ_NAME(nr); \
-extern "C" void FAST_IRQ_NAME(nr); \
-extern "C" void BAD_IRQ_NAME(nr); \
+asmlinkage void IRQ_NAME(nr); \
+asmlinkage void FAST_IRQ_NAME(nr); \
+asmlinkage void BAD_IRQ_NAME(nr); \
__asm__( \
"\n.align 4\n" \
"_IRQ" #nr "_interrupt:\n\t" \
diff -u --recursive --new-file pl12/linux/include/asm/segment.h linux/include/asm/segment.h
--- pl12/linux/include/asm/segment.h Mon Aug 2 14:31:28 1993
+++ linux/include/asm/segment.h Sat Sep 4 03:02:56 1993
@@ -1,7 +1,7 @@
#ifndef _ASM_SEGMENT_H
#define _ASM_SEGMENT_H
-static inline unsigned char get_fs_byte(const char * addr)
+static inline unsigned char get_user_byte(const char * addr)
{
register unsigned char _v;
@@ -9,23 +9,9 @@
return _v;
}
-static inline unsigned char get_fs_byte(const unsigned char * addr)
-{
- register unsigned char _v;
-
- __asm__ ("movb %%fs:%1,%0":"=q" (_v):"m" (*addr));
- return _v;
-}
-
-static inline unsigned short get_fs_word(const short *addr)
-{
- unsigned short _v;
-
- __asm__ ("movw %%fs:%1,%0":"=r" (_v):"m" (*addr));
- return _v;
-}
+#define get_fs_byte(addr) get_user_byte((char *)(addr))
-static inline unsigned short get_fs_word(const unsigned short *addr)
+static inline unsigned short get_user_word(const short *addr)
{
unsigned short _v;
@@ -33,31 +19,9 @@
return _v;
}
-static inline unsigned long get_fs_long(const int *addr)
-{
- unsigned long _v;
-
- __asm__ ("movl %%fs:%1,%0":"=r" (_v):"m" (*addr)); \
- return _v;
-}
-
-static inline unsigned long get_fs_long(const unsigned int *addr)
-{
- unsigned long _v;
-
- __asm__ ("movl %%fs:%1,%0":"=r" (_v):"m" (*addr)); \
- return _v;
-}
-
-static inline unsigned long get_fs_long(const long *addr)
-{
- unsigned long _v;
-
- __asm__ ("movl %%fs:%1,%0":"=r" (_v):"m" (*addr)); \
- return _v;
-}
+#define get_fs_word(addr) get_user_word((short *)(addr))
-static inline unsigned long get_fs_long(const unsigned long *addr)
+static inline unsigned long get_user_long(const int *addr)
{
unsigned long _v;
@@ -65,45 +29,28 @@
return _v;
}
-static inline void put_fs_byte(char val,char *addr)
-{
-__asm__ ("movb %0,%%fs:%1": /* no outputs */ :"iq" (val),"m" (*addr));
-}
+#define get_fs_long(addr) get_user_long((int *)(addr))
-static inline void put_fs_byte(char val,unsigned char *addr)
+static inline void put_user_byte(char val,char *addr)
{
__asm__ ("movb %0,%%fs:%1": /* no outputs */ :"iq" (val),"m" (*addr));
}
-static inline void put_fs_word(short val,short * addr)
-{
-__asm__ ("movw %0,%%fs:%1": /* no outputs */ :"ir" (val),"m" (*addr));
-}
+#define put_fs_byte(x,addr) put_user_byte((x),(char *)(addr))
-static inline void put_fs_word(short val,unsigned short * addr)
+static inline void put_user_word(short val,short * addr)
{
__asm__ ("movw %0,%%fs:%1": /* no outputs */ :"ir" (val),"m" (*addr));
}
-static inline void put_fs_long(unsigned long val,int * addr)
-{
-__asm__ ("movl %0,%%fs:%1": /* no outputs */ :"ir" (val),"m" (*addr));
-}
-
-static inline void put_fs_long(unsigned long val,unsigned int * addr)
-{
-__asm__ ("movl %0,%%fs:%1": /* no outputs */ :"ir" (val),"m" (*addr));
-}
+#define put_fs_word(x,addr) put_user_word((x),(short *)(addr))
-static inline void put_fs_long(unsigned long val,long * addr)
+static inline void put_user_long(unsigned long val,int * addr)
{
__asm__ ("movl %0,%%fs:%1": /* no outputs */ :"ir" (val),"m" (*addr));
}
-static inline void put_fs_long(unsigned long val,unsigned long * addr)
-{
-__asm__ ("movl %0,%%fs:%1": /* no outputs */ :"ir" (val),"m" (*addr));
-}
+#define put_fs_long(x,addr) put_user_long((x),(int *)(addr))
static inline void memcpy_tofs(void * to, const void * from, unsigned long n)
{
diff -u --recursive --new-file pl12/linux/include/linux/a.out.h linux/include/linux/a.out.h
--- pl12/linux/include/linux/a.out.h Mon Aug 9 17:41:23 1993
+++ linux/include/linux/a.out.h Fri Aug 20 08:59:31 1993
@@ -71,24 +71,26 @@
#define NMAGIC 0410
/* Code indicating demand-paged executable. */
#define ZMAGIC 0413
+/* This indicates a demand-paged executable with the header in the text.
+ The first page is unmapped to help trap NULL pointer references */
+#define QMAGIC 0314
/* Code indicating core file. */
#define CMAGIC 0421
+
#if !defined (N_BADMAG)
-#define N_BADMAG(x) \
- (N_MAGIC(x) != OMAGIC && N_MAGIC(x) != NMAGIC \
- && N_MAGIC(x) != ZMAGIC)
+#define N_BADMAG(x) (N_MAGIC(x) != OMAGIC \
+ && N_MAGIC(x) != NMAGIC \
+ && N_MAGIC(x) != ZMAGIC \
+ && N_MAGIC(x) != QMAGIC)
#endif
-#define _N_BADMAG(x) \
- (N_MAGIC(x) != OMAGIC && N_MAGIC(x) != NMAGIC \
- && N_MAGIC(x) != ZMAGIC)
-
#define _N_HDROFF(x) (1024 - sizeof (struct exec))
#if !defined (N_TXTOFF)
#define N_TXTOFF(x) \
- (N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) : sizeof (struct exec))
+ (N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) : \
+ (N_MAGIC(x) == QMAGIC ? 0 : sizeof (struct exec)))
#endif
#if !defined (N_DATOFF)
@@ -113,7 +115,7 @@
/* Address of text segment in memory after it is loaded. */
#if !defined (N_TXTADDR)
-#define N_TXTADDR(x) 0
+#define N_TXTADDR(x) (N_MAGIC(x) == QMAGIC ? PAGE_SIZE : 0)
#endif
/* Address of data segment in memory after it is loaded.
diff -u --recursive --new-file pl12/linux/include/linux/binfmts.h linux/include/linux/binfmts.h
--- pl12/linux/include/linux/binfmts.h Fri Aug 6 13:32:00 1993
+++ linux/include/linux/binfmts.h Sat Sep 4 03:39:51 1993
@@ -1,6 +1,8 @@
#ifndef _LINUX_BINFMTS_H
#define _LINUX_BINFMTS_H
+#include <linux/ptrace.h>
+
/*
* MAX_ARG_PAGES defines the number of pages allocated for arguments
* and envelope for the new program. 32 should suffice, this gives
@@ -15,6 +17,7 @@
char buf[128];
unsigned long page[MAX_ARG_PAGES];
unsigned long p;
+ int sh_bang;
struct inode * inode;
int e_uid, e_gid;
int argc, envc;
@@ -31,6 +34,15 @@
extern struct linux_binfmt formats[];
+extern int read_exec(struct inode *inode, unsigned long offset,
+ char * addr, unsigned long count);
+
+extern int open_inode(struct inode * inode, int mode);
+extern void flush_old_exec(struct linux_binprm * bprm);
+extern unsigned long change_ldt(unsigned long text_size,unsigned long * page);
+extern unsigned long * create_tables(char * p,int argc,int envc);
+extern unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
+ unsigned long p, int from_kmem);
#endif
diff -u --recursive --new-file pl12/linux/include/linux/elf.h linux/include/linux/elf.h
--- pl12/linux/include/linux/elf.h
+++ linux/include/linux/elf.h Sat Sep 4 01:48:20 1993
@@ -0,0 +1,153 @@
+#ifndef _ELF_H
+#define _ELF_H
+
+/* THese constants are for the segment types stored in the image headers */
+#define PT_NULL 0
+#define PT_LOAD 1
+#define PT_DYNAMIC 2
+#define PT_INTERP 3
+#define PT_NOTE 4
+#define PT_SHLIB 5
+#define PT_PHDR 6
+#define PT_LOPROC 0x70000000
+#define PT_HIPROC 0x7fffffff
+
+/* These constants define the different elf file types */
+#define ET_NONE 0
+#define ET_REL 1
+#define ET_EXEC 2
+#define ET_DYN 3
+#define ET_CORE 4
+#define ET_LOPROC 5
+#define ET_HIPROC 6
+
+/* These constants define the various ELF target machines */
+#define EM_NONE 0
+#define EM_M32 1
+#define EM_SPARC 2
+#define EM_386 3
+#define EM_68K 4
+#define EM_88K 5
+#define EM_486 6 /* Perhaps disused */
+#define EM_860 7
+
+/* This is the info that is needed to parse the dynamic section of the file */
+#define DT_NULL 0
+#define DT_NEEDED 1
+#define DT_PLTRELSZ 2
+#define DT_PLTGOT 3
+#define DT_HASH 4
+#define DT_STRTAB 5
+#define DT_SYMTAB 6
+#define DT_RELA 7
+#define DT_RELASZ 8
+#define DT_RELAENT 9
+#define DT_STRSZ 10
+#define DT_SYMENT 11
+#define DT_INIT 12
+#define DT_FINI 13
+#define DT_SONAME 14
+#define DT_RPATH 15
+#define DT_SYMBOLIC 16
+#define DT_REL 17
+#define DT_RELSZ 18
+#define DT_RELENT 19
+#define DT_PLTREL 20
+#define DT_DEBUG 21
+#define DT_TEXTREL 22
+#define DT_JMPREL 23
+#define DT_LOPROC 0x70000000
+#define DT_HIPROC 0x7fffffff
+
+/* This info is needed when parsing the symbol table */
+#define STB_LOCAL 0
+#define STB_GLOBAL 1
+#define STB_WEAK 2
+
+#define STT_NOTYPE 0
+#define STT_OBJECT 1
+#define STT_FUNC 2
+#define STT_SECTION 3
+#define STT_FILE 4
+
+#define ELF32_ST_BIND(x) ((x) >> 4)
+#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf)
+
+
+
+struct dynamic{
+ int d_tag;
+ union{
+ int d_val;
+ char * d_ptr;
+ } d_un;
+};
+
+/* THe following are used with relocations */
+#define ELF32_R_SYM(x) ((x) >> 8)
+#define ELF32_R_TYPE(x) ((x) & 0xff)
+
+#define R_386_NONE 0
+#define R_386_32 1
+#define R_386_PC32 2
+#define R_386_GOT32 3
+#define R_386_PLT32 4
+#define R_386_COPY 5
+#define R_386_GLOB_DAT 6
+#define R_386_JMP_SLOT 7
+#define R_386_RELATIVE 8
+#define R_386_GOTOFF 9
+#define R_386_GOTPC 10
+#define R_386_NUM 11
+
+struct Elf32_Rel{
+ unsigned int * offset;
+ int info;
+};
+
+struct Elf32_Rela{
+ unsigned int * offset;
+ int info;
+ int addend;
+};
+
+struct Elf32_Sym{
+ int st_name;
+ unsigned int st_value;
+ int st_size;
+ unsigned char st_info;
+ unsigned char st_other;
+ short int st_shndx;
+};
+
+struct elfhdr{
+ char e_ident[16];
+ short int e_type;
+ short int e_machine;
+ int e_version;
+ char *e_entry; /* Entry point */
+ int e_phoff;
+ int e_shoff;
+ int e_flags;
+ short int e_ehsize;
+ short int e_phentsize;
+ short int e_phnum;
+ short int e_shentsize;
+ short int e_shnum;
+ short int e_shstrndx;
+};
+
+struct elf_phdr{
+ int p_type;
+ int p_offset;
+ int p_vaddr;
+ int p_paddr;
+ int p_filesz;
+ int p_memsz;
+ int p_flags;
+ int p_align;
+};
+
+#define ELF_START_MMAP 0x80000000
+
+#endif
diff -u --recursive --new-file pl12/linux/include/linux/fs.h linux/include/linux/fs.h
--- pl12/linux/include/linux/fs.h Wed Aug 11 22:52:45 1993
+++ linux/include/linux/fs.h Sat Sep 4 02:55:18 1993
@@ -6,6 +6,7 @@
* structures etc.
*/
+#include <linux/linkage.h>
#include <linux/limits.h>
#include <linux/wait.h>
#include <linux/types.h>
@@ -319,8 +320,8 @@
#ifdef __KERNEL__
-extern "C" int sys_open(const char *, int, int);
-extern "C" int sys_close(unsigned int); /* yes, it's really unsigned */
+asmlinkage int sys_open(const char *, int, int);
+asmlinkage int sys_close(unsigned int); /* yes, it's really unsigned */
extern int getname(const char * filename, char **result);
extern void putname(char * name);
diff -u --recursive --new-file pl12/linux/include/linux/ioport.h linux/include/linux/ioport.h
--- pl12/linux/include/linux/ioport.h
+++ linux/include/linux/ioport.h Wed Sep 1 17:39:36 1993
@@ -0,0 +1,28 @@
+/*
+ * portio.h Definitions of routines for detecting, reserving and
+ * allocating system resources.
+ *
+ * Version: 0.01 8/30/93
+ *
+ * Author: Donald Becker (becker@super.org)
+ */
+
+#ifndef _LINUX_PORTIO_H
+#define _LINUX_PORTIO_H
+
+#define HAVE_PORTRESERVE
+/*
+ * Call check_region() before probing for your hardware.
+ * Once you have found you hardware, register it with snarf_region().
+ */
+extern void reserve_setup(char *str, int *ints);
+extern int check_region(unsigned int from, unsigned int extent);
+extern void snarf_region(unsigned int from, unsigned int extent);
+
+
+#define HAVE_AUTOIRQ
+extern void *irq2dev_map[16]; /* Use only if you own the IRQ. */
+extern void autoirq_setup(int waittime);
+extern int autoirq_report(int waittime);
+
+#endif /* _LINUX_PORTIO_H */
diff -u --recursive --new-file pl12/linux/include/linux/kernel.h linux/include/linux/kernel.h
--- pl12/linux/include/linux/kernel.h Mon Aug 9 18:02:30 1993
+++ linux/include/linux/kernel.h Sat Sep 4 02:56:46 1993
@@ -8,6 +8,7 @@
#ifdef __KERNEL__
#include <linux/config.h>
+#include <linux/linkage.h>
#define INT_MAX ((int)(~0U>>1))
#define UINT_MAX (~0U)
@@ -25,7 +26,7 @@
unsigned long simple_strtoul(const char *,char **,unsigned int);
int sprintf(char * buf, const char * fmt, ...);
-extern "C" int printk(const char * fmt, ...);
+asmlinkage int printk(const char * fmt, ...);
#ifdef CONFIG_DEBUG_MALLOC
#define kmalloc(a,b) deb_kmalloc(__FILE__,__LINE__, a,b)
diff -u --recursive --new-file pl12/linux/include/linux/linkage.h linux/include/linux/linkage.h
--- pl12/linux/include/linux/linkage.h
+++ linux/include/linux/linkage.h Sat Sep 4 02:56:10 1993
@@ -0,0 +1,10 @@
+#ifndef _LINUX_LINKAGE_H
+#define _LINUX_LINKAGE_H
+
+#ifdef __cplusplus
+#define asmlinkage extern "C"
+#else
+#define asmlinkage
+#endif
+
+#endif
diff -u --recursive --new-file pl12/linux/include/linux/page.h linux/include/linux/page.h
--- pl12/linux/include/linux/page.h Mon Aug 9 18:02:30 1993
+++ linux/include/linux/page.h Sat Sep 4 03:09:00 1993
@@ -25,7 +25,7 @@
((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)*2&PTR_MASK&~PAGE_MASK)))
/* to find an entry in a page-table */
#define PAGE_PTR(address) \
- ((unsigned long)(address)>>PAGE_SHIFT-SIZEOF_PTR_LOG2&PTR_MASK&~PAGE_MASK)
+ ((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
/* the no. of pointers that fit on a page */
#define PTRS_PER_PAGE (PAGE_SIZE/sizeof(void*))
diff -u --recursive --new-file pl12/linux/include/linux/sched.h linux/include/linux/sched.h
--- pl12/linux/include/linux/sched.h Sat Aug 14 16:01:26 1993
+++ linux/include/linux/sched.h Sat Sep 4 02:42:39 1993
@@ -85,7 +85,7 @@
extern void trap_init(void);
extern void panic(const char * str);
-extern "C" void schedule(void);
+asmlinkage void schedule(void);
#endif /* __KERNEL__ */
diff -u --recursive --new-file pl12/linux/include/linux/shm.h linux/include/linux/shm.h
--- pl12/linux/include/linux/shm.h Mon Aug 9 18:02:30 1993
+++ linux/include/linux/shm.h Sun Aug 29 23:26:57 1993
@@ -63,11 +63,11 @@
#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1)
#define SHM_READ_ONLY (1<<BITS_PER_PTR-1)
-#define SHMMAX (1<<PAGE_SHIFT+_SHM_IDX_BITS) /* max shared seg size (bytes) */
-#define SHMMIN 1 /* really PAGE_SIZE */ /* min shared seg size (bytes)*/
+#define SHMMAX 0x400000 /* max shared seg size (bytes) */
+#define SHMMIN 1 /* really PAGE_SIZE */ /* min shared seg size (bytes) */
#define SHMMNI (1<<_SHM_ID_BITS) /* max num of segs system wide */
#define SHMALL (1<<_SHM_IDX_BITS+_SHM_ID_BITS) /* max shm system wide (pages) */
-#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */
+#define SHMLBA 0x1000 /* attach addr a multiple of this */
#define SHMSEG SHMMNI /* max shared segs per process */
#ifdef __KERNEL__
diff -u --recursive --new-file pl12/linux/include/linux/signal.h linux/include/linux/signal.h
--- pl12/linux/include/linux/signal.h Thu May 20 10:34:30 1993
+++ linux/include/linux/signal.h Mon Aug 16 18:55:12 1993
@@ -53,6 +53,9 @@
*/
#define SIGPWR 30
+/* Arggh. Bad user source code wants this.. */
+#define SIGBUS SIGUNUSED
+
/*
* sa_flags values: SA_STACK is not currently supported, but will allow the
* usage of signal stacks by using the (now obsolete) sa_restorer field in
diff -u --recursive --new-file pl12/linux/include/linux/sys.h linux/include/linux/sys.h
--- pl12/linux/include/linux/sys.h Tue Jul 20 01:35:31 1993
+++ linux/include/linux/sys.h Sat Sep 4 02:43:53 1993
@@ -4,7 +4,9 @@
#define sys_clone sys_fork
+#ifdef __cplusplus
extern "C" {
+#endif
extern int sys_setup();
extern int sys_exit();
@@ -170,7 +172,9 @@
sys_wait4, sys_swapoff, sys_sysinfo, sys_ipc, sys_fsync, sys_sigreturn,
sys_clone, sys_setdomainname, sys_newuname, sys_modify_ldt};
+#ifdef __cplusplus
}
+#endif
/* So we don't have to do any more manual updating.... */
int NR_syscalls = sizeof(sys_call_table)/sizeof(fn_ptr);
diff -u --recursive --new-file pl12/linux/include/linux/tasks.h linux/include/linux/tasks.h
--- pl12/linux/include/linux/tasks.h Mon Jan 18 22:06:34 1993
+++ linux/include/linux/tasks.h Wed Aug 18 23:05:21 1993
@@ -4,6 +4,6 @@
/*
* This is the maximum nr of tasks - change it if you need to
*/
-#define NR_TASKS 64
+#define NR_TASKS 128
#endif
diff -u --recursive --new-file pl12/linux/include/linux/timer.h linux/include/linux/timer.h
--- pl12/linux/include/linux/timer.h Sat Aug 14 23:47:22 1993
+++ linux/include/linux/timer.h Tue Aug 17 18:39:34 1993
@@ -17,6 +17,8 @@
*
* HD_TIMER harddisk timer
*
+ * HD_TIMER2 (atdisk2 patches)
+ *
* FLOPPY_TIMER floppy disk timer (not used right now)
*
* SCSI_TIMER scsi.c timeout timer
@@ -43,6 +45,8 @@
#define TAPE_QIC02_TIMER 22 /* hhb */
#define MCD_TIMER 23
+
+#define HD_TIMER2 24
struct timer_struct {
unsigned long expires;
diff -u --recursive --new-file pl12/linux/init/main.c linux/init/main.c
--- pl12/linux/init/main.c Mon Aug 9 18:02:31 1993
+++ linux/init/main.c Sat Sep 4 02:58:36 1993
@@ -23,12 +23,13 @@
#include <linux/ctype.h>
#include <linux/delay.h>
#include <linux/utsname.h>
+#include <linux/ioport.h>
extern unsigned long * prof_buffer;
extern unsigned long prof_len;
extern char edata, end;
extern char *linux_banner;
-extern "C" void lcall7(void);
+asmlinkage void lcall7(void);
struct desc_struct default_ldt;
/*
@@ -43,6 +44,7 @@
* won't be any messing with the stack from main(), but we define
* some others too.
*/
+#define __NR__exit __NR_exit
static inline _syscall0(int,idle)
static inline _syscall0(int,fork)
static inline _syscall0(int,pause)
@@ -54,7 +56,7 @@
static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
static inline _syscall1(int,close,int,fd)
-static inline _syscall1(int,exit,int,exitcode)
+static inline _syscall1(int,_exit,int,exitcode)
static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
static inline pid_t wait(int * wait_stat)
@@ -189,6 +191,7 @@
char *str;
void (*setup_func)(char *, int *);
} bootsetups[] = {
+ { "reserve=", reserve_setup },
#ifdef CONFIG_INET
{ "ether=", eth_setup },
#endif
@@ -329,7 +332,7 @@
outb_p(0,0xf0);
}
-extern "C" void start_kernel(void)
+asmlinkage void start_kernel(void)
{
/*
* Interrupts are still disabled. Do necessary setups, then
@@ -466,9 +469,9 @@
if (!(pid=fork())) {
close(0);
if (open("/etc/rc",O_RDONLY,0))
- exit(1);
+ _exit(1);
execve("/bin/sh",argv_rc,envp_rc);
- exit(2);
+ _exit(2);
}
if (pid>0)
while (pid != wait(&i))
@@ -484,7 +487,7 @@
(void) open("/dev/tty1",O_RDWR,0);
(void) dup(0);
(void) dup(0);
- exit(execve("/bin/sh",argv,envp));
+ _exit(execve("/bin/sh",argv,envp));
}
while (1)
if (pid == wait(&i))
@@ -492,5 +495,5 @@
printf("\n\rchild %d died with code %04x\n\r",pid,i);
sync();
}
- exit(0);
+ _exit(0);
}
diff -u --recursive --new-file pl12/linux/ipc/util.c linux/ipc/util.c
--- pl12/linux/ipc/util.c Mon Aug 9 18:02:31 1993
+++ linux/ipc/util.c Sat Sep 4 14:29:20 1993
@@ -13,7 +13,7 @@
#include <linux/stat.h>
void ipc_init (void);
-extern "C" int sys_ipc (uint call, int first, int second, int third, void *ptr);
+asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr);
#ifdef CONFIG_SYSVIPC
@@ -67,7 +67,7 @@
return 0;
}
-extern "C" int sys_ipc (uint call, int first, int second, int third, void *ptr)
+asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr)
{
if (call <= SEMCTL)
@@ -123,7 +123,7 @@
#else /* not CONFIG_SYSVIPC */
-extern "C" int sys_ipc (uint call, int first, int second, int third, void *ptr)
+asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr)
{
return -ENOSYS;
}
diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/errors.c linux/kernel/FPU-emu/errors.c
--- pl12/linux/kernel/FPU-emu/errors.c Thu Jul 22 01:11:49 1993
+++ linux/kernel/FPU-emu/errors.c Sat Sep 4 03:25:27 1993
@@ -312,7 +312,7 @@
/* Real operation attempted on two operands, one a NaN. */
/* Returns nz if the exception is unmasked */
-extern "C" int real_2op_NaN(FPU_REG *a, FPU_REG *b, FPU_REG *dest)
+asmlinkage int real_2op_NaN(FPU_REG *a, FPU_REG *b, FPU_REG *dest)
{
FPU_REG *x;
int signalling;
@@ -326,7 +326,7 @@
{
signalling = !(a->sigh & b->sigh & 0x40000000);
/* find the "larger" */
- if ( *(long long *)&(a->sigl) < *(long long *)&(b->sigl) )
+ if ( significand(a) < significand(b) )
x = b;
}
else
@@ -378,7 +378,7 @@
/* Invalid arith operation on Valid registers */
/* Returns nz if the exception is unmasked */
-extern "C" int arith_invalid(FPU_REG *dest)
+asmlinkage int arith_invalid(FPU_REG *dest)
{
EXCEPTION(EX_Invalid);
@@ -395,7 +395,7 @@
/* Divide a finite number by zero */
-extern "C" int divide_by_zero(int sign, FPU_REG *dest)
+asmlinkage int divide_by_zero(int sign, FPU_REG *dest)
{
if ( control_word & CW_ZeroDiv )
@@ -430,7 +430,7 @@
/* This may be called often, so keep it lean */
-extern "C" void set_precision_flag_up(void)
+asmlinkage void set_precision_flag_up(void)
{
if ( control_word & CW_Precision )
partial_status |= (SW_Precision | SW_C1); /* The masked response */
@@ -441,7 +441,7 @@
/* This may be called often, so keep it lean */
-extern "C" void set_precision_flag_down(void)
+asmlinkage void set_precision_flag_down(void)
{
if ( control_word & CW_Precision )
{ /* The masked response */
@@ -453,7 +453,7 @@
}
-extern "C" int denormal_operand(void)
+asmlinkage int denormal_operand(void)
{
if ( control_word & CW_Denormal )
{ /* The masked response */
@@ -468,7 +468,7 @@
}
-extern "C" int arith_overflow(FPU_REG *dest)
+asmlinkage int arith_overflow(FPU_REG *dest)
{
if ( control_word & CW_Overflow )
@@ -502,7 +502,7 @@
}
-extern "C" int arith_underflow(FPU_REG *dest)
+asmlinkage int arith_underflow(FPU_REG *dest)
{
if ( control_word & CW_Underflow )
diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/fpu_arith.c linux/kernel/FPU-emu/fpu_arith.c
--- pl12/linux/kernel/FPU-emu/fpu_arith.c Thu Jul 22 01:11:50 1993
+++ linux/kernel/FPU-emu/fpu_arith.c Wed Sep 1 18:30:04 1993
@@ -19,10 +19,7 @@
void fadd__()
{
/* fadd st,st(i) */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
reg_add(FPU_st0_ptr, &st(FPU_rm), FPU_st0_ptr, control_word);
}
@@ -30,10 +27,7 @@
void fmul__()
{
/* fmul st,st(i) */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
reg_mul(FPU_st0_ptr, &st(FPU_rm), FPU_st0_ptr, control_word);
}
@@ -42,10 +36,7 @@
void fsub__()
{
/* fsub st,st(i) */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
reg_sub(FPU_st0_ptr, &st(FPU_rm), FPU_st0_ptr, control_word);
}
@@ -53,10 +44,7 @@
void fsubr_()
{
/* fsubr st,st(i) */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
reg_sub(&st(FPU_rm), FPU_st0_ptr, FPU_st0_ptr, control_word);
}
@@ -64,10 +52,7 @@
void fdiv__()
{
/* fdiv st,st(i) */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
reg_div(FPU_st0_ptr, &st(FPU_rm), FPU_st0_ptr, control_word);
}
@@ -75,10 +60,7 @@
void fdivr_()
{
/* fdivr st,st(i) */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
reg_div(&st(FPU_rm), FPU_st0_ptr, FPU_st0_ptr, control_word);
}
@@ -87,10 +69,7 @@
void fadd_i()
{
/* fadd st(i),st */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
reg_add(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word);
}
@@ -98,10 +77,7 @@
void fmul_i()
{
/* fmul st(i),st */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
reg_mul(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word);
}
@@ -111,10 +87,7 @@
/* fsubr st(i),st */
/* This is the sense of the 80486 manual
reg_sub(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm), control_word); */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
reg_sub(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word);
}
@@ -124,10 +97,7 @@
/* fsub st(i),st */
/* This is the sense of the 80486 manual
reg_sub(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word); */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
reg_sub(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm), control_word);
}
@@ -135,10 +105,7 @@
void fdivri()
{
/* fdivr st(i),st */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
reg_div(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word);
}
@@ -146,10 +113,7 @@
void fdiv_i()
{
/* fdiv st(i),st */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
reg_div(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm), control_word);
}
@@ -158,10 +122,7 @@
void faddp_()
{
/* faddp st(i),st */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
if ( !reg_add(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word) )
pop();
}
@@ -170,10 +131,7 @@
void fmulp_()
{
/* fmulp st(i),st */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
if ( !reg_mul(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word) )
pop();
}
@@ -185,10 +143,7 @@
/* fsubrp st(i),st */
/* This is the sense of the 80486 manual
reg_sub(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm), control_word); */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
if ( !reg_sub(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word) )
pop();
}
@@ -199,10 +154,7 @@
/* fsubp st(i),st */
/* This is the sense of the 80486 manual
reg_sub(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word); */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
if ( !reg_sub(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm), control_word) )
pop();
}
@@ -211,10 +163,7 @@
void fdivrp()
{
/* fdivrp st(i),st */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
if ( !reg_div(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm), control_word) )
pop();
}
@@ -223,10 +172,7 @@
void fdivp_()
{
/* fdivp st(i),st */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
if ( !reg_div(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm), control_word) )
pop();
}
diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/fpu_aux.c linux/kernel/FPU-emu/fpu_aux.c
--- pl12/linux/kernel/FPU-emu/fpu_aux.c Thu Jul 22 01:11:50 1993
+++ linux/kernel/FPU-emu/fpu_aux.c Wed Sep 1 18:30:04 1993
@@ -139,10 +139,7 @@
stack_underflow();
return;
}
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
reg_move(FPU_st0_ptr, &t);
reg_move(sti_ptr, FPU_st0_ptr);
reg_move(&t, sti_ptr);
diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/fpu_emu.h linux/kernel/FPU-emu/fpu_emu.h
--- pl12/linux/kernel/FPU-emu/fpu_emu.h Thu Jul 22 01:11:50 1993
+++ linux/kernel/FPU-emu/fpu_emu.h Sat Sep 4 03:28:02 1993
@@ -58,6 +58,7 @@
#ifndef __ASSEMBLER__
#include <linux/math_emu.h>
+#include <linux/linkage.h>
#ifdef PARANOID
extern char emulating;
@@ -110,33 +111,36 @@
*(long *)&((y)->exp) = *(long *)&((x)->exp); \
*(long long *)&((y)->sigl) = *(long long *)&((x)->sigl); }
+#define significand(x) ( ((unsigned long long *)&((x)->sigl))[0] )
+
/*----- Prototypes for functions written in assembler -----*/
/* extern void reg_move(FPU_REG *a, FPU_REG *b); */
-extern "C" void mul64(long long *a, long long *b, long long *result);
-extern "C" void poly_div2(long long *x);
-extern "C" void poly_div4(long long *x);
-extern "C" void poly_div16(long long *x);
-extern "C" void polynomial(unsigned accum[], unsigned x[],
+asmlinkage void mul64(unsigned long long *a, unsigned long long *b,
+ unsigned long long *result);
+asmlinkage void poly_div2(unsigned long long *x);
+asmlinkage void poly_div4(unsigned long long *x);
+asmlinkage void poly_div16(unsigned long long *x);
+asmlinkage void polynomial(unsigned accum[], unsigned x[],
unsigned short terms[][4], int n);
-extern "C" void normalize(FPU_REG *x);
-extern "C" void normalize_nuo(FPU_REG *x);
-extern "C" int reg_div(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ,
+asmlinkage void normalize(FPU_REG *x);
+asmlinkage void normalize_nuo(FPU_REG *x);
+asmlinkage int reg_div(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ,
unsigned int control_w);
-extern "C" int reg_u_sub(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ,
+asmlinkage int reg_u_sub(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ,
unsigned int control_w);
-extern "C" int reg_u_mul(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ,
+asmlinkage int reg_u_mul(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ,
unsigned int control_w);
-extern "C" int reg_u_div(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ,
+asmlinkage int reg_u_div(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ,
unsigned int control_w);
-extern "C" int reg_u_add(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ,
+asmlinkage int reg_u_add(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ,
unsigned int control_w);
-extern "C" int wm_sqrt(FPU_REG *n, unsigned int control_w);
-extern "C" unsigned shrx(void *l, unsigned x);
-extern "C" unsigned shrxs(void *v, unsigned x);
-extern "C" unsigned long div_small(unsigned long long *x, unsigned long y);
-extern "C" void round_reg(FPU_REG *arg, unsigned int extent,
+asmlinkage int wm_sqrt(FPU_REG *n, unsigned int control_w);
+asmlinkage unsigned shrx(void *l, unsigned x);
+asmlinkage unsigned shrxs(void *v, unsigned x);
+asmlinkage unsigned long div_small(unsigned long long *x, unsigned long y);
+asmlinkage void round_reg(FPU_REG *arg, unsigned int extent,
unsigned int control_w);
#ifndef MAKING_PROTO
diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/fpu_entry.c linux/kernel/FPU-emu/fpu_entry.c
--- pl12/linux/kernel/FPU-emu/fpu_entry.c Thu Jul 22 01:11:50 1993
+++ linux/kernel/FPU-emu/fpu_entry.c Sat Sep 4 03:25:27 1993
@@ -155,7 +155,7 @@
static int valid_prefix(unsigned char byte);
-extern "C" void math_emulate(long arg)
+asmlinkage void math_emulate(long arg)
{
unsigned char FPU_modrm;
unsigned short code;
@@ -183,7 +183,7 @@
current->used_math = 1;
}
- FPU_info = (struct info *) &arg;
+ SETUP_DATA_AREA(arg);
/* We cannot handle emulation in v86-mode */
if (FPU_EFLAGS & 0x00020000)
@@ -401,20 +401,12 @@
switch ( (FPU_modrm >> 3) & 7 )
{
case 0: /* fadd */
-#ifdef PECULIAR_486
- /* Default, this conveys no information,
- but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
reg_add(FPU_st0_ptr, &FPU_loaded_data, FPU_st0_ptr,
control_word);
break;
case 1: /* fmul */
-#ifdef PECULIAR_486
- /* Default, this conveys no information,
- but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
reg_mul(FPU_st0_ptr, &FPU_loaded_data, FPU_st0_ptr,
control_word);
break;
@@ -426,38 +418,22 @@
pop();
break;
case 4: /* fsub */
-#ifdef PECULIAR_486
- /* Default, this conveys no information,
- but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
reg_sub(FPU_st0_ptr, &FPU_loaded_data, FPU_st0_ptr,
control_word);
break;
case 5: /* fsubr */
-#ifdef PECULIAR_486
- /* Default, this conveys no information,
- but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
reg_sub(&FPU_loaded_data, FPU_st0_ptr, FPU_st0_ptr,
control_word);
break;
case 6: /* fdiv */
-#ifdef PECULIAR_486
- /* Default, this conveys no information,
- but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
reg_div(FPU_st0_ptr, &FPU_loaded_data, FPU_st0_ptr,
control_word);
break;
case 7: /* fdivr */
-#ifdef PECULIAR_486
- /* Default, this conveys no information,
- but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
if ( FPU_st0_tag == TW_Zero )
partial_status = status1; /* Undo any denorm tag,
zero-divide has priority. */
@@ -637,7 +613,7 @@
#include <linux/signal.h>
#include <linux/sched.h>
-extern "C" void math_emulate(long arg)
+asmlinkage void math_emulate(long arg)
{
printk("math-emulation not enabled and no coprocessor found.\n");
printk("killing %s.\n",current->comm);
diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/fpu_etc.c linux/kernel/FPU-emu/fpu_etc.c
--- pl12/linux/kernel/FPU-emu/fpu_etc.c Thu Jul 22 01:11:50 1993
+++ linux/kernel/FPU-emu/fpu_etc.c Wed Sep 1 18:30:04 1993
@@ -22,10 +22,7 @@
if ( NOT_EMPTY_0 )
{
FPU_st0_ptr->sign ^= SIGN_POS^SIGN_NEG;
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
}
else
stack_underflow();
@@ -36,10 +33,7 @@
if ( FPU_st0_tag ^ TW_Empty )
{
FPU_st0_ptr->sign = SIGN_POS;
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
}
else
stack_underflow();
diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/fpu_proto.h linux/kernel/FPU-emu/fpu_proto.h
--- pl12/linux/kernel/FPU-emu/fpu_proto.h Thu Jul 22 01:11:50 1993
+++ linux/kernel/FPU-emu/fpu_proto.h Sat Sep 4 03:25:27 1993
@@ -6,15 +6,15 @@
extern void stack_underflow_i(int i);
extern void stack_underflow_pop(int i);
extern int set_precision_flag(int flags);
-extern "C" void exception(int n);
-extern "C" int real_2op_NaN(FPU_REG *a, FPU_REG *b, FPU_REG *dest);
-extern "C" int arith_invalid(FPU_REG *dest);
-extern "C" int divide_by_zero(int sign, FPU_REG *dest);
-extern "C" void set_precision_flag_up(void);
-extern "C" void set_precision_flag_down(void);
-extern "C" int denormal_operand(void);
-extern "C" int arith_overflow(FPU_REG *dest);
-extern "C" int arith_underflow(FPU_REG *dest);
+asmlinkage void exception(int n);
+asmlinkage int real_2op_NaN(FPU_REG *a, FPU_REG *b, FPU_REG *dest);
+asmlinkage int arith_invalid(FPU_REG *dest);
+asmlinkage int divide_by_zero(int sign, FPU_REG *dest);
+asmlinkage void set_precision_flag_up(void);
+asmlinkage void set_precision_flag_down(void);
+asmlinkage int denormal_operand(void);
+asmlinkage int arith_overflow(FPU_REG *dest);
+asmlinkage int arith_underflow(FPU_REG *dest);
/* fpu_arith.c */
extern void fadd__(void);
@@ -50,7 +50,7 @@
extern void fstp_i(void);
/* fpu_entry.c */
-extern "C" void math_emulate(long arg);
+asmlinkage void math_emulate(long arg);
extern void __math_abort(struct info *info, unsigned int signal);
/* fpu_etc.c */
diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/fpu_system.h linux/kernel/FPU-emu/fpu_system.h
--- pl12/linux/kernel/FPU-emu/fpu_system.h Thu Jul 22 01:11:50 1993
+++ linux/kernel/FPU-emu/fpu_system.h Wed Sep 1 18:30:04 1993
@@ -14,6 +14,10 @@
#include <linux/sched.h>
#include <linux/kernel.h>
+/* This sets the pointer FPU_info to point to the argument part
+ of the stack frame of math_emulate() */
+#define SETUP_DATA_AREA(arg) FPU_info = (struct info *) &arg
+
#define I387 (current->tss.i387)
#define FPU_info (I387.soft.info)
diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/fpu_trig.c linux/kernel/FPU-emu/fpu_trig.c
--- pl12/linux/kernel/FPU-emu/fpu_trig.c Thu Jul 22 01:11:51 1993
+++ linux/kernel/FPU-emu/fpu_trig.c Wed Sep 1 18:30:05 1993
@@ -20,7 +20,7 @@
static void rem_kernel(unsigned long long st0, unsigned long long *y,
unsigned long long st1,
- long long q, int n);
+ unsigned long long q, int n);
#define BETTER_THAN_486
@@ -27,6 +27,7 @@
#define FCOS 4
#define FPTAN 1
+
/* Used only by fptan, fsin, fcos, and fsincos. */
/* This routine produces very accurate results, similar to
using a value of pi with more than 128 bits precision. */
@@ -36,7 +37,7 @@
static int trig_arg(FPU_REG *X, int even)
{
FPU_REG tmp;
- long long q;
+ unsigned long long q;
int old_cw = control_word, saved_status = partial_status;
if ( X->exp >= EXP_BIAS + 63 )
@@ -51,12 +52,12 @@
reg_div(X, &CONST_PI2, &tmp, PR_64_BITS | RC_CHOP | 0x3f);
round_to_int(&tmp); /* Fortunately, this can't overflow
to 2^64 */
- q = ((long long *)&(tmp.sigl))[0];
+ q = significand(&tmp);
if ( q )
{
- rem_kernel(((unsigned long long *)&(X->sigl))[0],
- (unsigned long long *)&(tmp.sigl),
- ((unsigned long long *)&(CONST_PI2.sigl))[0],
+ rem_kernel(significand(X),
+ &significand(&tmp),
+ significand(&CONST_PI2),
q, X->exp - CONST_PI2.exp);
tmp.exp = CONST_PI2.exp;
normalize(&tmp);
@@ -85,7 +86,7 @@
{
/* This code gives the effect of having p/2 to better than
128 bits precision. */
- ((long long *)&(tmp.sigl))[0] = q + 1;
+ significand(&tmp) = q + 1;
tmp.exp = EXP_BIAS + 63;
normalize(&tmp);
reg_mul(&CONST_PI2extra, &tmp, &tmp, FULL_PRECISION);
@@ -104,7 +105,7 @@
{
/* This code gives the effect of having p/2 to better than
128 bits precision. */
- ((long long *)&(tmp.sigl))[0] = q;
+ significand(&tmp) = q;
tmp.exp = EXP_BIAS + 63;
normalize(&tmp);
reg_mul(&CONST_PI2extra, &tmp, &tmp, FULL_PRECISION);
@@ -204,10 +205,7 @@
static void f2xm1(void)
{
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
switch ( FPU_st0_tag )
{
case TW_Valid:
@@ -363,11 +361,7 @@
if ( STACK_OVERFLOW )
{ stack_overflow(); return; }
-
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
if ( !(FPU_st0_tag ^ TW_Valid) )
{
long e;
@@ -432,19 +426,13 @@
static void fdecstp(void)
{
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
top--; /* FPU_st0_ptr will be fixed in math_emulate() before the next instr */
}
static void fincstp(void)
{
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
top++; /* FPU_st0_ptr will be fixed in math_emulate() before the next instr */
}
@@ -451,10 +439,7 @@
static void fsqrt_(void)
{
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
if ( !(FPU_st0_tag ^ TW_Valid) )
{
int expon;
@@ -729,7 +714,7 @@
*/
static void rem_kernel(unsigned long long st0, unsigned long long *y,
unsigned long long st1,
- long long q, int n)
+ unsigned long long q, int n)
{
unsigned long long x;
@@ -790,11 +775,11 @@
{
round_to_int(&tmp); /* Fortunately, this can't overflow
to 2^64 */
- q = ((long long *)&(tmp.sigl))[0];
+ q = significand(&tmp);
- rem_kernel(((unsigned long long *)&(FPU_st0_ptr->sigl))[0],
- (unsigned long long *)&(tmp.sigl),
- ((unsigned long long *)&(st1_ptr->sigl))[0],
+ rem_kernel(significand(FPU_st0_ptr),
+ &significand(&tmp),
+ significand(st1_ptr),
q, expdif);
tmp.exp = st1_ptr->exp;
@@ -808,14 +793,24 @@
if ( (round == RC_RND) && (tmp.sigh & 0xc0000000) )
{
- /* We may need to subtract st(1) once more. */
+ /* We may need to subtract st(1) once more,
+ to get a result <= 1/2 of st(1). */
unsigned long long x;
- x = ((unsigned long long *)&(st1_ptr->sigl))[0] -
- ((unsigned long long *)&(tmp.sigl))[0];
- if ( x < ((unsigned long long *)&(tmp.sigl))[0] )
+ expdif = st1_ptr->exp - tmp.exp;
+ if ( expdif <= 1 )
{
- tmp.sign ^= (SIGN_POS^SIGN_NEG);
- ((unsigned long long *)&(tmp.sigl))[0] = x;
+ if ( expdif == 0 )
+ x = significand(st1_ptr) - significand(&tmp);
+ else /* expdif is 1 */
+ x = (significand(st1_ptr) << 1) - significand(&tmp);
+ if ( (x < significand(&tmp)) ||
+ /* or equi-distant (from 0 & st(1)) and q is odd */
+ ((x == significand(&tmp)) && (q & 1) ) )
+ {
+ tmp.sign ^= (SIGN_POS^SIGN_NEG);
+ significand(&tmp) = x;
+ q++;
+ }
}
}
@@ -849,10 +844,10 @@
round_to_int(&tmp); /* Fortunately, this can't overflow to 2^64 */
- rem_kernel(((unsigned long long *)&(FPU_st0_ptr->sigl))[0],
- ((unsigned long long *)&(tmp.sigl)),
- ((unsigned long long *)&(st1_ptr->sigl))[0],
- ((long long *)&(tmp.sigl))[0],
+ rem_kernel(significand(FPU_st0_ptr),
+ &significand(&tmp),
+ significand(st1_ptr),
+ significand(&tmp),
tmp.exp - EXP_BIAS
);
tmp.exp = exp_1 + expdif;
@@ -882,13 +877,15 @@
control_word = old_cw;
partial_status = saved_status;
- normalize(&tmp);
+ normalize_nuo(&tmp);
reg_move(&tmp, FPU_st0_ptr);
setcc(cc);
- if ( FPU_st0_ptr->tag != TW_Zero )
- /* Use round_reg() to properly detect under/overflow etc */
- round_reg(FPU_st0_ptr, 0, control_word);
+ /* The only condition to be looked for is underflow,
+ and it can occur here only if underflow is unmasked. */
+ if ( (FPU_st0_ptr->exp <= EXP_UNDER) && (FPU_st0_ptr->tag != TW_Zero)
+ && !(control_word & CW_Underflow) )
+ arith_underflow(FPU_st0_ptr);
return;
}
@@ -961,10 +958,7 @@
FPU_REG *st1_ptr = &st(1);
char st1_tag = st1_ptr->tag;
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
if ( !((FPU_st0_tag ^ TW_Valid) | (st1_tag ^ TW_Valid)) )
{
if ( FPU_st0_ptr->sign == SIGN_POS )
@@ -1155,10 +1149,7 @@
char st1_tag = st1_ptr->tag;
char st1_sign = st1_ptr->sign, st0_sign = FPU_st0_ptr->sign;
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
if ( !((FPU_st0_tag ^ TW_Valid) | (st1_tag ^ TW_Valid)) )
{
int saved_control, saved_status;
@@ -1336,10 +1327,7 @@
FPU_REG *st1_ptr = &st(1);
char st1_tag = st1_ptr->tag;
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
if ( !((FPU_st0_tag ^ TW_Valid) | (st1_tag ^ TW_Valid)) )
{
int saved_control, saved_status;
@@ -1560,10 +1548,7 @@
int old_cw = control_word;
char sign = FPU_st0_ptr->sign;
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
if ( !((FPU_st0_tag ^ TW_Valid) | (st1_tag ^ TW_Valid)) )
{
long scale;
diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/load_store.c linux/kernel/FPU-emu/load_store.c
--- pl12/linux/kernel/FPU-emu/load_store.c Thu Jul 22 01:11:51 1993
+++ linux/kernel/FPU-emu/load_store.c Wed Sep 1 18:30:05 1993
@@ -84,10 +84,7 @@
switch ( type )
{
case 000: /* fld m32real */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
reg_load_single();
if ( (FPU_loaded_data.tag == TW_NaN) &&
real_2op_NaN(&FPU_loaded_data, &FPU_loaded_data, &FPU_loaded_data) )
@@ -98,18 +95,12 @@
reg_move(&FPU_loaded_data, pop_ptr);
break;
case 001: /* fild m32int */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
reg_load_int32();
reg_move(&FPU_loaded_data, pop_ptr);
break;
case 002: /* fld m64real */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
reg_load_double();
if ( (FPU_loaded_data.tag == TW_NaN) &&
real_2op_NaN(&FPU_loaded_data, &FPU_loaded_data, &FPU_loaded_data) )
@@ -120,73 +111,46 @@
reg_move(&FPU_loaded_data, pop_ptr);
break;
case 003: /* fild m16int */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
reg_load_int16();
reg_move(&FPU_loaded_data, pop_ptr);
break;
case 010: /* fst m32real */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
reg_store_single();
break;
case 011: /* fist m32int */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
reg_store_int32();
break;
case 012: /* fst m64real */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
reg_store_double();
break;
case 013: /* fist m16int */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
reg_store_int16();
break;
case 014: /* fstp m32real */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
if ( reg_store_single() )
pop_0(); /* pop only if the number was actually stored
(see the 80486 manual p16-28) */
break;
case 015: /* fistp m32int */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
if ( reg_store_int32() )
pop_0(); /* pop only if the number was actually stored
(see the 80486 manual p16-28) */
break;
case 016: /* fstp m64real */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
if ( reg_store_double() )
pop_0(); /* pop only if the number was actually stored
(see the 80486 manual p16-28) */
break;
case 017: /* fistp m16int */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
if ( reg_store_int16() )
pop_0(); /* pop only if the number was actually stored
(see the 80486 manual p16-28) */
@@ -198,10 +162,7 @@
frstor();
break;
case 023: /* fbld m80dec */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
reg_load_bcd();
reg_move(&FPU_loaded_data, pop_ptr);
break;
@@ -220,18 +181,12 @@
NO_NET_INSTR_EFFECT;
break;
case 025: /* fld m80real */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
reg_load_extended();
reg_move(&FPU_loaded_data, pop_ptr);
break;
case 027: /* fild m64int */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
reg_load_int64();
reg_move(&FPU_loaded_data, pop_ptr);
break;
@@ -244,10 +199,7 @@
NO_NET_DATA_EFFECT;
break;
case 033: /* fbstp m80dec */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
if ( reg_store_bcd() )
pop_0(); /* pop only if the number was actually stored
(see the 80486 manual p16-28) */
@@ -261,10 +213,7 @@
NO_NET_INSTR_EFFECT;
break;
case 035: /* fstp m80real */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
if ( reg_store_extended() )
pop_0(); /* pop only if the number was actually stored
(see the 80486 manual p16-28) */
@@ -278,10 +227,7 @@
NO_NET_INSTR_EFFECT;
break;
case 037: /* fistp m64int */
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
if ( reg_store_int64() )
pop_0(); /* pop only if the number was actually stored
(see the 80486 manual p16-28) */
diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/poly_atan.c linux/kernel/FPU-emu/poly_atan.c
--- pl12/linux/kernel/FPU-emu/poly_atan.c Thu Jul 22 01:11:51 1993
+++ linux/kernel/FPU-emu/poly_atan.c Wed Sep 1 18:30:05 1993
@@ -38,12 +38,9 @@
{ 0xf1dd2dbf, 0x000a530a }
};
+static unsigned long long denomterm = 0xea2e6612fc4bd208LL;
-static unsigned denomterm[2] =
-{ 0xfc4bd208, 0xea2e6612 };
-
-
/*--- poly_atan() -----------------------------------------------------------+
| |
+---------------------------------------------------------------------------*/
@@ -53,7 +50,7 @@
short exponent;
FPU_REG odd_poly, even_poly, pos_poly, neg_poly, ratio;
FPU_REG argSq;
- long long arg_signif, argSqSq;
+ unsigned long long arg_signif, argSqSq;
#ifdef PARANOID
@@ -97,20 +94,20 @@
recursions++;
- arg_signif = *(long long *)&(arg->sigl);
+ arg_signif = significand(arg);
if ( exponent < -1 )
{
if ( shrx(&arg_signif, -1-exponent) >= 0x80000000U )
arg_signif++; /* round up */
}
- *(long long *)&(numerator.sigl) = -arg_signif;
+ significand(&numerator) = -arg_signif;
numerator.exp = EXP_BIAS - 1;
normalize(&numerator); /* 1 - arg */
- arg_signif = *(long long *)&(arg->sigl);
+ arg_signif = significand(arg);
if ( shrx(&arg_signif, -exponent) >= 0x80000000U )
arg_signif++; /* round up */
- *(long long *)&(denom.sigl) = arg_signif;
+ significand(&denom) = arg_signif;
denom.sigh |= 0x80000000; /* 1 + arg */
arg->exp = numerator.exp;
@@ -120,7 +117,7 @@
}
}
- *(long long *)&arg_signif = *(long long *)&(arg->sigl);
+ arg_signif = significand(arg);
#ifdef PARANOID
/* This must always be true */
@@ -136,8 +133,8 @@
/* Now have arg_signif with binary point at the left
.1xxxxxxxx */
- mul64(&arg_signif, &arg_signif, (long long *)(&argSq.sigl));
- mul64((long long *)(&argSq.sigl), (long long *)(&argSq.sigl), &argSqSq);
+ mul64(&arg_signif, &arg_signif, &significand(&argSq));
+ mul64(&significand(&argSq), &significand(&argSq), &argSqSq);
/* will be a valid positive nr with expon = 0 */
*(short *)&(pos_poly.sign) = 0;
@@ -146,8 +143,8 @@
/* Do the basic fixed point polynomial evaluation */
polynomial(&pos_poly.sigl, (unsigned *)&argSqSq,
(unsigned short (*)[4])oddplterms, HIPOWERop-1);
- mul64((long long *)(&argSq.sigl), (long long *)(&pos_poly.sigl),
- (long long *)(&pos_poly.sigl));
+ mul64(&significand(&argSq), &significand(&pos_poly),
+ &significand(&pos_poly));
/* will be a valid positive nr with expon = 0 */
*(short *)&(neg_poly.sign) = 0;
@@ -158,7 +155,7 @@
(unsigned short (*)[4])oddnegterms, HIPOWERon-1);
/* Subtract the mantissas */
- *((long long *)(&pos_poly.sigl)) -= *((long long *)(&neg_poly.sigl));
+ significand(&pos_poly) -= significand(&neg_poly);
reg_move(&pos_poly, &odd_poly);
poly_add_1(&odd_poly);
@@ -166,8 +163,7 @@
/* will be a valid positive nr with expon = 0 */
*(short *)&(even_poly.sign) = 0;
- mul64((long long *)(&argSq.sigl),
- (long long *)(&denomterm), (long long *)(&even_poly.sigl));
+ mul64(&significand(&argSq), &denomterm, &significand(&even_poly));
poly_add_1(&even_poly);
@@ -198,7 +194,7 @@
shrx(&src->sigl, 1);
#ifdef OBSOLETE
-if ( round ) (*(long long *)&src->sigl)++; /* Round to even */
+if ( round ) significand(src)++; /* Round to even */
#endif OBSOLETE
src->sigh |= 0x80000000;
diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/poly_div.S linux/kernel/FPU-emu/poly_div.S
--- pl12/linux/kernel/FPU-emu/poly_div.S Tue Nov 10 12:54:54 1992
+++ linux/kernel/FPU-emu/poly_div.S Wed Sep 1 18:30:05 1993
@@ -8,9 +8,9 @@
| Australia. E-mail apm233m@vaxc.cc.monash.edu.au |
| |
| Call from C as: |
- | void poly_div2(long long *x) |
- | void poly_div4(long long *x) |
- | void poly_div16(long long *x) |
+ | void poly_div2(unsigned long long *x) |
+ | void poly_div4(unsigned long long *x) |
+ | void poly_div16(unsigned long long *x) |
| |
+---------------------------------------------------------------------------*/
diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/poly_l2.c linux/kernel/FPU-emu/poly_l2.c
--- pl12/linux/kernel/FPU-emu/poly_l2.c Sun May 23 14:48:35 1993
+++ linux/kernel/FPU-emu/poly_l2.c Wed Sep 1 18:30:05 1993
@@ -45,7 +45,7 @@
short exponent;
char zero; /* flag for an Xx == 0 */
unsigned short bits, shift;
- long long Xsq;
+ unsigned long long Xsq;
FPU_REG accum, denom, num, Xx;
@@ -79,7 +79,7 @@
denom.sigl = num.sigl;
denom.sigh = num.sigh;
- poly_div4((long long *)&(denom.sigl));
+ poly_div4(&significand(&denom));
denom.sigh += 0x80000000; /* set the msb */
Xx.exp = EXP_BIAS; /* needed to prevent errors in div routine */
reg_u_div(&num, &denom, &Xx, FULL_PRECISION);
@@ -86,7 +86,7 @@
zero = !(Xx.sigh | Xx.sigl);
- mul64((long long *)&Xx.sigl, (long long *)&Xx.sigl, &Xsq);
+ mul64(&significand(&Xx), &significand(&Xx), &Xsq);
poly_div16(&Xsq);
accum.exp = -1; /* exponent of accum */
@@ -123,7 +123,7 @@
{
/* The argument is of the form 1-x */
/* Use 1-1/(1-x) = x/(1-x) */
- *((long long *)&num.sigl) = - *((long long *)&(arg->sigl));
+ significand(&num) = - significand(arg);
normalize(&num);
reg_div(&num, arg, &num, FULL_PRECISION);
}
@@ -149,16 +149,16 @@
return;
}
- mul64((long long *)&accum.sigl,
- (long long *)&Xx.sigl, (long long *)&accum.sigl);
+ mul64(&significand(&accum),
+ &significand(&Xx), &significand(&accum));
- *((long long *)(&accum.sigl)) += *((long long *)(&Xx.sigl));
+ significand(&accum) += significand(&Xx);
if ( Xx.sigh > accum.sigh )
{
/* There was an overflow */
- poly_div2((long long *)&accum.sigl);
+ poly_div2(&significand(&accum));
accum.sigh |= 0x80000000;
accum.exp++;
}
@@ -179,11 +179,11 @@
/* Shift to get exponent == 0 */
if ( accum.exp < 0 )
{
- poly_div2((long long *)&accum.sigl);
+ poly_div2(&significand(&accum));
accum.exp++;
}
/* Just negate, but throw away the sign */
- *((long long *)&(accum.sigl)) = - *((long long *)&(accum.sigl));
+ significand(&accum) = - significand(&accum);
if ( exponent < 0 )
exponent++;
else
@@ -198,11 +198,11 @@
if ( accum.exp )
{
accum.exp++;
- poly_div2((long long *)&accum.sigl);
+ poly_div2(&significand(&accum));
}
while ( shift )
{
- poly_div2((long long *)&accum.sigl);
+ poly_div2(&significand(&accum));
if ( shift & 1)
accum.sigh |= 0x80000000;
shift >>= 1;
@@ -227,7 +227,7 @@
int poly_l2p1(FPU_REG *arg, FPU_REG *result)
{
char sign = 0;
- long long Xsq;
+ unsigned long long Xsq;
FPU_REG arg_pl1, denom, accum, local_arg, poly_arg;
@@ -263,7 +263,7 @@
/* Get poly_arg bits aligned as required */
shrx((unsigned *)&(poly_arg.sigl), -(poly_arg.exp - EXP_BIAS + 3));
- mul64((long long *)&(poly_arg.sigl), (long long *)&(poly_arg.sigl), &Xsq);
+ mul64(&significand(&poly_arg), &significand(&poly_arg), &Xsq);
poly_div16(&Xsq);
/* Do the basic fixed point polynomial evaluation */
diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/poly_sin.c linux/kernel/FPU-emu/poly_sin.c
--- pl12/linux/kernel/FPU-emu/poly_sin.c Thu Jul 22 01:11:51 1993
+++ linux/kernel/FPU-emu/poly_sin.c Wed Sep 1 18:30:05 1993
@@ -82,13 +82,13 @@
{
/* shift the argument right by the required places */
if ( shrx(&(fixed_arg.sigl), -1-exponent) >= 0x80000000U )
- (*((long long *)(&(fixed_arg.sigl))))++; /* round up */
+ significand(&fixed_arg)++; /* round up */
}
- mul64((long long *)&(fixed_arg.sigl), (long long *)&(fixed_arg.sigl),
- (long long *)&(arg_sqrd.sigl));
- mul64((long long *)&(arg_sqrd.sigl), (long long *)&(arg_sqrd.sigl),
- (long long *)&(arg_to_4.sigl));
+ mul64(&significand(&fixed_arg), &significand(&fixed_arg),
+ &significand(&arg_sqrd));
+ mul64(&significand(&arg_sqrd), &significand(&arg_sqrd),
+ &significand(&arg_to_4));
/* will be a valid positive nr with expon = 0 */
*(short *)&(accum.sign) = 0;
@@ -103,11 +103,11 @@
/* Do the basic fixed point polynomial evaluation */
polynomial(&(negaccum.sigl), &(arg_to_4.sigl), negterms, HIPOWER-1);
- mul64((long long *)&(arg_sqrd.sigl), (long long *)&(negaccum.sigl),
- (long long *)&(negaccum.sigl));
+ mul64(&significand(&arg_sqrd), &significand(&negaccum),
+ &significand(&negaccum));
/* Subtract the mantissas */
- *((long long *)(&(accum.sigl))) -= *((long long *)(&(negaccum.sigl)));
+ significand(&accum) -= significand(&negaccum);
/* Convert to 64 bit signed-compatible */
accum.exp = EXP_BIAS - 1 + accum.exp;
diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/poly_tan.c linux/kernel/FPU-emu/poly_tan.c
--- pl12/linux/kernel/FPU-emu/poly_tan.c Thu Jul 22 01:11:51 1993
+++ linux/kernel/FPU-emu/poly_tan.c Wed Sep 1 18:30:05 1993
@@ -54,7 +54,7 @@
short exponent;
FPU_REG odd_poly, even_poly, pos_poly, neg_poly;
FPU_REG argSq;
- long long arg_signif, argSqSq;
+ unsigned long long arg_signif, argSqSq;
exponent = arg->exp - EXP_BIAS;
@@ -64,7 +64,7 @@
{ arith_invalid(y_reg); return; } /* Need a positive number */
#endif PARANOID
- *(long long *)&arg_signif = *(long long *)&(arg->sigl);
+ arg_signif = significand(arg);
if ( exponent < -1 )
{
/* shift the argument right by the required places */
@@ -72,8 +72,8 @@
arg_signif++; /* round up */
}
- mul64(&arg_signif, &arg_signif, (long long *)(&argSq.sigl));
- mul64((long long *)(&argSq.sigl), (long long *)(&argSq.sigl), &argSqSq);
+ mul64(&arg_signif, &arg_signif, &significand(&argSq));
+ mul64(&significand(&argSq), &significand(&argSq), &argSqSq);
/* will be a valid positive nr with expon = 0 */
*(short *)&(pos_poly.sign) = 0;
@@ -88,11 +88,11 @@
/* Do the basic fixed point polynomial evaluation */
polynomial(&neg_poly.sigl, (unsigned *)&argSqSq, oddnegterms, HIPOWERon-1);
- mul64((long long *)(&argSq.sigl), (long long *)(&neg_poly.sigl),
- (long long *)(&neg_poly.sigl));
+ mul64(&significand(&argSq), &significand(&neg_poly),
+ &significand(&neg_poly));
/* Subtract the mantissas */
- *((long long *)(&pos_poly.sigl)) -= *((long long *)(&neg_poly.sigl));
+ significand(&pos_poly) -= significand(&neg_poly);
/* Convert to 64 bit signed-compatible */
pos_poly.exp -= 1;
@@ -110,8 +110,8 @@
/* Do the basic fixed point polynomial evaluation */
polynomial(&pos_poly.sigl, (unsigned *)&argSqSq, evenplterms, HIPOWERep-1);
- mul64((long long *)(&argSq.sigl),
- (long long *)(&pos_poly.sigl), (long long *)(&pos_poly.sigl));
+ mul64(&significand(&argSq),
+ &significand(&pos_poly), &significand(&pos_poly));
/* will be a valid positive nr with expon = 0 */
*(short *)&(neg_poly.sign) = 0;
@@ -121,7 +121,7 @@
polynomial(&neg_poly.sigl, (unsigned *)&argSqSq, evennegterms, HIPOWERen-1);
/* Subtract the mantissas */
- *((long long *)(&neg_poly.sigl)) -= *((long long *)(&pos_poly.sigl));
+ significand(&neg_poly) -= significand(&pos_poly);
/* and multiply by argSq */
/* Convert argSq to a valid reg number */
diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/reg_constant.c linux/kernel/FPU-emu/reg_constant.c
--- pl12/linux/kernel/FPU-emu/reg_constant.c Thu Jul 22 01:11:52 1993
+++ linux/kernel/FPU-emu/reg_constant.c Wed Sep 1 18:30:05 1993
@@ -67,10 +67,7 @@
}
push();
reg_move(c, FPU_st0_ptr);
-#ifdef PECULIAR_486
- /* Default, this conveys no information, but an 80486 does it. */
clear_C1();
-#endif PECULIAR_486
}
diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/reg_ld_str.c linux/kernel/FPU-emu/reg_ld_str.c
--- pl12/linux/kernel/FPU-emu/reg_ld_str.c Thu Jul 22 01:11:52 1993
+++ linux/kernel/FPU-emu/reg_ld_str.c Wed Sep 1 18:30:05 1993
@@ -312,7 +312,7 @@
}
e = EXP_BIAS + 63;
- *((long long *)&FPU_loaded_data.sigl) = s;
+ significand(&FPU_loaded_data) = s;
FPU_loaded_data.exp = e;
FPU_loaded_data.tag = TW_Valid;
normalize_nuo(&FPU_loaded_data);
@@ -417,7 +417,7 @@
}
else
{
- *((long long *)&FPU_loaded_data.sigl) = l;
+ significand(&FPU_loaded_data) = l;
FPU_loaded_data.exp = EXP_BIAS + 63;
FPU_loaded_data.tag = TW_Valid;
normalize_nuo(&FPU_loaded_data);
@@ -1033,7 +1033,7 @@
reg_move(FPU_st0_ptr, &t);
precision_loss = round_to_int(&t);
- ll = *(unsigned long long *)(&t.sigl);
+ ll = significand(&t);
/* Check for overflow, by comparing with 999999999999999999 decimal. */
if ( (t.sigh > 0x0de0b6b3) ||
@@ -1042,14 +1042,16 @@
EXCEPTION(EX_Invalid);
/* This is a special case: see sec 16.2.5.1 of the 80486 book */
invalid_operand:
- if ( control_word & EX_Invalid )
+ if ( control_word & CW_Invalid )
{
/* Produce the QNaN "indefinite" */
RE_ENTRANT_CHECK_OFF
verify_area(VERIFY_WRITE,d,10);
- put_fs_byte(0xff,(unsigned char *) d+7); /* This byte undefined */
- put_fs_byte(0xff,(unsigned char *) d+8);
- put_fs_byte(0xff,(unsigned char *) d+9);
+ for ( i = 0; i < 7; i++)
+ put_fs_byte(0, (unsigned char *) d+i); /* These bytes "undefined" */
+ put_fs_byte(0xc0, (unsigned char *) d+7); /* This byte "undefined" */
+ put_fs_byte(0xff, (unsigned char *) d+8);
+ put_fs_byte(0xff, (unsigned char *) d+9);
RE_ENTRANT_CHECK_ON
return 1;
}
@@ -1058,8 +1060,8 @@
}
else if ( precision_loss )
{
- if ( set_precision_flag(precision_loss) )
- return 0;
+ /* Precision loss doesn't stop the data transfer */
+ set_precision_flag(precision_loss);
}
verify_area(VERIFY_WRITE,d,10);
@@ -1096,7 +1098,7 @@
if (r->tag == TW_Zero)
{
/* Make sure that zero is returned */
- *(long long *)&r->sigl = 0;
+ significand(r) = 0;
return 0; /* o.k. */
}
@@ -1118,7 +1120,7 @@
|| (half_or_more && (r->sigl & 1)) ) /* odd -> even */
{
if ( very_big ) return 1; /* overflow */
- (*(long long *)(&r->sigl)) ++;
+ significand(r) ++;
return PRECISION_LOST_UP;
}
break;
@@ -1126,7 +1128,7 @@
if (frac_part && r->sign)
{
if ( very_big ) return 1; /* overflow */
- (*(long long *)(&r->sigl)) ++;
+ significand(r) ++;
return PRECISION_LOST_UP;
}
break;
@@ -1134,7 +1136,7 @@
if (frac_part && !r->sign)
{
if ( very_big ) return 1; /* overflow */
- (*(long long *)(&r->sigl)) ++;
+ significand(r) ++;
return PRECISION_LOST_UP;
}
break;
diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/status_w.h linux/kernel/FPU-emu/status_w.h
--- pl12/linux/kernel/FPU-emu/status_w.h Thu Jul 22 01:11:53 1993
+++ linux/kernel/FPU-emu/status_w.h Wed Sep 1 18:30:06 1993
@@ -10,6 +10,7 @@
#ifndef _STATUS_H_
#define _STATUS_H_
+#include "fpu_emu.h" /* for definition of PECULIAR_486 */
#ifdef __ASSEMBLER__
#define Const__(x) $##x
@@ -51,8 +52,13 @@
partial_status &= ~(SW_C0|SW_C1|SW_C2|SW_C3); \
partial_status |= (cc) & (SW_C0|SW_C1|SW_C2|SW_C3); })
-/* Clear the SW_C1 bit, "other bits undefined" */
-#define clear_C1() { partial_status &= ~SW_C1; }
+#ifdef PECULIAR_486
+ /* Default, this conveys no information, but an 80486 does it. */
+ /* Clear the SW_C1 bit, "other bits undefined". */
+# define clear_C1() { partial_status &= ~SW_C1; }
+# else
+# define clear_C1()
+#endif PECULIAR_486
#endif __ASSEMBLER__
diff -u --recursive --new-file pl12/linux/kernel/FPU-emu/version.h linux/kernel/FPU-emu/version.h
--- pl12/linux/kernel/FPU-emu/version.h Thu Jul 22 01:11:53 1993
+++ linux/kernel/FPU-emu/version.h Wed Sep 1 18:30:06 1993
@@ -9,5 +9,5 @@
| |
+---------------------------------------------------------------------------*/
-#define FPU_VERSION "wm-FPU-emu version BETA 1.5"
+#define FPU_VERSION "wm-FPU-emu version BETA 1.6"
diff -u --recursive --new-file pl12/linux/kernel/blk_drv/blk.h linux/kernel/blk_drv/blk.h
--- pl12/linux/kernel/blk_drv/blk.h Sat Aug 14 23:47:22 1993
+++ linux/kernel/blk_drv/blk.h Sat Sep 4 03:21:32 1993
@@ -3,6 +3,7 @@
#include <linux/sched.h>
#include <linux/locks.h>
+#include <linux/genhd.h>
/*
* NR_REQUEST is the number of entries in the request-queue.
diff -u --recursive --new-file pl12/linux/kernel/blk_drv/genhd.c linux/kernel/blk_drv/genhd.c
--- pl12/linux/kernel/blk_drv/genhd.c Sat Jul 3 03:01:45 1993
+++ linux/kernel/blk_drv/genhd.c Sat Sep 4 03:22:38 1993
@@ -194,7 +194,7 @@
}
/* This may be used only once, enforced by 'static int callable' */
-extern "C" int sys_setup(void * BIOS)
+asmlinkage int sys_setup(void * BIOS)
{
static int callable = 1;
struct gendisk *p;
diff -u --recursive --new-file pl12/linux/kernel/blk_drv/hd.c linux/kernel/blk_drv/hd.c
--- pl12/linux/kernel/blk_drv/hd.c Wed Jul 28 00:19:32 1993
+++ linux/kernel/blk_drv/hd.c Wed Sep 1 17:04:43 1993
@@ -559,7 +559,7 @@
case BLKFLSBUF:
if(!suser()) return -EACCES;
if(!inode->i_rdev) return -EINVAL;
- sync_dev(inode->i_rdev);
+ fsync_dev(inode->i_rdev);
invalidate_buffers(inode->i_rdev);
return 0;
diff -u --recursive --new-file pl12/linux/kernel/blk_drv/ramdisk.c linux/kernel/blk_drv/ramdisk.c
--- pl12/linux/kernel/blk_drv/ramdisk.c Wed Aug 4 22:38:40 1993
+++ linux/kernel/blk_drv/ramdisk.c Sat Sep 4 01:48:21 1993
@@ -37,7 +37,8 @@
repeat:
INIT_REQUEST;
addr = rd_start + (CURRENT->sector << 9);
- len = CURRENT->nr_sectors << 9;
+ len = CURRENT->current_nr_sectors << 9;
+
if ((MINOR(CURRENT->dev) != MINOR_RAMDISK) ||
(addr+len > rd_start+rd_length)) {
end_request(0);
diff -u --recursive --new-file pl12/linux/kernel/blk_drv/scsi/aha1542.c linux/kernel/blk_drv/scsi/aha1542.c
--- pl12/linux/kernel/blk_drv/scsi/aha1542.c Wed Jul 28 00:19:32 1993
+++ linux/kernel/blk_drv/scsi/aha1542.c Sat Sep 4 01:48:21 1993
@@ -15,6 +15,7 @@
#include <linux/head.h>
#include <linux/types.h>
#include <linux/string.h>
+#include <linux/ioport.h>
#include <linux/sched.h>
#include <asm/dma.h>
@@ -663,8 +664,10 @@
indx = 0;
while(indx < sizeof(bases)/sizeof(bases[0])){
- i = aha1542_test_port(bases[indx]);
- if (i) break;
+ if(!check_region(bases[indx], 4)){
+ i = aha1542_test_port(bases[indx]);
+ if (i) break;
+ };
indx++;
}
if (indx == sizeof(bases)/sizeof(bases[0])) return 0;
@@ -755,6 +758,7 @@
aha1542_command(0, cmd, buffer, 512);
}
#endif
+ snarf_region(bases[indx], 4); /* Register the IO ports that we use */
aha1542_host = hostnum;
return 1;
}
diff -u --recursive --new-file pl12/linux/kernel/blk_drv/scsi/aha1740.c linux/kernel/blk_drv/scsi/aha1740.c
--- pl12/linux/kernel/blk_drv/scsi/aha1740.c Wed Jul 28 00:19:32 1993
+++ linux/kernel/blk_drv/scsi/aha1740.c Sat Sep 4 01:48:21 1993
@@ -21,6 +21,7 @@
#include <linux/head.h>
#include <linux/types.h>
#include <linux/string.h>
+#include <linux/ioport.h>
#include <linux/sched.h>
#include <asm/dma.h>
@@ -432,6 +433,12 @@
for ( slot=MINEISA; slot <= MAXEISA; slot++ )
{
base = SLOTBASE(slot);
+
+ /* The ioports for eisa boards are generally beyond that used in the
+ check,snarf_region code, but this may change at some point, so we
+ go through the motions. */
+
+ if(check_region(base, 0x5c)) continue; /* See if in use */
if ( aha1740_test_port()) break;
}
if ( slot > MAXEISA )
@@ -455,6 +462,7 @@
printk("Unable to allocate IRQ for adaptec controller.\n");
return 0;
}
+ snarf_region(base, 0x5c); /* Reserve the space that we need to use */
return 1;
}
diff -u --recursive --new-file pl12/linux/kernel/blk_drv/scsi/fdomain.c linux/kernel/blk_drv/scsi/fdomain.c
--- pl12/linux/kernel/blk_drv/scsi/fdomain.c Sat Aug 14 09:05:16 1993
+++ linux/kernel/blk_drv/scsi/fdomain.c Sat Sep 4 01:48:21 1993
@@ -138,6 +138,7 @@
#include <asm/system.h>
#include <linux/errno.h>
#include <linux/string.h>
+#include <linux/ioport.h>
#define VERSION "$Revision: 3.18 $"
@@ -528,6 +529,8 @@
for (i = 0; !flag && i < PORT_COUNT; i++) {
port_base = ports[i];
+ if(check_region(port_base, 0x10)) continue; /* skip if I/O port in
+ use */
#if DEBUG_DETECT
printk( " %x,", port_base );
#endif
@@ -607,6 +610,8 @@
scsi_hosts[this_host].this_id = 7;
}
+ snarf_region(port_base, 0x10); /* Register */
+
#if DO_DETECT
/* These routines are here because of the way the SCSI bus behaves after
diff -u --recursive --new-file pl12/linux/kernel/blk_drv/scsi/scsi.c linux/kernel/blk_drv/scsi/scsi.c
--- pl12/linux/kernel/blk_drv/scsi/scsi.c Sun Aug 15 10:55:23 1993
+++ linux/kernel/blk_drv/scsi/scsi.c Sat Sep 4 01:48:22 1993
@@ -68,6 +68,7 @@
#define WAS_TIMEDOUT 0x02
#define WAS_SENSE 0x04
#define IS_RESETTING 0x08
+#define ASKED_FOR_SENSE 0x10
extern int last_reset[];
@@ -661,7 +662,7 @@
static void scsi_request_sense (Scsi_Cmnd * SCpnt)
{
cli();
- SCpnt->flags |= WAS_SENSE;
+ SCpnt->flags |= WAS_SENSE | ASKED_FOR_SENSE;
update_timeout(SCpnt, SENSE_TIMEOUT);
sti();
@@ -805,9 +806,17 @@
static int check_sense (Scsi_Cmnd * SCpnt)
{
- /* If there is no sense information, request it. */
- if (((SCpnt->sense_buffer[0] & 0x70) >> 4) != 7)
- return SUGGEST_SENSE;
+ /* If there is no sense information, request it. If we have already
+ requested it, there is no point in asking again - the firmware must be
+ confused. */
+ if (((SCpnt->sense_buffer[0] & 0x70) >> 4) != 7) {
+ if(!SCpnt->flags & ASKED_FOR_SENSE)
+ return SUGGEST_SENSE;
+ else
+ return SUGGEST_RETRY;
+ }
+
+ SCpnt->flags &= ~ASKED_FOR_SENSE;
#ifdef DEBUG_INIT
printk("scsi%d : ", SCpnt->host);
diff -u --recursive --new-file pl12/linux/kernel/blk_drv/scsi/sd.c linux/kernel/blk_drv/scsi/sd.c
--- pl12/linux/kernel/blk_drv/scsi/sd.c Wed Aug 11 22:36:48 1993
+++ linux/kernel/blk_drv/scsi/sd.c Sat Sep 4 01:48:22 1993
@@ -324,6 +324,7 @@
INIT_SCSI_REQUEST;
+
/* We have to be careful here. allocate_device will get a free pointer, but
there is no guarantee that it is queueable. In normal usage, we want to
call this, because other types of devices may have the host all tied up,
@@ -668,6 +669,7 @@
int j = 0;
unsigned char cmd[10];
unsigned char *buffer;
+ char spintime;
int the_result, retries;
Scsi_Cmnd * SCpnt;
@@ -677,6 +679,58 @@
SCpnt = allocate_device(NULL, rscsi_disks[i].device->index, 1);
buffer = (unsigned char *) scsi_malloc(512);
+
+ spintime = 0;
+
+ /* Spin up drives, as required. Only do this at boot time */
+ if (current == task[0]){
+ do{
+ cmd[0] = TEST_UNIT_READY;
+ cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0;
+ memset ((void *) &cmd[2], 0, 8);
+ SCpnt->request.dev = 0xffff; /* Mark as really busy again */
+ SCpnt->sense_buffer[0] = 0;
+ SCpnt->sense_buffer[2] = 0;
+
+ scsi_do_cmd (SCpnt,
+ (void *) cmd, (void *) buffer,
+ 512, sd_init_done, SD_TIMEOUT,
+ MAX_RETRIES);
+
+ while(SCpnt->request.dev != 0xfffe);
+
+ the_result = SCpnt->result;
+
+ /* Look for non-removable devices that return NOT_READY. Issue command
+ to spin up drive for these cases. */
+ if(the_result && !rscsi_disks[i].device->removable &&
+ SCpnt->sense_buffer[2] == NOT_READY) {
+ int time1;
+ if(!spintime){
+ cmd[0] = START_STOP;
+ cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0;
+ memset ((void *) &cmd[2], 0, 8);
+ cmd[4] = 1; /* Start spin cycle */
+ SCpnt->request.dev = 0xffff; /* Mark as really busy again */
+ SCpnt->sense_buffer[0] = 0;
+ SCpnt->sense_buffer[2] = 0;
+
+ scsi_do_cmd (SCpnt,
+ (void *) cmd, (void *) buffer,
+ 512, sd_init_done, SD_TIMEOUT,
+ MAX_RETRIES);
+
+ while(SCpnt->request.dev != 0xfffe);
+
+ spintime = jiffies;
+ };
+
+ time1 = jiffies;
+ while(jiffies < time1 + 100); /* Wait 1 second for next try */
+ };
+ } while(the_result && spintime && spintime < jiffies+1500);
+ }; /* current == task[0] */
+
retries = 3;
do {
diff -u --recursive --new-file pl12/linux/kernel/blk_drv/scsi/sd_ioctl.c linux/kernel/blk_drv/scsi/sd_ioctl.c
--- pl12/linux/kernel/blk_drv/scsi/sd_ioctl.c Wed Jul 28 00:19:33 1993
+++ linux/kernel/blk_drv/scsi/sd_ioctl.c Wed Sep 1 17:04:43 1993
@@ -55,7 +55,7 @@
case BLKFLSBUF:
if(!suser()) return -EACCES;
if(!inode->i_rdev) return -EINVAL;
- sync_dev(inode->i_rdev);
+ fsync_dev(inode->i_rdev);
invalidate_buffers(inode->i_rdev);
return 0;
diff -u --recursive --new-file pl12/linux/kernel/blk_drv/scsi/seagate.c linux/kernel/blk_drv/scsi/seagate.c
--- pl12/linux/kernel/blk_drv/scsi/seagate.c Sat Aug 7 11:27:00 1993
+++ linux/kernel/blk_drv/scsi/seagate.c Sat Sep 4 01:48:22 1993
@@ -10,6 +10,8 @@
* Note : TMC-880 boards don't work because they have two bits in
* the status register flipped, I'll fix this "RSN"
*
+ * This card does all the I/O via memory mapped I/O, so there is no need
+ * to check or snarf a region of the I/O address space.
*/
/*
diff -u --recursive --new-file pl12/linux/kernel/blk_drv/scsi/st.c linux/kernel/blk_drv/scsi/st.c
--- pl12/linux/kernel/blk_drv/scsi/st.c Wed Aug 11 22:36:49 1993
+++ linux/kernel/blk_drv/scsi/st.c Sun Aug 29 23:07:52 1993
@@ -127,9 +127,11 @@
/* Convert the result to success code */
static int st_chk_result(Scsi_Cmnd * SCpnt)
{
+#ifdef DEBUG
int dev = SCpnt->request.dev;
+#endif
int result = SCpnt->result;
- char * sense = SCpnt->sense_buffer;
+ unsigned char * sense = SCpnt->sense_buffer;
if (!result)
return 0;
diff -u --recursive --new-file pl12/linux/kernel/blk_drv/scsi/ultrastor.c linux/kernel/blk_drv/scsi/ultrastor.c
--- pl12/linux/kernel/blk_drv/scsi/ultrastor.c Wed Jul 28 00:19:35 1993
+++ linux/kernel/blk_drv/scsi/ultrastor.c Sat Sep 4 01:48:22 1993
@@ -43,6 +43,7 @@
#include <linux/string.h>
#include <linux/sched.h>
#include <linux/kernel.h>
+#include <linux/ioport.h>
#include <asm/io.h>
#include <asm/system.h>
@@ -194,6 +195,12 @@
PORT_ADDRESS = 0;
for (i = 0; i < ARRAY_SIZE(ultrastor_ports_14f); i++) {
PORT_ADDRESS = ultrastor_ports_14f[i];
+ if(check_region(PORT_ADDRESS, 4)) continue;
+#else
+ if(check_region(PORT_ADDRESS, 4)) {
+ printk("Ultrastor I/O space already in use\n");
+ return FALSE;
+ };
#endif
#if (ULTRASTOR_DEBUG & UD_DETECT)
@@ -248,6 +255,7 @@
PORT_ADDRESS);
#endif
+ snarf_region(PORT_ADDRESS, 4); /* Register the I/O space that we use */
/* All above tests passed, must be the right thing. Get some useful
info. */
*(char *)&config_1 = inb(CONFIG(PORT_ADDRESS + 0));
diff -u --recursive --new-file pl12/linux/kernel/blk_drv/scsi/wd7000.c linux/kernel/blk_drv/scsi/wd7000.c
--- pl12/linux/kernel/blk_drv/scsi/wd7000.c Sat Jul 3 03:40:30 1993
+++ linux/kernel/blk_drv/scsi/wd7000.c Sat Sep 4 01:48:23 1993
@@ -20,6 +20,8 @@
#include <asm/system.h>
#include <asm/dma.h>
#include <asm/io.h>
+#include <linux/ioport.h>
+
#include "../blk.h"
#include "scsi.h"
#include "hosts.h"
@@ -526,6 +528,7 @@
int i,j;
char const *base_address = NULL;
+ if(check_region(IO_BASE, 4)) return 0; /* IO ports in use */
for(i=0;i<(sizeof(wd_bases)/sizeof(char *));i++){
for(j=0;j<NUM_SIGNATURES;j++){
if(!memcmp((void *)(wd_bases[i] + signatures[j].offset),
@@ -537,6 +540,7 @@
}
if (base_address == NULL) return 0;
+ snarf_region(IO_BASE, 4); /* Register our ports */
/* Store our host number */
wd7000_host = hostnum;
diff -u --recursive --new-file pl12/linux/kernel/blk_drv/xd.c linux/kernel/blk_drv/xd.c
--- pl12/linux/kernel/blk_drv/xd.c Wed Jul 28 00:19:35 1993
+++ linux/kernel/blk_drv/xd.c Wed Sep 1 17:04:43 1993
@@ -222,7 +222,7 @@
case BLKFLSBUF:
if(!suser()) return -EACCES;
if(!inode->i_rdev) return -EINVAL;
- sync_dev(inode->i_rdev);
+ fsync_dev(inode->i_rdev);
invalidate_buffers(inode->i_rdev);
return 0;
diff -u --recursive --new-file pl12/linux/kernel/chr_drv/keyboard.c linux/kernel/chr_drv/keyboard.c
--- pl12/linux/kernel/chr_drv/keyboard.c Sat Aug 14 18:52:34 1993
+++ linux/kernel/chr_drv/keyboard.c Wed Sep 1 09:04:14 1993
@@ -65,7 +65,11 @@
unsigned long kbd_dead_keys = 0;
unsigned long kbd_prev_dead_keys = 0;
+/* shift state counters.. */
static unsigned char k_down[NR_SHIFT] = {0, };
+/* keyboard key bitmap */
+static unsigned long key_down[8] = { 0, };
+
static int want_console = -1;
static int last_console = 0; /* last used VC */
static char rep = 0; /* flag telling character repeat */
@@ -149,6 +153,7 @@
kbd = kbd_table + fg_console;
if (vc_kbd_flag(kbd,VC_RAW)) {
memset(k_down, 0, sizeof(k_down));
+ memset(key_down, 0, sizeof(key_down));
put_queue(scancode);
goto end_kbd_intr;
} else
@@ -160,7 +165,6 @@
static inline void translate(unsigned char scancode)
{
char break_flag;
- static unsigned long key_down[8] = { 0, };
static unsigned char e0_keys[] = {
0x1c, /* keypad enter */
0x1d, /* right control */
@@ -584,6 +588,8 @@
value = KVAL(K_SHIFT);
clr_vc_kbd_flag(kbd, VC_CAPSLOCK);
}
+ if (value > 3)
+ return;
if (up_flag) {
if (k_down[value])
diff -u --recursive --new-file pl12/linux/kernel/chr_drv/mem.c linux/kernel/chr_drv/mem.c
--- pl12/linux/kernel/chr_drv/mem.c Mon Aug 9 18:02:32 1993
+++ linux/kernel/chr_drv/mem.c Sat Aug 21 10:19:32 1993
@@ -129,12 +129,28 @@
static int mmap_mem(struct inode * inode, struct file * file,
unsigned long addr, size_t len, int prot, unsigned long off)
{
+ struct vm_area_struct * mpnt;
+
if (off & 0xfff || off + len < off)
return -ENXIO;
-
if (remap_page_range(addr, off, len, prot))
return -EAGAIN;
-
+/* try to create a dummy vmm-structure so that the rest of the kernel knows we are here */
+ mpnt = (struct vm_area_struct * ) kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
+ if (!mpnt)
+ return 0;
+
+ mpnt->vm_task = current;
+ mpnt->vm_start = addr;
+ mpnt->vm_end = addr + len;
+ mpnt->vm_page_prot = prot;
+ mpnt->vm_share = NULL;
+ mpnt->vm_inode = inode;
+ inode->i_count++;
+ mpnt->vm_offset = off;
+ mpnt->vm_ops = NULL;
+ mpnt->vm_next = current->mmap;
+ current->mmap = mpnt;
return 0;
}
diff -u --recursive --new-file pl12/linux/kernel/chr_drv/serial.c linux/kernel/chr_drv/serial.c
--- pl12/linux/kernel/chr_drv/serial.c Fri Aug 13 21:20:52 1993
+++ linux/kernel/chr_drv/serial.c Wed Aug 18 01:13:23 1993
@@ -1321,12 +1321,10 @@
switch (cmd) {
case TCSBRK: /* SVID version: non-zero arg --> no break */
- wait_until_sent(tty);
if (!arg)
send_break(info, HZ/4); /* 1/4 second */
return 0;
case TCSBRKP: /* support for POSIX tcsendbreak() */
- wait_until_sent(tty);
send_break(info, arg ? arg*(HZ/10) : HZ/4);
return 0;
case TIOCGSOFTCAR:
diff -u --recursive --new-file pl12/linux/kernel/chr_drv/tty_ioctl.c linux/kernel/chr_drv/tty_ioctl.c
--- pl12/linux/kernel/chr_drv/tty_ioctl.c Thu Jul 29 12:15:25 1993
+++ linux/kernel/chr_drv/tty_ioctl.c Wed Aug 18 01:13:07 1993
@@ -605,7 +605,12 @@
tty->packet = 0;
return (0);
}
-
+ case TCSBRK: case TCSBRKP:
+ wait_until_sent(tty);
+ if (!tty->ioctl)
+ return 0;
+ tty->ioctl(tty, file, cmd, arg);
+ return 0;
default:
if (tty->ioctl) {
retval = (tty->ioctl)(tty, file, cmd, arg);
diff -u --recursive --new-file pl12/linux/kernel/chr_drv/vt.c linux/kernel/chr_drv/vt.c
--- pl12/linux/kernel/chr_drv/vt.c Sat Jul 31 20:32:36 1993
+++ linux/kernel/chr_drv/vt.c Sat Sep 4 03:17:54 1993
@@ -35,7 +35,7 @@
struct vt_cons vt_cons[NR_CONSOLES];
-extern "C" int sys_ioperm(unsigned long from, unsigned long num, int on);
+asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on);
extern void change_console(unsigned int new_console);
extern void complete_change_console(unsigned int new_console);
diff -u --recursive --new-file pl12/linux/kernel/exit.c linux/kernel/exit.c
--- pl12/linux/kernel/exit.c Mon Aug 2 18:16:26 1993
+++ linux/kernel/exit.c Sat Sep 4 03:04:34 1993
@@ -274,7 +274,7 @@
* POSIX specifies that kill(-1,sig) is unspecified, but what we have
* is probably wrong. Should make it like BSD or SYSV.
*/
-extern "C" int sys_kill(int pid,int sig)
+asmlinkage int sys_kill(int pid,int sig)
{
int err, retval = 0, count = 0;
@@ -376,7 +376,7 @@
current->mmap = NULL;
while (mpnt) {
mpnt1 = mpnt->vm_next;
- if (mpnt->vm_ops->close)
+ if (mpnt->vm_ops && mpnt->vm_ops->close)
mpnt->vm_ops->close(mpnt);
kfree(mpnt);
mpnt = mpnt1;
@@ -491,12 +491,12 @@
goto fake_volatile;
}
-extern "C" int sys_exit(int error_code)
+asmlinkage int sys_exit(int error_code)
{
do_exit((error_code&0xff)<<8);
}
-extern "C" int sys_wait4(pid_t pid,unsigned long * stat_addr, int options, struct rusage * ru)
+asmlinkage int sys_wait4(pid_t pid,unsigned long * stat_addr, int options, struct rusage * ru)
{
int flag, retval;
struct wait_queue wait = { current, NULL };
@@ -587,7 +587,7 @@
* sys_waitpid() remains for compatibility. waitpid() should be
* implemented by calling sys_wait4() from libc.a.
*/
-extern "C" int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options)
+asmlinkage int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options)
{
return sys_wait4(pid, stat_addr, options, NULL);
}
diff -u --recursive --new-file pl12/linux/kernel/fork.c linux/kernel/fork.c
--- pl12/linux/kernel/fork.c Mon Aug 9 17:41:24 1993
+++ linux/kernel/fork.c Sat Sep 4 03:01:14 1993
@@ -23,7 +23,7 @@
#include <asm/segment.h>
#include <asm/system.h>
-extern "C" void ret_from_sys_call(void) __asm__("ret_from_sys_call");
+asmlinkage void ret_from_sys_call(void) __asm__("ret_from_sys_call");
#define MAX_TASKS_PER_USER (NR_TASKS/2)
@@ -113,7 +113,7 @@
* information (task[nr]) and sets up the necessary registers. It
* also copies the data segment in it's entirety.
*/
-extern "C" int sys_fork(struct pt_regs regs)
+asmlinkage int sys_fork(struct pt_regs regs)
{
struct pt_regs * childregs;
struct task_struct *p;
@@ -176,7 +176,7 @@
p->exit_signal = clone_flags & CSIGNAL;
p->tss.ldt = _LDT(nr);
if (p->ldt) {
- if (p->ldt = (struct desc_struct*) __get_free_page(GFP_KERNEL))
+ if ((p->ldt = (struct desc_struct*) __get_free_page(GFP_KERNEL)) != NULL)
memcpy(p->ldt, current->ldt, PAGE_SIZE);
}
p->tss.bitmap = offsetof(struct tss_struct,io_bitmap);
diff -u --recursive --new-file pl12/linux/kernel/info.c linux/kernel/info.c
--- pl12/linux/kernel/info.c Sat Jul 3 01:02:33 1993
+++ linux/kernel/info.c Sat Sep 4 03:11:09 1993
@@ -14,7 +14,7 @@
#include <linux/types.h>
#include <linux/mm.h>
-extern "C" int sys_sysinfo(struct sysinfo *info)
+asmlinkage int sys_sysinfo(struct sysinfo *info)
{
int error;
struct sysinfo val;
diff -u --recursive --new-file pl12/linux/kernel/ioport.c linux/kernel/ioport.c
--- pl12/linux/kernel/ioport.c Wed Jul 14 19:07:28 1993
+++ linux/kernel/ioport.c Sat Sep 4 03:10:28 1993
@@ -9,7 +9,10 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/types.h>
+#include <linux/ioport.h>
+static unsigned long ioport_registrar[IO_BITMAP_SIZE] = {0, /* ... */};
+
#define _IODEBUG
#ifdef IODEBUG
@@ -40,14 +43,76 @@
}
#endif
+/* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
+asmlinkage void set_bitmap(unsigned long *bitmap,
+ short base, short extent, int new_value)
+{
+ int mask;
+ unsigned long *bitmap_base = bitmap + (base >> 5);
+ unsigned short low_index = base & 0x1f;
+ int length = low_index + extent;
+
+ if (low_index != 0) {
+ mask = (~0 << low_index);
+ if (length < 32)
+ mask &= ~(~0 << length);
+ if (new_value)
+ *bitmap_base++ |= mask;
+ else
+ *bitmap_base++ &= ~mask;
+ length -= 32;
+ }
+
+ mask = (new_value ? ~0 : 0);
+ while (length >= 32) {
+ *bitmap_base++ = mask;
+ length -= 32;
+ }
+
+ if (length > 0) {
+ mask = ~(~0 << length);
+ if (new_value)
+ *bitmap_base++ |= mask;
+ else
+ *bitmap_base++ &= ~mask;
+ }
+}
+
+/* Check for set bits in BITMAP starting at BASE, going to EXTENT. */
+asmlinkage int check_bitmap(unsigned long *bitmap, short base, short extent)
+{
+ int mask;
+ unsigned long *bitmap_base = bitmap + (base >> 5);
+ unsigned short low_index = base & 0x1f;
+ int length = low_index + extent;
+
+ if (low_index != 0) {
+ mask = (~0 << low_index);
+ if (length < 32)
+ mask &= ~(~0 << length);
+ if (*bitmap_base++ & mask)
+ return 1;
+ length -= 32;
+ }
+ while (length >= 32) {
+ if (*bitmap_base++ != 0)
+ return 1;
+ length -= 32;
+ }
+
+ if (length > 0) {
+ mask = ~(~0 << length);
+ if (*bitmap_base++ & mask)
+ return 1;
+ }
+ return 0;
+}
+
/*
* this changes the io permissions bitmap in the current task.
*/
-extern "C" int sys_ioperm(unsigned long from, unsigned long num, int turn_on)
+asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int turn_on)
{
- unsigned long froml, lindex, tnum, numl, rindex, mask;
- unsigned long *iop;
-
if (from + num <= from)
return -EINVAL;
if (from + num > IO_BITMAP_SIZE*32)
@@ -54,42 +119,11 @@
return -EINVAL;
if (!suser())
return -EPERM;
- froml = from >> 5;
- lindex = from & 0x1f;
- tnum = lindex + num;
- numl = (tnum + 0x1f) >> 5;
- rindex = tnum & 0x1f;
#ifdef IODEBUG
printk("io: from=%d num=%d %s\n", from, num, (turn_on ? "on" : "off"));
#endif
-
- if (numl) {
- iop = (unsigned long *)current->tss.io_bitmap + froml;
- if (lindex != 0) {
- mask = (~0 << lindex);
- if (--numl == 0 && rindex)
- mask &= ~(~0 << rindex);
- if (turn_on)
- *iop++ &= ~mask;
- else
- *iop++ |= mask;
- }
- if (numl) {
- if (rindex)
- --numl;
- mask = (turn_on ? 0 : ~0);
- while (numl--)
- *iop++ = mask;
- if (numl && rindex) {
- mask = ~(~0 << rindex);
- if (turn_on)
- *iop++ &= ~mask;
- else
- *iop++ |= mask;
- }
- }
- }
+ set_bitmap((unsigned long *)current->tss.io_bitmap, from, num, !turn_on);
return 0;
}
@@ -105,7 +139,7 @@
* on system-call entry - see also fork() and the signal handling
* code.
*/
-extern "C" int sys_iopl(long ebx,long ecx,long edx,
+asmlinkage int sys_iopl(long ebx,long ecx,long edx,
long esi, long edi, long ebp, long eax, long ds,
long es, long fs, long gs, long orig_eax,
long eip,long cs,long eflags,long esp,long ss)
@@ -118,4 +152,33 @@
return -EPERM;
*(&eflags) = (eflags & 0xffffcfff) | (level << 12);
return 0;
+}
+
+
+void snarf_region(unsigned int from, unsigned int num)
+{
+ if (from > IO_BITMAP_SIZE*32)
+ return;
+ if (from + num > IO_BITMAP_SIZE*32)
+ num = IO_BITMAP_SIZE*32 - from;
+ set_bitmap(ioport_registrar, from, num, 1);
+ return;
+}
+
+int check_region(unsigned int from, unsigned int num)
+{
+ if (from > IO_BITMAP_SIZE*32)
+ return 0;
+ if (from + num > IO_BITMAP_SIZE*32)
+ num = IO_BITMAP_SIZE*32 - from;
+ return check_bitmap(ioport_registrar, from, num);
+}
+
+/* Called from init/main.c to reserve IO ports. */
+void reserve_setup(char *str, int *ints)
+{
+ int i;
+
+ for (i = 1; i < ints[0]; i += 2)
+ snarf_region(ints[i], ints[i+1]);
}
diff -u --recursive --new-file pl12/linux/kernel/irq.c linux/kernel/irq.c
--- pl12/linux/kernel/irq.c Sun Jul 18 16:01:35 1993
+++ linux/kernel/irq.c Sat Sep 4 02:59:06 1993
@@ -47,7 +47,7 @@
* enabled. do_bottom_half() is atomic with respect to itself: a
* bottom_half handler need not be re-entrant.
*/
-extern "C" void do_bottom_half(void)
+asmlinkage void do_bottom_half(void)
{
unsigned long active;
unsigned long mask, left;
@@ -156,7 +156,7 @@
* IRQ's should use this format: notably the keyboard/timer
* routines.
*/
-extern "C" void do_IRQ(int irq, struct pt_regs * regs)
+asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
{
struct sigaction * sa = irq + irq_sigaction;
@@ -168,7 +168,7 @@
* stuff - the handler is also running with interrupts disabled unless
* it explicitly enables them later.
*/
-extern "C" void do_fast_IRQ(int irq)
+asmlinkage void do_fast_IRQ(int irq)
{
struct sigaction * sa = irq + irq_sigaction;
diff -u --recursive --new-file pl12/linux/kernel/itimer.c linux/kernel/itimer.c
--- pl12/linux/kernel/itimer.c Sat Jul 3 01:01:39 1993
+++ linux/kernel/itimer.c Sat Sep 4 03:10:51 1993
@@ -53,7 +53,7 @@
return(0);
}
-extern "C" int sys_getitimer(int which, struct itimerval *value)
+asmlinkage int sys_getitimer(int which, struct itimerval *value)
{
int error;
struct itimerval get_buffer;
@@ -98,7 +98,7 @@
return 0;
}
-extern "C" int sys_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
+asmlinkage int sys_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
{
int error;
struct itimerval set_buffer, get_buffer;
diff -u --recursive --new-file pl12/linux/kernel/ldt.c linux/kernel/ldt.c
--- pl12/linux/kernel/ldt.c Mon Aug 9 18:02:32 1993
+++ linux/kernel/ldt.c Sat Sep 4 03:11:30 1993
@@ -86,7 +86,7 @@
return 0;
}
-extern "C" int sys_modify_ldt(int func, void *ptr, unsigned long bytecount)
+asmlinkage int sys_modify_ldt(int func, void *ptr, unsigned long bytecount)
{
if (func == 0)
return read_ldt(ptr, bytecount);
diff -u --recursive --new-file pl12/linux/kernel/panic.c linux/kernel/panic.c
--- pl12/linux/kernel/panic.c Sat Jul 3 01:03:15 1993
+++ linux/kernel/panic.c Sat Sep 4 03:01:42 1993
@@ -11,7 +11,7 @@
#include <linux/kernel.h>
#include <linux/sched.h>
-extern "C" void sys_sync(void); /* it's really int */
+asmlinkage void sys_sync(void); /* it's really int */
volatile void panic(const char * s)
{
diff -u --recursive --new-file pl12/linux/kernel/printk.c linux/kernel/printk.c
--- pl12/linux/kernel/printk.c Mon Aug 9 18:02:32 1993
+++ linux/kernel/printk.c Sat Sep 4 03:04:18 1993
@@ -47,7 +47,7 @@
* 6 -- Disable printk's to console
* 7 -- Enable printk's to console
*/
-extern "C" int sys_syslog(int type, char * buf, int len)
+asmlinkage int sys_syslog(int type, char * buf, int len)
{
unsigned long i, j, count;
int do_clear = 0;
@@ -104,7 +104,7 @@
count = logged_chars;
j = log_start + log_size - count;
for (i = 0; i < count; i++) {
- c = *((char *) log_buf + (j++ & LOG_BUF_LEN-1));
+ c = *((char *) log_buf+(j++ & (LOG_BUF_LEN-1)));
put_fs_byte(c, buf++);
}
if (do_clear)
@@ -124,7 +124,7 @@
}
-extern "C" int printk(const char *fmt, ...)
+asmlinkage int printk(const char *fmt, ...)
{
va_list args;
int i,j;
@@ -133,7 +133,7 @@
i=vsprintf(buf,fmt,args);
va_end(args);
for (j = 0; j < i ; j++) {
- log_buf[(log_start+log_size) & LOG_BUF_LEN-1] = buf[j];
+ log_buf[(log_start+log_size) & (LOG_BUF_LEN-1)] = buf[j];
if (log_size < LOG_BUF_LEN)
log_size++;
else
diff -u --recursive --new-file pl12/linux/kernel/ptrace.c linux/kernel/ptrace.c
--- pl12/linux/kernel/ptrace.c Mon Aug 9 18:02:32 1993
+++ linux/kernel/ptrace.c Sat Sep 4 03:10:15 1993
@@ -152,7 +152,7 @@
if ((addr & ~PAGE_MASK) > PAGE_SIZE-sizeof(long)) {
low = get_long(tsk,addr & ~(sizeof(long)-1));
high = get_long(tsk,(addr+sizeof(long)) & ~(sizeof(long)-1));
- switch (addr & sizeof(long)-1) {
+ switch (addr & (sizeof(long)-1)) {
case 1:
low >>= 8;
low |= high << 24;
@@ -186,7 +186,7 @@
if ((addr & ~PAGE_MASK) > PAGE_SIZE-sizeof(long)) {
low = get_long(tsk,addr & ~(sizeof(long)-1));
high = get_long(tsk,(addr+sizeof(long)) & ~(sizeof(long)-1));
- switch (addr & sizeof(long)-1) {
+ switch (addr & (sizeof(long)-1)) {
case 0: /* shouldn't happen, but safety first */
low = data;
break;
@@ -216,7 +216,7 @@
return 0;
}
-extern "C" int sys_ptrace(long request, long pid, long addr, long data)
+asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
{
struct task_struct *child;
@@ -285,6 +285,10 @@
if (res)
return res;
tmp = get_stack_long(child, sizeof(long)*addr - MAGICNUMBER);
+ if (addr == DS || addr == ES ||
+ addr == FS || addr == GS ||
+ addr == CS || addr == SS)
+ tmp &= 0xffff;
put_fs_long(tmp,(unsigned long *) data);
return 0;
}
@@ -302,8 +306,11 @@
return -EIO;
if (addr == DS || addr == ES ||
addr == FS || addr == GS ||
- addr == CS || addr == SS)
- return -EIO;
+ addr == CS || addr == SS) {
+ data &= 0xffff;
+ if (data && (data & 3) != 3)
+ return -EIO;
+ }
if (addr == EFL) { /* flags. */
data &= FLAG_MASK;
data |= get_stack_long(child, EFL*sizeof(long)-MAGICNUMBER) & ~FLAG_MASK;
@@ -382,7 +389,7 @@
}
}
-extern "C" void syscall_trace(void)
+asmlinkage void syscall_trace(void)
{
if ((current->flags & (PF_PTRACED|PF_TRACESYS))
!= (PF_PTRACED|PF_TRACESYS))
diff -u --recursive --new-file pl12/linux/kernel/sched.c linux/kernel/sched.c
--- pl12/linux/kernel/sched.c Mon Aug 9 18:02:32 1993
+++ linux/kernel/sched.c Sat Sep 4 02:45:09 1993
@@ -51,7 +51,7 @@
extern void mem_use(void);
extern int timer_interrupt(void);
-extern "C" int system_call(void);
+asmlinkage int system_call(void);
static unsigned long init_kernel_stack[1024];
struct task_struct init_task = INIT_TASK;
@@ -82,7 +82,7 @@
* Careful.. There are problems with IBM-designed IRQ13 behaviour.
* Don't touch unless you *really* know how it works.
*/
-extern "C" void math_state_restore(void)
+asmlinkage void math_state_restore(void)
{
__asm__ __volatile__("clts");
if (last_task_used_math == current)
@@ -115,7 +115,7 @@
* The "confuse_gcc" goto is used only to get better assembly code..
* Djikstra probably hates me.
*/
-extern "C" void schedule(void)
+asmlinkage void schedule(void)
{
int c;
struct task_struct * p;
@@ -160,7 +160,7 @@
switch_to(next);
}
-extern "C" int sys_pause(void)
+asmlinkage int sys_pause(void)
{
current->state = TASK_INTERRUPTIBLE;
schedule();
@@ -421,7 +421,7 @@
sti();
}
-extern "C" int sys_alarm(long seconds)
+asmlinkage int sys_alarm(long seconds)
{
struct itimerval it_new, it_old;
@@ -432,37 +432,37 @@
return(it_old.it_value.tv_sec + (it_old.it_value.tv_usec / 1000000));
}
-extern "C" int sys_getpid(void)
+asmlinkage int sys_getpid(void)
{
return current->pid;
}
-extern "C" int sys_getppid(void)
+asmlinkage int sys_getppid(void)
{
return current->p_pptr->pid;
}
-extern "C" int sys_getuid(void)
+asmlinkage int sys_getuid(void)
{
return current->uid;
}
-extern "C" int sys_geteuid(void)
+asmlinkage int sys_geteuid(void)
{
return current->euid;
}
-extern "C" int sys_getgid(void)
+asmlinkage int sys_getgid(void)
{
return current->gid;
}
-extern "C" int sys_getegid(void)
+asmlinkage int sys_getegid(void)
{
return current->egid;
}
-extern "C" int sys_nice(long increment)
+asmlinkage int sys_nice(long increment)
{
int newprio;
diff -u --recursive --new-file pl12/linux/kernel/signal.c linux/kernel/signal.c
--- pl12/linux/kernel/signal.c Sun Aug 15 14:28:14 1993
+++ linux/kernel/signal.c Sat Sep 4 02:44:57 1993
@@ -20,14 +20,39 @@
extern int core_dump(long signr,struct pt_regs * regs);
-extern "C" int do_signal(unsigned long oldmask, struct pt_regs * regs);
+asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs);
-extern "C" int sys_sgetmask(void)
+struct sigcontext_struct {
+ unsigned short gs, __gsh;
+ unsigned short fs, __fsh;
+ unsigned short es, __esh;
+ unsigned short ds, __dsh;
+ unsigned long edi;
+ unsigned long esi;
+ unsigned long ebp;
+ unsigned long esp;
+ unsigned long ebx;
+ unsigned long edx;
+ unsigned long ecx;
+ unsigned long eax;
+ unsigned long trapno;
+ unsigned long err;
+ unsigned long eip;
+ unsigned short cs, __csh;
+ unsigned long eflags;
+ unsigned long esp_at_signal;
+ unsigned short ss, __ssh;
+ unsigned long i387;
+ unsigned long oldmask;
+ unsigned long cr2;
+};
+
+asmlinkage int sys_sgetmask(void)
{
return current->blocked;
}
-extern "C" int sys_ssetmask(int newmask)
+asmlinkage int sys_ssetmask(int newmask)
{
int old=current->blocked;
@@ -35,7 +60,7 @@
return old;
}
-extern "C" int sys_sigpending(sigset_t *set)
+asmlinkage int sys_sigpending(sigset_t *set)
{
int error;
/* fill in "set" with signals pending but blocked. */
@@ -48,7 +73,7 @@
/*
* atomically swap in the new signal mask, and wait for a signal.
*/
-extern "C" int sys_sigsuspend(int restart, unsigned long oldmask, unsigned long set)
+asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, unsigned long set)
{
unsigned long mask;
struct pt_regs * regs = (struct pt_regs *) &restart;
@@ -98,7 +123,7 @@
}
}
-extern "C" int sys_signal(int signum, unsigned long handler)
+asmlinkage int sys_signal(int signum, unsigned long handler)
{
struct sigaction tmp;
@@ -116,7 +141,7 @@
return handler;
}
-extern "C" int sys_sigaction(int signum, const struct sigaction * action,
+asmlinkage int sys_sigaction(int signum, const struct sigaction * action,
struct sigaction * oldaction)
{
struct sigaction new_sa, *p;
@@ -146,20 +171,37 @@
return 0;
}
-extern "C" int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options);
+asmlinkage int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options);
/*
* This sets regs->esp even though we don't actually use sigstacks yet..
*/
-extern "C" int sys_sigreturn(unsigned long oldmask, unsigned long eip, unsigned long esp)
+asmlinkage int sys_sigreturn(unsigned long __unused)
{
+#define CHECK_SEG(x) if (x) x |= 3
+#define COPY(x) regs->x = context.x
+ struct sigcontext_struct context;
struct pt_regs * regs;
- regs = (struct pt_regs *) &oldmask;
- current->blocked = oldmask & _BLOCKABLE;
- regs->eip = eip;
- regs->esp = esp;
- return 0;
+ regs = (struct pt_regs *) &__unused;
+ memcpy_fromfs(&context,(void *) regs->esp, sizeof(context));
+ current->blocked = context.oldmask & _BLOCKABLE;
+ CHECK_SEG(context.ss);
+ CHECK_SEG(context.cs);
+ CHECK_SEG(context.ds);
+ CHECK_SEG(context.es);
+ CHECK_SEG(context.fs);
+ CHECK_SEG(context.gs);
+ COPY(eip); COPY(eflags);
+ COPY(ecx); COPY(edx);
+ COPY(ebx);
+ COPY(esp); COPY(ebp);
+ COPY(edi); COPY(esi);
+ COPY(cs); COPY(ss);
+ COPY(ds); COPY(es);
+ COPY(fs); COPY(gs);
+ regs->orig_eax = -1; /* disable syscall checks */
+ return context.eax;
}
/*
@@ -166,15 +208,17 @@
* Set up a signal frame... Make the stack look the way iBCS2 expects
* it to look.
*/
-static void setup_frame(unsigned long ** fp, unsigned long eip,
- struct pt_regs * regs, int signr,
- unsigned long sa_handler, unsigned long oldmask)
+static void setup_frame(struct sigaction * sa, unsigned long ** fp, unsigned long eip,
+ struct pt_regs * regs, int signr, unsigned long oldmask)
{
unsigned long * frame;
#define __CODE ((unsigned long)(frame+24))
#define CODE(x) ((unsigned long *) ((x)+__CODE))
- frame = *fp - 32;
+ frame = *fp;
+ if (regs->ss != USER_DS)
+ frame = (unsigned long *) sa->sa_restorer;
+ frame -= 32;
verify_area(VERIFY_WRITE,frame,32*4);
/* set up the "normal" stack seen by the signal handler (iBCS2) */
put_fs_long(__CODE,frame);
@@ -186,32 +230,26 @@
put_fs_long(regs->edi, frame+6);
put_fs_long(regs->esi, frame+7);
put_fs_long(regs->ebp, frame+8);
- put_fs_long(regs->esp, frame+9);
+ put_fs_long((long)*fp, frame+9);
put_fs_long(regs->ebx, frame+10);
put_fs_long(regs->edx, frame+11);
put_fs_long(regs->ecx, frame+12);
put_fs_long(regs->eax, frame+13);
- put_fs_long(0, frame+14); /* trapno */
- put_fs_long(0, frame+15); /* err */
- put_fs_long(regs->eip, frame+16);
+ put_fs_long(0, frame+14); /* trapno - not implemented */
+ put_fs_long(0, frame+15); /* err - not implemented */
+ put_fs_long(eip, frame+16);
put_fs_long(regs->cs, frame+17);
put_fs_long(regs->eflags, frame+18);
put_fs_long(regs->esp, frame+19);
put_fs_long(regs->ss, frame+20);
- put_fs_long(0,frame+21); /* 387 state pointer */
-/* linux extended stack - easier to handle.. */
- put_fs_long(regs->eflags, frame+22);
- put_fs_long(eip, frame+23);
+ put_fs_long(0,frame+21); /* 387 state pointer - not implemented*/
+/* non-iBCS2 extensions.. */
+ put_fs_long(oldmask, frame+22);
+ put_fs_long(0, frame+23); /* cr2 - not implemented */
/* set up the return code... */
put_fs_long(0x0000b858, CODE(0)); /* popl %eax ; movl $,%eax */
- put_fs_long(0x00bb0000, CODE(4)); /* movl $,%ebx */
- put_fs_long(0xcd000000, CODE(8)); /* int $0x80 */
- put_fs_long(0x0fa90f80, CODE(12)); /* pop %gs ; pop %fs */
- put_fs_long(0x611f07a1, CODE(16)); /* pop %es ; pop %ds ; popad */
- put_fs_long(0x20c48390, CODE(20)); /* nop ; addl $32,%esp */
- put_fs_long(0x0020c29d, CODE(24)); /* popfl ; ret $32 */
- put_fs_long(__NR_ssetmask, CODE(2));
- put_fs_long(oldmask, CODE(7));
+ put_fs_long(0x80cd0000, CODE(4)); /* int $0x80 */
+ put_fs_long(__NR_sigreturn, CODE(2));
*fp = frame;
#undef __CODE
#undef CODE
@@ -226,7 +264,7 @@
* the kernel can handle, and then we build all the user-level signal handling
* stack-frames in one go after that.
*/
-extern "C" int do_signal(unsigned long oldmask, struct pt_regs * regs)
+asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs)
{
unsigned long mask = ~current->blocked;
unsigned long handler_signal = 0;
@@ -233,7 +271,6 @@
unsigned long *frame = NULL;
unsigned long eip = 0;
unsigned long signr;
- unsigned long sa_handler;
struct sigaction * sa;
while ((signr = current->signal & mask)) {
@@ -317,20 +354,20 @@
frame = (unsigned long *) regs->esp;
signr = 1;
sa = current->sigaction;
- if (regs->cs != USER_CS || regs->ss != USER_DS)
- printk("Warning: signal handler with nonstandard code/stack segment\n");
for (mask = 1 ; mask ; sa++,signr++,mask += mask) {
if (mask > handler_signal)
break;
if (!(mask & handler_signal))
continue;
- sa_handler = (unsigned long) sa->sa_handler;
+ setup_frame(sa,&frame,eip,regs,signr,oldmask);
+ eip = (unsigned long) sa->sa_handler;
if (sa->sa_flags & SA_ONESHOT)
sa->sa_handler = NULL;
/* force a supervisor-mode page-in of the signal handler to reduce races */
- __asm__("testb $0,%%fs:%0": :"m" (*(char *) sa_handler));
- setup_frame(&frame,eip,regs,signr,sa_handler,oldmask);
- eip = sa_handler;
+ __asm__("testb $0,%%fs:%0": :"m" (*(char *) eip));
+ regs->cs = USER_CS; regs->ss = USER_DS;
+ regs->ds = USER_DS; regs->es = USER_DS;
+ regs->gs = USER_DS; regs->fs = USER_DS;
current->blocked |= sa->sa_mask;
oldmask |= sa->sa_mask;
}
diff -u --recursive --new-file pl12/linux/kernel/sys.c linux/kernel/sys.c
--- pl12/linux/kernel/sys.c Mon Aug 9 18:02:32 1993
+++ linux/kernel/sys.c Sat Sep 4 02:44:45 1993
@@ -56,7 +56,7 @@
return 0;
}
-extern "C" int sys_setpriority(int which, int who, int niceval)
+asmlinkage int sys_setpriority(int which, int who, int niceval)
{
struct task_struct **p;
int error = ESRCH;
@@ -86,7 +86,7 @@
return -error;
}
-extern "C" int sys_getpriority(int which, int who)
+asmlinkage int sys_getpriority(int which, int who)
{
struct task_struct **p;
int max_prio = 0;
@@ -103,37 +103,37 @@
return(max_prio ? max_prio : -ESRCH);
}
-extern "C" int sys_profil(void)
+asmlinkage int sys_profil(void)
{
return -ENOSYS;
}
-extern "C" int sys_ftime(void)
+asmlinkage int sys_ftime(void)
{
return -ENOSYS;
}
-extern "C" int sys_break(void)
+asmlinkage int sys_break(void)
{
return -ENOSYS;
}
-extern "C" int sys_stty(void)
+asmlinkage int sys_stty(void)
{
return -ENOSYS;
}
-extern "C" int sys_gtty(void)
+asmlinkage int sys_gtty(void)
{
return -ENOSYS;
}
-extern "C" int sys_prof(void)
+asmlinkage int sys_prof(void)
{
return -ENOSYS;
}
-extern "C" unsigned long save_v86_state(struct vm86_regs * regs)
+asmlinkage unsigned long save_v86_state(struct vm86_regs * regs)
{
unsigned long stack;
@@ -169,7 +169,7 @@
}
}
-extern "C" int sys_vm86(struct vm86_struct * v86)
+asmlinkage int sys_vm86(struct vm86_struct * v86)
{
struct vm86_struct info;
struct pt_regs * pt_regs = (struct pt_regs *) &v86;
@@ -216,7 +216,7 @@
*
* reboot doesn't sync: do that yourself before calling this.
*/
-extern "C" int sys_reboot(int magic, int magic_too, int flag)
+asmlinkage int sys_reboot(int magic, int magic_too, int flag)
{
if (!suser())
return -EPERM;
@@ -258,7 +258,7 @@
* 100% compatible with BSD. A program which uses just setgid() will be
* 100% compatible with POSIX w/ Saved ID's.
*/
-extern "C" int sys_setregid(gid_t rgid, gid_t egid)
+asmlinkage int sys_setregid(gid_t rgid, gid_t egid)
{
int old_rgid = current->gid;
@@ -287,7 +287,7 @@
/*
* setgid() is implemeneted like SysV w/ SAVED_IDS
*/
-extern "C" int sys_setgid(gid_t gid)
+asmlinkage int sys_setgid(gid_t gid)
{
if (suser())
current->gid = current->egid = current->sgid = gid;
@@ -298,37 +298,37 @@
return 0;
}
-extern "C" int sys_acct(void)
+asmlinkage int sys_acct(void)
{
return -ENOSYS;
}
-extern "C" int sys_phys(void)
+asmlinkage int sys_phys(void)
{
return -ENOSYS;
}
-extern "C" int sys_lock(void)
+asmlinkage int sys_lock(void)
{
return -ENOSYS;
}
-extern "C" int sys_mpx(void)
+asmlinkage int sys_mpx(void)
{
return -ENOSYS;
}
-extern "C" int sys_ulimit(void)
+asmlinkage int sys_ulimit(void)
{
return -ENOSYS;
}
-extern "C" int sys_old_syscall(void)
+asmlinkage int sys_old_syscall(void)
{
return -ENOSYS;
}
-extern "C" int sys_time(long * tloc)
+asmlinkage int sys_time(long * tloc)
{
int i, error;
@@ -355,7 +355,7 @@
* 100% compatible with BSD. A program which uses just setuid() will be
* 100% compatible with POSIX w/ Saved ID's.
*/
-extern "C" int sys_setreuid(uid_t ruid, uid_t euid)
+asmlinkage int sys_setreuid(uid_t ruid, uid_t euid)
{
int old_ruid = current->uid;
@@ -392,7 +392,7 @@
* will allow a root program to temporarily drop privileges and be able to
* regain them by swapping the real and effective uid.
*/
-extern "C" int sys_setuid(uid_t uid)
+asmlinkage int sys_setuid(uid_t uid)
{
if (suser())
current->uid = current->euid = current->suid = uid;
@@ -403,7 +403,7 @@
return(0);
}
-extern "C" int sys_stime(long * tptr)
+asmlinkage int sys_stime(long * tptr)
{
if (!suser())
return -EPERM;
@@ -412,7 +412,7 @@
return 0;
}
-extern "C" int sys_times(struct tms * tbuf)
+asmlinkage int sys_times(struct tms * tbuf)
{
if (tbuf) {
int error = verify_area(VERIFY_WRITE,tbuf,sizeof *tbuf);
@@ -426,7 +426,7 @@
return jiffies;
}
-extern "C" int sys_brk(unsigned long brk)
+asmlinkage int sys_brk(unsigned long brk)
{
int freepages;
unsigned long rlim;
@@ -487,7 +487,7 @@
* only important on a multi-user system anyway, to make sure one user
* can't send a signal to a process owned by another. -TYT, 12/12/91
*/
-extern "C" int sys_setpgid(pid_t pid, pid_t pgid)
+asmlinkage int sys_setpgid(pid_t pid, pid_t pgid)
{
int i;
@@ -513,12 +513,12 @@
return -ESRCH;
}
-extern "C" int sys_getpgrp(void)
+asmlinkage int sys_getpgrp(void)
{
return current->pgrp;
}
-extern "C" int sys_setsid(void)
+asmlinkage int sys_setsid(void)
{
if (current->leader && !suser())
return -EPERM;
@@ -531,7 +531,7 @@
/*
* Supplementary group ID's
*/
-extern "C" int sys_getgroups(int gidsetsize, gid_t *grouplist)
+asmlinkage int sys_getgroups(int gidsetsize, gid_t *grouplist)
{
int i;
@@ -551,7 +551,7 @@
return(i);
}
-extern "C" int sys_setgroups(int gidsetsize, gid_t *grouplist)
+asmlinkage int sys_setgroups(int gidsetsize, gid_t *grouplist)
{
int i;
@@ -583,7 +583,7 @@
return 0;
}
-extern "C" int sys_newuname(struct new_utsname * name)
+asmlinkage int sys_newuname(struct new_utsname * name)
{
int error;
@@ -595,7 +595,7 @@
return error;
}
-extern "C" int sys_uname(struct old_utsname * name)
+asmlinkage int sys_uname(struct old_utsname * name)
{
int error;
if (!name)
@@ -616,7 +616,7 @@
return 0;
}
-extern "C" int sys_olduname(struct oldold_utsname * name)
+asmlinkage int sys_olduname(struct oldold_utsname * name)
{
int error;
if (!name)
@@ -640,7 +640,7 @@
/*
* Only sethostname; gethostname can be implemented by calling uname()
*/
-extern "C" int sys_sethostname(char *name, int len)
+asmlinkage int sys_sethostname(char *name, int len)
{
int i;
@@ -660,7 +660,7 @@
* Only setdomainname; getdomainname can be implemented by calling
* uname()
*/
-extern "C" int sys_setdomainname(char *name, int len)
+asmlinkage int sys_setdomainname(char *name, int len)
{
int i;
@@ -676,7 +676,7 @@
return 0;
}
-extern "C" int sys_getrlimit(unsigned int resource, struct rlimit *rlim)
+asmlinkage int sys_getrlimit(unsigned int resource, struct rlimit *rlim)
{
int error;
@@ -692,7 +692,7 @@
return 0;
}
-extern "C" int sys_setrlimit(unsigned int resource, struct rlimit *rlim)
+asmlinkage int sys_setrlimit(unsigned int resource, struct rlimit *rlim)
{
struct rlimit new_rlim, *old_rlim;
@@ -761,7 +761,7 @@
return 0;
}
-extern "C" int sys_getrusage(int who, struct rusage *ru)
+asmlinkage int sys_getrusage(int who, struct rusage *ru)
{
if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN)
return -EINVAL;
@@ -808,7 +808,7 @@
#endif /* not __i386__ */
}
-extern "C" int sys_gettimeofday(struct timeval *tv, struct timezone *tz)
+asmlinkage int sys_gettimeofday(struct timeval *tv, struct timezone *tz)
{
int error;
@@ -840,7 +840,7 @@
* soon as possible, so that the clock can be set right. Otherwise,
* various programs will get confused when the clock gets warped.
*/
-extern "C" int sys_settimeofday(struct timeval *tv, struct timezone *tz)
+asmlinkage int sys_settimeofday(struct timeval *tv, struct timezone *tz)
{
static int firsttime = 1;
@@ -888,7 +888,7 @@
startup_time += sys_tz.tz_minuteswest*60;
}
-extern "C" int sys_umask(int mask)
+asmlinkage int sys_umask(int mask)
{
int old = current->umask;
diff -u --recursive --new-file pl12/linux/kernel/traps.c linux/kernel/traps.c
--- pl12/linux/kernel/traps.c Wed Jul 14 16:57:11 1993
+++ linux/kernel/traps.c Sat Sep 4 02:44:31 1993
@@ -41,31 +41,32 @@
void page_exception(void);
-extern "C" void divide_error(void);
-extern "C" void debug(void);
-extern "C" void nmi(void);
-extern "C" void int3(void);
-extern "C" void overflow(void);
-extern "C" void bounds(void);
-extern "C" void invalid_op(void);
-extern "C" void device_not_available(void);
-extern "C" void double_fault(void);
-extern "C" void coprocessor_segment_overrun(void);
-extern "C" void invalid_TSS(void);
-extern "C" void segment_not_present(void);
-extern "C" void stack_segment(void);
-extern "C" void general_protection(void);
-extern "C" void page_fault(void);
-extern "C" void coprocessor_error(void);
-extern "C" void reserved(void);
-extern "C" void alignment_check(void);
+asmlinkage void divide_error(void);
+asmlinkage void debug(void);
+asmlinkage void nmi(void);
+asmlinkage void int3(void);
+asmlinkage void overflow(void);
+asmlinkage void bounds(void);
+asmlinkage void invalid_op(void);
+asmlinkage void device_not_available(void);
+asmlinkage void double_fault(void);
+asmlinkage void coprocessor_segment_overrun(void);
+asmlinkage void invalid_TSS(void);
+asmlinkage void segment_not_present(void);
+asmlinkage void stack_segment(void);
+asmlinkage void general_protection(void);
+asmlinkage void page_fault(void);
+asmlinkage void coprocessor_error(void);
+asmlinkage void reserved(void);
+asmlinkage void alignment_check(void);
/*static*/ void die_if_kernel(char * str, struct pt_regs * regs, long err)
{
int i;
- if ((regs->eflags & VM_MASK) || ((0xffff & regs->cs) == USER_CS))
+ if ((regs->eflags & VM_MASK) || (3 & regs->cs) == 3)
return;
+
printk("%s: %04x\n", str, err & 0xffff);
printk("EIP: %04x:%p\nEFLAGS: %p\n", 0xffff & regs->cs,regs->eip,regs->eflags);
printk("eax: %08x ebx: %08x ecx: %08x edx: %08x\n",
@@ -82,31 +83,31 @@
do_exit(SIGSEGV);
}
-extern "C" void do_double_fault(struct pt_regs * regs, long error_code)
+asmlinkage void do_double_fault(struct pt_regs * regs, long error_code)
{
send_sig(SIGSEGV, current, 1);
die_if_kernel("double fault",regs,error_code);
}
-extern "C" void do_general_protection(struct pt_regs * regs, long error_code)
+asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
{
send_sig(SIGSEGV, current, 1);
die_if_kernel("general protection",regs,error_code);
}
-extern "C" void do_alignment_check(struct pt_regs * regs, long error_code)
+asmlinkage void do_alignment_check(struct pt_regs * regs, long error_code)
{
send_sig(SIGSEGV, current, 1);
die_if_kernel("alignment check",regs,error_code);
}
-extern "C" void do_divide_error(struct pt_regs * regs, long error_code)
+asmlinkage void do_divide_error(struct pt_regs * regs, long error_code)
{
send_sig(SIGFPE, current, 1);
die_if_kernel("divide error",regs,error_code);
}
-extern "C" void do_int3(struct pt_regs * regs, long error_code)
+asmlinkage void do_int3(struct pt_regs * regs, long error_code)
{
if (current->flags & PF_PTRACED)
current->blocked &= ~(1 << (SIGTRAP-1));
@@ -114,12 +115,12 @@
die_if_kernel("int3",regs,error_code);
}
-extern "C" void do_nmi(struct pt_regs * regs, long error_code)
+asmlinkage void do_nmi(struct pt_regs * regs, long error_code)
{
printk("Uhhuh. NMI received. Dazed and confused, but trying to continue\n");
}
-extern "C" void do_debug(struct pt_regs * regs, long error_code)
+asmlinkage void do_debug(struct pt_regs * regs, long error_code)
{
if (current->flags & PF_PTRACED)
current->blocked &= ~(1 << (SIGTRAP-1));
@@ -127,49 +128,49 @@
die_if_kernel("debug",regs,error_code);
}
-extern "C" void do_overflow(struct pt_regs * regs, long error_code)
+asmlinkage void do_overflow(struct pt_regs * regs, long error_code)
{
send_sig(SIGSEGV, current, 1);
die_if_kernel("overflow",regs,error_code);
}
-extern "C" void do_bounds(struct pt_regs * regs, long error_code)
+asmlinkage void do_bounds(struct pt_regs * regs, long error_code)
{
send_sig(SIGSEGV, current, 1);
die_if_kernel("bounds",regs,error_code);
}
-extern "C" void do_invalid_op(struct pt_regs * regs, long error_code)
+asmlinkage void do_invalid_op(struct pt_regs * regs, long error_code)
{
send_sig(SIGILL, current, 1);
die_if_kernel("invalid operand",regs,error_code);
}
-extern "C" void do_device_not_available(struct pt_regs * regs, long error_code)
+asmlinkage void do_device_not_available(struct pt_regs * regs, long error_code)
{
send_sig(SIGSEGV, current, 1);
die_if_kernel("device not available",regs,error_code);
}
-extern "C" void do_coprocessor_segment_overrun(struct pt_regs * regs, long error_code)
+asmlinkage void do_coprocessor_segment_overrun(struct pt_regs * regs, long error_code)
{
send_sig(SIGFPE, last_task_used_math, 1);
die_if_kernel("coprocessor segment overrun",regs,error_code);
}
-extern "C" void do_invalid_TSS(struct pt_regs * regs,long error_code)
+asmlinkage void do_invalid_TSS(struct pt_regs * regs,long error_code)
{
send_sig(SIGSEGV, current, 1);
die_if_kernel("invalid TSS",regs,error_code);
}
-extern "C" void do_segment_not_present(struct pt_regs * regs,long error_code)
+asmlinkage void do_segment_not_present(struct pt_regs * regs,long error_code)
{
send_sig(SIGSEGV, current, 1);
die_if_kernel("segment not present",regs,error_code);
}
-extern "C" void do_stack_segment(struct pt_regs * regs,long error_code)
+asmlinkage void do_stack_segment(struct pt_regs * regs,long error_code)
{
send_sig(SIGSEGV, current, 1);
die_if_kernel("stack segment",regs,error_code);
@@ -210,13 +211,13 @@
env->twd = 0xffffffff;
}
-extern "C" void do_coprocessor_error(struct pt_regs * regs, long error_code)
+asmlinkage void do_coprocessor_error(struct pt_regs * regs, long error_code)
{
ignore_irq13 = 1;
math_error();
}
-extern "C" void do_reserved(struct pt_regs * regs, long error_code)
+asmlinkage void do_reserved(struct pt_regs * regs, long error_code)
{
send_sig(SIGSEGV, current, 1);
die_if_kernel("reserved (15,17-47) error",regs,error_code);
diff -u --recursive --new-file pl12/linux/mm/memory.c linux/mm/memory.c
--- pl12/linux/mm/memory.c Sun Aug 15 11:09:18 1993
+++ linux/mm/memory.c Sat Sep 4 03:34:22 1993
@@ -278,7 +278,7 @@
}
size = (size + ~PAGE_MASK) >> PAGE_SHIFT;
dir = PAGE_DIR_OFFSET(current->tss.cr3,from);
- poff = (from >> PAGE_SHIFT) & PTRS_PER_PAGE-1;
+ poff = (from >> PAGE_SHIFT) & (PTRS_PER_PAGE-1);
if ((pcnt = PTRS_PER_PAGE - poff) > size)
pcnt = size;
@@ -337,7 +337,7 @@
}
dir = PAGE_DIR_OFFSET(current->tss.cr3,from);
size = (size + ~PAGE_MASK) >> PAGE_SHIFT;
- poff = (from >> PAGE_SHIFT) & PTRS_PER_PAGE-1;
+ poff = (from >> PAGE_SHIFT) & (PTRS_PER_PAGE-1);
if ((pcnt = PTRS_PER_PAGE - poff) > size)
pcnt = size;
@@ -399,7 +399,7 @@
}
dir = PAGE_DIR_OFFSET(current->tss.cr3,from);
size = (size + ~PAGE_MASK) >> PAGE_SHIFT;
- poff = (from >> PAGE_SHIFT) & PTRS_PER_PAGE-1;
+ poff = (from >> PAGE_SHIFT) & (PTRS_PER_PAGE-1);
if ((pcnt = PTRS_PER_PAGE - poff) > size)
pcnt = size;
@@ -484,7 +484,7 @@
*page_table = BAD_PAGETABLE | PAGE_TABLE;
return 0;
}
- page_table += (address >> PAGE_SHIFT) & PTRS_PER_PAGE-1;
+ page_table += (address >> PAGE_SHIFT) & (PTRS_PER_PAGE-1);
if (*page_table) {
printk("put_page: page already exists\n");
*page_table = 0;
@@ -523,7 +523,7 @@
page_table = (unsigned long *) tmp;
}
}
- page_table += (address >> PAGE_SHIFT) & PTRS_PER_PAGE-1;
+ page_table += (address >> PAGE_SHIFT) & (PTRS_PER_PAGE-1);
if (*page_table) {
printk("put_dirty_page: page already exists\n");
*page_table = 0;
@@ -760,7 +760,7 @@
{
struct task_struct ** p;
- if (!inode || inode->i_count < 2)
+ if (!inode || inode->i_count < 2 || !area->vm_ops)
return 0;
for (p = &LAST_TASK ; p > &FIRST_TASK ; --p) {
if (!*p)
@@ -773,8 +773,8 @@
we can share pages with */
if(area){
struct vm_area_struct * mpnt;
- for(mpnt = (*p)->mmap; mpnt; mpnt = mpnt->vm_next){
- if(mpnt->vm_ops && mpnt->vm_ops == area->vm_ops &&
+ for (mpnt = (*p)->mmap; mpnt; mpnt = mpnt->vm_next) {
+ if (mpnt->vm_ops == area->vm_ops &&
mpnt->vm_inode->i_ino == area->vm_inode->i_ino&&
mpnt->vm_inode->i_dev == area->vm_inode->i_dev){
if (mpnt->vm_ops->share(mpnt, area, address))
@@ -851,6 +851,8 @@
continue;
if (address >= ((mpnt->vm_end + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))
continue;
+ if (!mpnt->vm_ops || !mpnt->vm_ops->nopage)
+ break;
mpnt->vm_ops->nopage(error_code, mpnt, address);
return;
}
@@ -858,7 +860,7 @@
get_empty_page(tsk,address);
if (tsk != current)
return;
- if (address < tsk->brk)
+ if (address >= tsk->end_data && address < tsk->brk)
return;
if (address+8192 >= (user_esp & 0xfffff000) &&
address <= current->start_stack)
@@ -872,7 +874,7 @@
* and the problem, and then passes it off to one of the appropriate
* routines.
*/
-extern "C" void do_page_fault(struct pt_regs *regs, unsigned long error_code)
+asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
{
unsigned long address;
unsigned long user_esp = 0;
@@ -966,9 +968,9 @@
int shared = 0;
printk("Mem-info:\n");
- printk("Free pages: %6dkB\n",nr_free_pages<<PAGE_SHIFT-10);
- printk("Secondary pages: %6dkB\n",nr_secondary_pages<<PAGE_SHIFT-10);
- printk("Free swap: %6dkB\n",nr_swap_pages<<PAGE_SHIFT-10);
+ printk("Free pages: %6dkB\n",nr_free_pages<<(PAGE_SHIFT-10));
+ printk("Secondary pages: %6dkB\n",nr_secondary_pages<<(PAGE_SHIFT-10));
+ printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
printk("Buffer memory: %6dkB\n",buffermem>>10);
printk("Buffer heads: %6d\n",nr_buffer_heads);
printk("Buffer blocks: %6d\n",nr_buffers);
@@ -1085,9 +1087,9 @@
printk("Memory: %dk/%dk available (%dk kernel code, %dk reserved, %dk data)\n",
tmp >> 10,
end_mem >> 10,
- codepages << PAGE_SHIFT-10,
- reservedpages << PAGE_SHIFT-10,
- datapages << PAGE_SHIFT-10);
+ codepages << (PAGE_SHIFT-10),
+ reservedpages << (PAGE_SHIFT-10),
+ datapages << (PAGE_SHIFT-10));
return;
}
diff -u --recursive --new-file pl12/linux/mm/mmap.c linux/mm/mmap.c
--- pl12/linux/mm/mmap.c Mon Aug 9 18:02:33 1993
+++ linux/mm/mmap.c Sat Sep 4 02:45:22 1993
@@ -52,11 +52,11 @@
switch (flags & MAP_TYPE) {
case MAP_SHARED:
if ((prot & PROT_WRITE) && !(file->f_mode & 2))
- return -EINVAL;
+ return -EACCES;
/* fall through */
case MAP_PRIVATE:
if (!(file->f_mode & 1))
- return -EINVAL;
+ return -EACCES;
break;
default:
@@ -121,7 +121,7 @@
return -1;
}
-extern "C" int sys_mmap(unsigned long *buffer)
+asmlinkage int sys_mmap(unsigned long *buffer)
{
unsigned long fd;
struct file * file;
@@ -133,7 +133,7 @@
get_fs_long(buffer+2), get_fs_long(buffer+3), get_fs_long(buffer+5));
}
-extern "C" int sys_munmap(unsigned long addr, size_t len)
+asmlinkage int sys_munmap(unsigned long addr, size_t len)
{
struct vm_area_struct *mpnt, **p, *free;
@@ -169,7 +169,7 @@
while (free) {
mpnt = free;
free = free->vm_next;
- if (mpnt->vm_ops->close)
+ if (mpnt->vm_ops && mpnt->vm_ops->close)
mpnt->vm_ops->close(mpnt);
kfree(mpnt);
}
@@ -197,11 +197,9 @@
extern struct vm_operations_struct file_mmap;
struct buffer_head * bh;
- if (off & (inode->i_sb->s_blocksize - 1))
+ if (prot & PAGE_RW) /* only PAGE_COW or read-only supported right now */
return -EINVAL;
- if (len > high_memory || off > high_memory - len) /* avoid overflow */
- return -ENXIO;
- if (get_limit(USER_DS) != TASK_SIZE)
+ if (off & (inode->i_sb->s_blocksize - 1))
return -EINVAL;
if (!inode->i_sb || !S_ISREG(inode->i_mode))
return -EACCES;
@@ -231,10 +229,6 @@
mpnt->vm_ops = &file_mmap;
mpnt->vm_next = current->mmap;
current->mmap = mpnt;
-#if 0
- printk("VFS: Loaded mmap at %08x - %08x\n",
- mpnt->vm_start, mpnt->vm_end);
-#endif
return 0;
}
diff -u --recursive --new-file pl12/linux/mm/swap.c linux/mm/swap.c
--- pl12/linux/mm/swap.c Sat Aug 14 15:59:34 1993
+++ linux/mm/swap.c Sat Sep 4 02:45:34 1993
@@ -265,7 +265,7 @@
* swapping out or forgetting about. This speeds up the search when we
* actually have to swap.
*/
-extern "C" int sys_idle(void)
+asmlinkage int sys_idle(void)
{
need_resched = 1;
return 0;
@@ -661,7 +661,7 @@
return 0;
}
-extern "C" int sys_swapoff(const char * specialfile)
+asmlinkage int sys_swapoff(const char * specialfile)
{
struct swap_info_struct * p;
struct inode * inode;
@@ -713,7 +713,7 @@
*
* The swapon system call
*/
-extern "C" int sys_swapon(const char * specialfile)
+asmlinkage int sys_swapon(const char * specialfile)
{
struct swap_info_struct * p;
struct inode * swap_inode;
diff -u --recursive --new-file pl12/linux/net/inet/3c509.c linux/net/inet/3c509.c
--- pl12/linux/net/inet/3c509.c Fri Aug 13 06:35:44 1993
+++ linux/net/inet/3c509.c Fri Sep 3 22:08:32 1993
@@ -1,4 +1,4 @@
-/* el3.c: An 3c509 EtherLink3 ethernet driver for linux. */
+/* 3c509.c: A 3c509 EtherLink3 ethernet driver for linux. */
/*
Written 1993 by Donald Becker.
@@ -7,13 +7,13 @@
distributed according to the terms of the GNU Public License,
incorporated herein by reference.
- This driver should work with the 3Com EtherLinkIII series.
+ This driver is for the 3Com EtherLinkIII series.
The author may be reached as becker@super.org or
C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715
*/
-static char *version = "el3.c: v0.02 8/13/93 becker@super.org\n";
+static char *version = "3c509.c: v0.06 9/3/93 becker@super.org\n";
#include <linux/config.h>
#include <linux/kernel.h>
@@ -23,6 +23,14 @@
#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/in.h>
+
+#ifndef PRE_PL13
+#include <linux/ioport.h>
+#else
+#define snarf_region(base,extent) do {;}while(0)
+#define check_region(base,extent) (0)
+#endif
+
/*#include <asm/system.h>*/
#include <asm/io.h>
#ifndef port_read
@@ -34,10 +42,12 @@
#include "skbuff.h"
#include "arp.h"
+#ifndef HAVE_AUTOIRQ
/* From auto_irq.c, should be in a *.h file. */
extern void autoirq_setup(int waittime);
extern int autoirq_report(int waittime);
extern struct device *irq2dev_map[16];
+#endif
/* These should be in <asm/io.h>. */
#define port_read_l(port,buf,nr) \
@@ -49,9 +59,12 @@
#ifdef EL3_DEBUG
int el3_debug = EL3_DEBUG;
#else
-int el3_debug = 1;
+int el3_debug = 2;
#endif
+/* To minimize the size of the driver source I only define operating
+ constants if they are used several times. You'll need the manual
+ if you want to understand driver details. */
/* Offsets from base I/O address. */
#define EL3_DATA 0x00
#define EL3_CMD 0x0e
@@ -59,6 +72,9 @@
#define ID_PORT 0x100
#define EEPROM_READ 0x80
+#define EL3WINDOW(win_num) outw(0x0800+(win_num), ioaddr + EL3_CMD)
+
+
/* Register window 1 offsets, used in normal operation. */
#define TX_FREE 0x0C
#define TX_STATUS 0x0B
@@ -66,11 +82,12 @@
#define RX_STATUS 0x08
#define RX_FIFO 0x00
+#define WN4_MEDIA 0x0A
+
struct el3_private {
struct enet_statistics stats;
};
-static int el3_init(struct device *dev);
static int read_eeprom(int index);
static int el3_open(struct device *dev);
static int el3_start_xmit(struct sk_buff *skb, struct device *dev);
@@ -85,7 +102,9 @@
int el3_probe(struct device *dev)
{
short lrs_state = 0xff, i;
- unsigned short iobase = 0;
+ short ioaddr, irq;
+ short *phys_addr = (short *)dev->dev_addr;
+ static int current_tag = 0;
/* Send the ID sequence to the ID_PORT. */
outb(0x00, ID_PORT);
@@ -96,75 +115,57 @@
lrs_state = lrs_state & 0x100 ? lrs_state ^ 0xcf : lrs_state;
}
- /* The current Space.c initialization makes it difficult to have more
- than one adaptor initialized. Send me email if you have a need for
- multiple adaptors. */
-
- /* Read in EEPROM data.
- Only the highest address board will stay on-line. */
+ /* For the first probe, clear all board's tag registers. */
+ if (current_tag == 0)
+ outb(0xd0, ID_PORT);
+ else /* Otherwise kill off already-found boards. */
+ outb(0xd8, ID_PORT);
- {
- short *phys_addr = (short *)dev->dev_addr;
- phys_addr[0] = htons(read_eeprom(0));
- if (phys_addr[0] != 0x6000)
- return 1;
- phys_addr[1] = htons(read_eeprom(1));
- phys_addr[2] = htons(read_eeprom(2));
+ if (read_eeprom(7) != 0x6d50) {
+ return -ENODEV;
}
- iobase = read_eeprom(8);
- dev->irq = read_eeprom(9) >> 12;
-
- /* Activate the adaptor at the EEPROM location (if set), else 0x320. */
-
- if (iobase == 0x0000) {
- dev->base_addr = 0x320;
- outb(0xf2, ID_PORT);
- } else {
- dev->base_addr = 0x200 + ((iobase & 0x1f) << 4);
- outb(0xff, ID_PORT);
+ /* Read in EEPROM data, which does contention-select.
+ Only the lowest address board will stay "on-line".
+ 3Com got the byte order backwards. */
+ for (i = 0; i < 3; i++) {
+ phys_addr[i] = htons(read_eeprom(i));
}
- outw(0x0800, dev->base_addr + EL3_CMD); /* Window 0. */
- printk("%s: 3c509 at %#3.3x key %4.4x iobase %4.4x.\n",
- dev->name, dev->base_addr, inw(dev->base_addr), iobase);
+ {
+ unsigned short iobase = read_eeprom(8);
+ dev->if_port = iobase >> 14;
+ ioaddr = 0x200 + ((iobase & 0x1f) << 4);
+ }
+ irq = read_eeprom(9) >> 12;
- if (inw(dev->base_addr) == 0x6d50) {
- el3_init(dev);
- return 0;
- } else
+ /* The current Space.c structure makes it difficult to have more
+ than one adaptor initialized. Send me email if you have a need for
+ multiple adaptors, and we'll work out something. -becker@super.org */
+ if (dev->base_addr != 0
+ && dev->base_addr != (unsigned short)ioaddr) {
return -ENODEV;
-}
-
-static int
-read_eeprom(int index)
-{
- int timer, bit, word = 0;
-
- /* Issue read command, and pause for at least 162 us. for it to complete.
- Assume extra-fast 16Mhz bus. */
- outb(EEPROM_READ + index, ID_PORT);
+ }
- for (timer = 0; timer < 162*4 + 400; timer++)
- SLOW_DOWN_IO;
+ /* Set the adaptor tag so that the next card can be found. */
+ outb(0xd0 + ++current_tag, ID_PORT);
- for (bit = 15; bit >= 0; bit--)
- word = (word << 1) + (inb(ID_PORT) & 0x01);
-
- if (el3_debug > 3)
- printk(" 3c509 EEPROM word %d %#4.4x.\n", index, word);
+ /* Activate the adaptor at the EEPROM location. */
+ outb(0xff, ID_PORT);
- return word;
-}
+ EL3WINDOW(0);
+ if (inw(ioaddr) != 0x6d50)
+ return -ENODEV;
-static int
-el3_init(struct device *dev)
-{
- struct el3_private *lp;
- int ioaddr = dev->base_addr;
- int i;
+ dev->base_addr = ioaddr;
+ dev->irq = irq;
+ snarf_region(dev->base_addr, 16);
- printk("%s: EL3 at %#3x, address", dev->name, ioaddr);
+ {
+ char *if_names[] = {"10baseT", "AUI", "undefined", "BNC"};
+ printk("%s: 3c509 at %#3.3x tag %d, %s port, address ",
+ dev->name, dev->base_addr, current_tag, if_names[dev->if_port]);
+ }
/* Read in the station address. */
for (i = 0; i < 6; i++)
@@ -174,9 +175,8 @@
/* Make up a EL3-specific-data structure. */
dev->priv = kmalloc(sizeof(struct el3_private), GFP_KERNEL);
memset(dev->priv, 0, sizeof(struct el3_private));
- lp = (struct el3_private *)dev->priv;
- if (el3_debug > 1)
+ if (el3_debug > 0)
printk(version);
/* The EL3-specific entries in the device structure. */
@@ -199,7 +199,7 @@
dev->hard_header_len = ETH_HLEN;
dev->mtu = 1500; /* eth_mtu */
dev->addr_len = ETH_ALEN;
- for (i = 0; i < dev->addr_len; i++) {
+ for (i = 0; i < ETH_ALEN; i++) {
dev->broadcast[i]=0xff;
}
@@ -214,6 +214,30 @@
return 0;
}
+
+static int
+read_eeprom(int index)
+{
+ int timer, bit, word = 0;
+
+ /* Issue read command, and pause for at least 162 us. for it to complete.
+ Assume extra-fast 16Mhz bus. */
+ outb(EEPROM_READ + index, ID_PORT);
+
+ /* This should really be done by looking at one of the timer channels. */
+ for (timer = 0; timer < 162*4 + 400; timer++)
+ SLOW_DOWN_IO;
+
+ for (bit = 15; bit >= 0; bit--)
+ word = (word << 1) + (inb(ID_PORT) & 0x01);
+
+ if (el3_debug > 3)
+ printk(" 3c509 EEPROM word %d %#4.4x.\n", index, word);
+
+ return word;
+}
+
+
static int
el3_open(struct device *dev)
@@ -225,26 +249,36 @@
return -EAGAIN;
}
+ EL3WINDOW(0);
if (el3_debug > 3)
- printk("%s: Opening, IRQ %d status@%x %4.4x reg4 %4.4x.\n",
- dev->name, dev->irq, ioaddr + EL3_STATUS,
- inw(ioaddr + EL3_STATUS), inw(ioaddr + 4));
- outw(0x0800, ioaddr + EL3_CMD); /* Make certain we are in window 0. */
+ printk("%s: Opening, IRQ %d status@%x %4.4x.\n", dev->name,
+ dev->irq, ioaddr + EL3_STATUS, inw(ioaddr + EL3_STATUS));
- /* This is probably unnecessary. */
+ /* Activate board: this is probably unnecessary. */
outw(0x0001, ioaddr + 4);
- outw((dev->irq << 12) | 0x0f00, ioaddr + 8);
-
irq2dev_map[dev->irq] = dev;
+ /* Set the IRQ line. */
+ outw((dev->irq << 12) | 0x0f00, ioaddr + 8);
+
/* Set the station address in window 2 each time opened. */
- outw(0x0802, ioaddr + EL3_CMD);
+ EL3WINDOW(2);
for (i = 0; i < 6; i++)
outb(dev->dev_addr[i], ioaddr + i);
- outw(0x1000, ioaddr + EL3_CMD); /* Start the thinnet transceiver. */
+ if (dev->if_port == 3)
+ /* Start the thinnet transceiver. We should really wait 50ms...*/
+ outw(0x1000, ioaddr + EL3_CMD);
+ else if (dev->if_port == 0) {
+ /* 10baseT interface, enabled link beat and jabber check. */
+ EL3WINDOW(4);
+ outw(inw(ioaddr + WN4_MEDIA) | 0x00C0, ioaddr + WN4_MEDIA);
+ }
+
+ /* Switch to register set 1 for normal use. */
+ EL3WINDOW(1);
outw(0x8005, ioaddr + EL3_CMD); /* Accept b-case and phys addr only. */
outw(0xA800, ioaddr + EL3_CMD); /* Turn on statistics. */
@@ -251,19 +285,15 @@
outw(0x2000, ioaddr + EL3_CMD); /* Enable the receiver. */
outw(0x4800, ioaddr + EL3_CMD); /* Enable transmitter. */
outw(0x78ff, ioaddr + EL3_CMD); /* Allow all status bits to be seen. */
+ dev->interrupt = 0;
+ dev->tbusy = 0;
+ dev->start = 1;
outw(0x7098, ioaddr + EL3_CMD); /* Set interrupt mask. */
- /* Switch to register set 1 for normal use. */
- outw(0x0801, ioaddr + EL3_CMD);
-
if (el3_debug > 3)
printk("%s: Opened 3c509 IRQ %d status %4.4x.\n",
dev->name, dev->irq, inw(ioaddr + EL3_STATUS));
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 1;
-
return 0; /* Always succeed */
}
@@ -278,7 +308,7 @@
int tickssofar = jiffies - dev->trans_start;
if (tickssofar < 10)
return 1;
- printk("%s: transmit timed out, tx_status %4.4x status %4.4x.\n",
+ printk("%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
dev->name, inb(ioaddr + TX_STATUS), inw(ioaddr + EL3_STATUS));
dev->trans_start = jiffies;
/* Issue TX_RESET and TX_START commands. */
@@ -308,8 +338,9 @@
}
if (inw(ioaddr + EL3_STATUS) & 0x0001) { /* IRQ line active, missed one. */
- printk("%s: Missed interrupt, status %4.4x.\n", dev->name,
- inw(ioaddr + EL3_STATUS));
+ printk("%s: Missed interrupt, status %4.4x Tx %2.2x Rx %4.4x.\n",
+ dev->name, inw(ioaddr + EL3_STATUS), inb(ioaddr + TX_STATUS),
+ inw(ioaddr + RX_STATUS));
outw(0x7800, ioaddr + EL3_CMD); /* Fake interrupt trigger. */
outw(0x6899, ioaddr + EL3_CMD); /* Ack IRQ */
outw(0x78ff, ioaddr + EL3_CMD); /* Allow all status bits to be seen. */
@@ -322,8 +353,7 @@
outw(skb->len, ioaddr + TX_FIFO);
outw(0x00, ioaddr + TX_FIFO);
/* ... and the packet rounded to a doubleword. */
- port_write(ioaddr + TX_FIFO, (void *)(skb+1),
- ((skb->len + 3) >> 1) & ~0x1);
+ port_write_l(ioaddr + TX_FIFO, (void *)(skb+1), (skb->len + 3) >> 2);
dev->trans_start = jiffies;
if (skb->free)
@@ -360,8 +390,9 @@
el3_interrupt(int reg_ptr)
{
int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2);
- struct device *dev = irq2dev_map[irq];
+ struct device *dev = (struct device *)(irq2dev_map[irq]);
int ioaddr, status;
+ int i = 0;
if (dev == NULL) {
printk ("el3_interrupt(): irq %d for unknown device.\n", irq);
@@ -380,6 +411,9 @@
while ((status = inw(ioaddr + EL3_STATUS)) & 0x01) {
+ if (status & 0x10)
+ el3_rx(dev);
+
if (status & 0x08) {
if (el3_debug > 5)
printk(" TX room bit was handled.\n");
@@ -391,10 +425,12 @@
if (status & 0x80) /* Statistics full. */
update_stats(ioaddr, dev);
- if (status & 0x10)
- el3_rx(dev);
-
- /* Clear the interrupts we've handled. */
+ if (++i > 10) {
+ printk("%s: Infinite loop in interrupt, status %4.4x.\n",
+ dev->name, status);
+ break;
+ }
+ /* Clear the other interrupts we have handled. */
outw(0x6899, ioaddr + EL3_CMD); /* Ack IRQ */
}
@@ -403,16 +439,6 @@
inw(ioaddr + EL3_STATUS));
}
- if (inw(ioaddr + EL3_STATUS) & 0x01) {
- int i = 100000;
- printk("%s: exiting interrupt with status %4.4x.\n", dev->name,
- inw(ioaddr + EL3_STATUS));
- while (i--) /* Delay loop to see the message. */
- inw(ioaddr + EL3_STATUS);
- while ((inw(ioaddr + EL3_STATUS) & 0x0010) && i++ < 20)
- outw(0x00, ioaddr + RX_STATUS);
- }
-
dev->interrupt = 0;
return;
}
@@ -430,7 +456,9 @@
}
/* Update statistics. We change to register window 6, so this
- must be run single-threaded. */
+ should be run single-threaded if the device is active. This
+ is expected to be a rare operation, and not worth a special
+ window-state variable. */
static void update_stats(int ioaddr, struct device *dev)
{
struct el3_private *lp = (struct el3_private *)dev->priv;
@@ -440,7 +468,7 @@
/* Turn off statistics updates while reading. */
outw(0xB000, ioaddr + EL3_CMD);
/* Switch to the stats window, and read everything. */
- outw(0x0806, ioaddr + EL3_CMD);
+ EL3WINDOW(6);
lp->stats.tx_carrier_errors += inb(ioaddr + 0);
lp->stats.tx_heartbeat_errors += inb(ioaddr + 1);
/* Multiple collisions. */ inb(ioaddr + 2);
@@ -454,25 +482,11 @@
inw(ioaddr + 12);
/* Back to window 1, and turn statistics back on. */
- outw(0x0801, ioaddr + EL3_CMD);
+ EL3WINDOW(1);
outw(0xA800, ioaddr + EL3_CMD);
return;
}
-/* Print statistics on the kernel error output. */
-void printk_stats(struct enet_statistics *stats)
-{
-
- printk(" Ethernet statistics: Rx packets %6d Tx packets %6d.\n",
- stats->rx_packets, stats->tx_packets);
- printk(" Carrier errors: %6d.\n", stats->tx_carrier_errors);
- printk(" Heartbeat errors: %6d.\n", stats->tx_heartbeat_errors);
- printk(" Collisions: %6d.\n", stats->collisions);
- printk(" Rx FIFO problems: %6d.\n", stats->rx_fifo_errors);
-
- return;
-}
-
static int
el3_rx(struct device *dev)
{
@@ -498,21 +512,32 @@
}
if ( (! (rx_status & 0x4000))
|| ! (rx_status & 0x2000)) { /* Dribble bits are OK. */
- short length = rx_status & 0x3ff;
- int sksize = sizeof(struct sk_buff) + length + 3;
+ short pkt_len = rx_status & 0x3ff;
+ int sksize = sizeof(struct sk_buff) + pkt_len + 3;
struct sk_buff *skb;
skb = (struct sk_buff *) kmalloc(sksize, GFP_ATOMIC);
if (el3_debug > 4)
printk(" Receiving packet size %d status %4.4x.\n",
- length, rx_status);
+ pkt_len, rx_status);
if (skb != NULL) {
- skb->lock = 0;
skb->mem_len = sksize;
skb->mem_addr = skb;
+ skb->len = pkt_len;
+ skb->dev = dev;
+
/* 'skb+1' points to the start of sk_buff data area. */
- port_read(ioaddr+RX_FIFO, (void *)(skb+1), ((length + 3) >> 2) << 1);
- if (dev_rint((unsigned char *)skb, length, IN_SKBUFF,dev)== 0){
+ port_read_l(ioaddr+RX_FIFO, (void *)(skb+1),
+ (pkt_len + 3) >> 2);
+
+#ifdef HAVE_NETIF_RX
+ netif_rx(skb);
+ outw(0x4000, ioaddr + EL3_CMD); /* Rx discard */
+ continue;
+#else
+ skb->lock = 0;
+ if (dev_rint((unsigned char *)skb, pkt_len,
+ IN_SKBUFF,dev)== 0){
if (el3_debug > 6)
printk(" dev_rint() happy, status %4.4x.\n",
inb(ioaddr + EL3_STATUS));
@@ -527,7 +552,8 @@
} else {
printk("%s: receive buffers full.\n", dev->name);
kfree_s(skb, sksize);
- }
+ }
+#endif
} else if (el3_debug)
printk("%s: Couldn't allocate a sk_buff of size %d.\n",
dev->name, sksize);
@@ -564,22 +590,21 @@
outw(0x1800, ioaddr + EL3_CMD);
outw(0x5000, ioaddr + EL3_CMD);
- /* Turn off thinnet power. */
- outw(0xb800, ioaddr + EL3_CMD);
-
- if (el3_debug > 2) {
- struct el3_private *lp = (struct el3_private *)dev->priv;
- printk("%s: Status was %4.4x.\n", dev->name, inw(ioaddr + EL3_STATUS));
- printk_stats(&lp->stats);
+ if (dev->if_port == 3)
+ /* Turn off thinnet power. */
+ outw(0xb800, ioaddr + EL3_CMD);
+ else if (dev->if_port == 0) {
+ /* Disable link beat and jabber, if_port may change ere next open(). */
+ EL3WINDOW(4);
+ outw(inw(ioaddr + WN4_MEDIA) & ~ 0x00C0, ioaddr + WN4_MEDIA);
}
- /* Free the interrupt line. */
free_irq(dev->irq);
- outw(0x1000, ioaddr + EL3_CMD);
+ /* Switching back to window 0 disables the IRQ. */
+ EL3WINDOW(0);
+ /* But we explicitly zero the IRQ line select anyway. */
outw(0x0f00, ioaddr + 8);
- /* Switch back to register window 0. */
- outw(0x0800, ioaddr + EL3_CMD);
irq2dev_map[dev->irq] = 0;
diff -u --recursive --new-file pl12/linux/net/inet/8390.c linux/net/inet/8390.c
--- pl12/linux/net/inet/8390.c Fri Aug 13 04:24:31 1993
+++ linux/net/inet/8390.c Fri Sep 3 23:27:54 1993
@@ -14,15 +14,8 @@
*/
static char *version =
- "8390.c:v0.99-12 8/9/93 for 0.99.12+ Donald Becker (becker@super.org)\n";
+ "8390.c:v0.99-13 9/3/93 for 0.99.13 Donald Becker (becker@super.org)\n";
#include <linux/config.h>
-#if !defined(EL2) && !defined(NE2000) && !defined(WD80x3) && !defined(HPLAN)
-/* They don't know what they want -- give it all to them! */
-#define EL2
-#define NE2000
-#define WD80x3
-#define HPLAN
-#endif
/*
Braindamage remaining:
@@ -94,12 +87,6 @@
static void NS8390_trigger_send(struct device *dev, unsigned int length,
int start_page);
-extern int el2autoprobe(int ioaddr, struct device *dev);
-extern int el2probe(int ioaddr, struct device *dev);
-extern int neprobe(int ioaddr, struct device *dev);
-extern int wdprobe(int ioaddr, struct device *dev);
-extern int hpprobe(int ioaddr, struct device *dev);
-
struct sigaction ei_sigaction = { ei_interrupt, 0, 0, NULL, };
/* Open/initialize the board. This routine goes all-out, setting everything
@@ -260,7 +247,7 @@
ei_interrupt(int reg_ptr)
{
int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2);
- struct device *dev = irq2dev_map[irq];
+ struct device *dev = (struct device *)(irq2dev_map[irq]);
int e8390_base;
int interrupts, boguscount = 0;
struct ei_device *ei_local;
@@ -580,35 +567,14 @@
return &ei_local->stat;
}
-int
-ethif_init(struct device *dev)
-{
- if (1
-#ifdef WD80x3
- && ! wdprobe(dev->base_addr, dev)
-#endif
-#ifdef EL2
- && ! el2autoprobe(dev->base_addr, dev)
-#endif
-#ifdef NE2000
- && ! neprobe(dev->base_addr, dev)
-#endif
-#ifdef HPLAN
- && ! hpprobe(dev->base_addr, dev)
-#endif
- && 1 ) {
- return 1; /* -ENODEV or -EAGAIN would be more accurate. */
- }
- if (ei_debug > 1)
- printk(version);
- return 0;
-}
-
-/* Initialize the rest of the device structure. */
+/* Initialize the rest of the 8390 device structure. */
int
ethdev_init(struct device *dev)
{
int i;
+
+ if (ei_debug > 1)
+ printk(version);
for (i = 0; i < DEV_NUMBUFFS; i++)
dev->buffs[i] = NULL;
diff -u --recursive --new-file pl12/linux/net/inet/8390.h linux/net/inet/8390.h
--- pl12/linux/net/inet/8390.h Fri Aug 13 04:24:32 1993
+++ linux/net/inet/8390.h Mon Aug 30 22:43:18 1993
@@ -8,6 +8,7 @@
#define _8390_h
#include <linux/if_ether.h>
+#include <linux/ioport.h>
#define TX_2X_PAGES 12
#define TX_1X_PAGES 6
@@ -25,10 +26,12 @@
extern int ei_open(struct device *dev);
extern void ei_interrupt(int reg_ptr);
+#ifndef HAVE_AUTOIRQ
/* From auto_irq.c */
extern struct device *irq2dev_map[16];
extern void autoirq_setup(int waittime);
extern int autoirq_report(int waittime);
+#endif
/* Most of these entries should be in 'struct device' (or most of the
things in there should be here!) */
diff -u --recursive --new-file pl12/linux/net/inet/CONFIG linux/net/inet/CONFIG
--- pl12/linux/net/inet/CONFIG Fri Aug 6 20:46:27 1993
+++ linux/net/inet/CONFIG Fri Sep 3 23:54:30 1993
@@ -1,53 +1,47 @@
#
-# Set the address and IRQ here. The ne.c and 3c503 driver will autoprobe
+# Set any special options here. Most drivers will autoprobe/autoIRQ
# if you set the address or IRQ to zero, so we do that by default.
-# Cards supportted:
+# Cards and options supported:
#
-# WD80x3 The Western Digital (SMC) WD80x3 driver
-# WD_SHMEM=xxx Forces the address of the shared memory
-# FORCE_8BIT Force card into 8-bit mode (WD8003)
-# NE2000 The Novell NE-2000 driver
-# HPLAN The HP-LAN driver
-# EL1 The 3c501 EtherLink I driver (source missing?)
-# EL2 The 3c503 EtherLink II driver
-# EL2_AUI Selects the AUI port instead of the BNC port
-# PLIP The Crynwe PL/IP driver
-# SLIP The MicroWalt SLIP driver
+# EI_DEBUG Set the debugging level for 8390-based boards
+# CONFIG_WD80x3 The Western Digital (SMC) WD80x3 driver
+# WD_SHMEM=xxx Forces the address of the shared memory
+# WD_no_mapout Don't map out the shared memory (faster, but
+# your machine may not warm-boot).
+# CONFIG_NE2000 The NE-[12]000 clone driver.
+# PACKETBUF_MEMSIZE Allows an extra-large packet buffer to be
+# used. Usually pointless under Linux.
+# show_all_SAPROM Show the entire address PROM, not just the
+# ethernet address, during boot.
+# rw_bugfix Patch an obscure bug with a version of the 8390.
+# CONFIG_HPLAN The HP-LAN driver (for 8390-based boards only).
+# rw_bugfix Fix the same obscure bug.
+# CONFIG_EL1 The 3c501 driver (just joking, never released)
+# CONFIG_EL2 The 3c503 EtherLink II driver
+# EL2_AUI Default to the AUI port instead of the BNC port
+# no_probe_nonshared_memory Don't probe for programmed-I/O boards.
+# EL2MEMTEST Test shared memory at boot-time.
+# CONFIG_EL3
+# EL3_DEBUG Set the debugging message level.
+# CONFIG_AT1500
+# LANCE_DEBUG Set the debugging message level.
+# DEFAULT_DMA Change the default DMA to other than 5.
+# CONFIG_PLIP The Crynwr-protocol PL/IP driver
+# SLIP The MicroWalt SLIP driver
# SL_DUMP Uses the "dump frame" debug code
# SL_COMPRESSED Use CSLIP
-# D_LINK The D-Link DE-600 Portable Ethernet Adaptor.
+# D_LINK The D-Link DE-600 Portable Ethernet Adaptor.
# D_LINK_IO The D-Link I/O address (0x378 == default)
# D_LINK_IRQ The D-Link IRQ number to use (IRQ7 == default)
# D_LINK_DEBUG Enable or disable D-Link debugging
#
-# Note: for most WD (SMC) cards, the AutoProbe doesn't work. You have
-# to force those cards into operation, by specifying the I/O add-
-# ress (EI8390=xxx), the IRQ (EI8390_IRQ=xxx) and the address of
-# the shared memory (WD_SHMEM=xxxx). All other supported cards
-# behave like they should, you can leave the values to 0. -FvK
-#
-
-# Comment out the lines you don't want..
-
-#CARDS := $(CARDS) -DSLIP
-#CARDS := $(CARDS) -DPLIP
-CARDS := $(CARDS) -DWD80x3
-CARDS := $(CARDS) -DNE2000
-CARDS := $(CARDS) -DHPLAN
-CARDS := $(CARDS) -DEL2
-CARDS := $(CARDS) -DD_LINK
-CARDS := $(CARDS) -DCONFIG_AT1500
-# For WD and SMC cards:
-#OPTS = -DEI8390=0x280 -DEI8390_IRQ=15
-#WD_OPTS = -DWD_SHMEM=0xCC000 -UFORCE_8BIT
-OPTS = -DEI8390=0 -DEI8390_IRQ=0
-WD_OPTS = -DWD_SHMEM=0
+# This is at the top level with 'make config'
+CARDS =
-# For all other cards:
-#OPTS = -DEI8390=0 -DEI8390_IRQ=0
-#WD_OPTS = -DUD_SHMEM=0xCC000 -UFORCE_8BIT
+OPTS = #-DEI8390=0 -DEI8390_IRQ=0
+WD_OPTS = #-DWD_SHMEM=0
EL2_OPTS = #-UEL2_AUI
NE_OPTS =
HP_OPTS =
diff -u --recursive --new-file pl12/linux/net/inet/Makefile linux/net/inet/Makefile
--- pl12/linux/net/inet/Makefile Fri Aug 6 20:44:14 1993
+++ linux/net/inet/Makefile Fri Sep 3 23:57:25 1993
@@ -20,7 +20,7 @@
OBJS = Space.o sock.o utils.o route.o proc.o timer.o protocol.o loopback.o \
eth.o packet.o arp.o dev.o 8390.o wd.o ne.o el2.o hp.o plip.o \
slip.o slhc.o d_link.o auto_irq.o ip.o raw.o icmp.o tcp.o udp.o\
- lance.o
+ lance.o 3c509.o #ip-frag.o
ifdef CONFIG_INET
@@ -38,36 +38,39 @@
include CONFIG
-Space.o: CONFIG Space.c Makefile
+Space.o: Space.c CONFIG /usr/include/linux/autoconf.h
$(CC) $(CPPFLAGS) $(CFLAGS) $(OPTS) $(CARDS) $(DL_OPTS) \
- -c Space.c -o $@
+ -c $< -o $@
-8390.o: CONFIG 8390.c Makefile
- $(CC) $(CPPFLAGS) $(CFLAGS) $(CARDS) -c 8390.c -o $@
+8390.o: 8390.c CONFIG
+ $(CC) $(CPPFLAGS) $(CFLAGS) $(CARDS) -c $< -o $@
-wd.o: CONFIG wd.c Makefile
- $(CC) $(CPPFLAGS) $(CFLAGS) $(WD_OPTS) -c wd.c -o $@
+wd.o: wd.c CONFIG
+ $(CC) $(CPPFLAGS) $(CFLAGS) $(WD_OPTS) -c $< -o $@
-el2.o: CONFIG el2.c el2reg.h Makefile
- $(CC) $(CPPFLAGS) $(CFLAGS) $(EL2_OPTS) -c el2.c -o $@
+el2.o: el2.c CONFIG el2reg.h
+ $(CC) $(CPPFLAGS) $(CFLAGS) $(EL2_OPTS) -c $< -o $@
-ne.o: CONFIG ne.c Makefile
- $(CC) $(CPPFLAGS) $(CFLAGS) $(NE_OPTS) -c ne.c -o $@
+ne.o: ne.c CONFIG
+ $(CC) $(CPPFLAGS) $(CFLAGS) $(NE_OPTS) -c $< -o $@
-hp.o: CONFIG hp.c Makefile
- $(CC) $(CPPFLAGS) $(CFLAGS) $(HP_OPTS) -c hp.c -o $@
+hp.o: hp.c CONFIG
+ $(CC) $(CPPFLAGS) $(CFLAGS) $(HP_OPTS) -c $< -o $@
-plip.o: CONFIG plip.c Makefile
- $(CC) $(CPPFLAGS) $(CFLAGS) $(PLIP_OPTS) -c plip.c -o $@
+plip.o: plip.c CONFIG
+ $(CC) $(CPPFLAGS) $(CFLAGS) $(PLIP_OPTS) -c $< -o $@
-slip.o: CONFIG slip.c Makefile
- $(CC) $(CPPFLAGS) $(CFLAGS) $(SLIP_OPTS) -c slip.c -o $@
+slip.o: slip.c CONFIG
+ $(CC) $(CPPFLAGS) $(CFLAGS) $(SLIP_OPTS) -c $< -o $@
-d_link.o: CONFIG d_link.c Makefile
- $(CC) $(CPPFLAGS) $(CFLAGS) $(DL_OPTS) -c d_link.c -o $@
+d_link.o: d_link.c CONFIG
+ $(CC) $(CPPFLAGS) $(CFLAGS) $(DL_OPTS) -c $< -o $@
-lance.o: CONFIG lance.c Makefile
- $(CC) $(CPPFLAGS) $(CFLAGS) $(AT_OPTS) -c lance.c -o $@
+lance.o: lance.c CONFIG
+ $(CC) $(CPPFLAGS) $(CFLAGS) $(AT_OPTS) -c $< -o $@
+
+3c509.o: 3c509.c CONFIG
+ $(CC) $(CPPFLAGS) $(CFLAGS) $(EL3_OPTS) -c $< -o $@
subdirs: dummy
for i in $(SUBDIRS); do (cd $$i; $(MAKE)); done
diff -u --recursive --new-file pl12/linux/net/inet/Space.c linux/net/inet/Space.c
--- pl12/linux/net/inet/Space.c Fri Aug 13 04:27:58 1993
+++ linux/net/inet/Space.c Sat Sep 4 13:42:55 1993
@@ -33,6 +33,73 @@
#define NEXT_DEV NULL
+/* A unifed ethernet device probe. This is the easiest way to have every
+ ethernet adaptor have the name "eth[0123...]".
+ */
+
+extern int wd_probe(struct device *dev);
+extern int el2_probe(struct device *dev);
+extern int ne_probe(struct device *dev);
+extern int hp_probe(struct device *dev);
+extern int znet_probe(struct device *);
+extern int express_probe(struct device *);
+extern int el3_probe(struct device *);
+extern int atp_probe(struct device *);
+extern int at1500_probe(struct device *);
+extern int depca_probe(struct device *);
+extern int el1_probe(struct device *);
+
+static int
+ethif_probe(struct device *dev)
+{
+ short base_addr = dev->base_addr;
+
+ if (base_addr < 0 || base_addr == 1)
+ return 1; /* ENXIO */
+
+ if (1
+#if defined(CONFIG_WD80x3) || defined(WD80x3)
+ && wd_probe(dev)
+#endif
+#if defined(CONFIG_EL2) || defined(EL2)
+ && el2_probe(dev)
+#endif
+#if defined(CONFIG_NE2000) || defined(NE2000)
+ && ne_probe(dev)
+#endif
+#if defined(CONFIG_HPLAN) || defined(HPLAN)
+ && hp_probe(dev)
+#endif
+#ifdef CONFIG_AT1500
+ && at1500_probe(dev)
+#endif
+#ifdef CONFIG_EL3
+ && el3_probe(dev)
+#endif
+#ifdef CONFIG_ZNET
+ && znet_probe(dev)
+#endif
+#ifdef CONFIG_EEXPRESS
+ && express_probe(dev)
+#endif
+#ifdef CONFIG_ATP /* AT-LAN-TEC (RealTek) pocket adaptor. */
+ && atp_probe(dev)
+#endif
+#ifdef CONFIG_DEPCA
+ && depca_probe(dev)
+#endif
+#ifdef CONFIG_EL1
+ && el1_probe(dev)
+#endif
+ && 1 ) {
+ return 1; /* -ENODEV or -EAGAIN would be more accurate. */
+ }
+ return 0;
+}
+
+
+/* This remains seperate because it requires the addr and IRQ to be
+ set. */
#if defined(D_LINK) || defined(CONFIG_DE600)
extern int d_link_init(struct device *);
static struct device d_link_dev = {
@@ -51,101 +118,32 @@
# define NEXT_DEV (&d_link_dev)
#endif
-#ifdef CONFIG_EL1
-#error
-# ifndef EL1_IRQ
-# define EL1_IRQ 9
-# endif
-# ifndef EL1
-# define EL1 0
-# endif
- extern int el1_init(struct device *);
- static struct device el1_dev = {
- "el0", 0, 0, 0, 0, EL1, EL1_IRQ, 0, 0, 0, NEXT_DEV, el1_init
- };
-# undef NEXT_DEV
-# define NEXT_DEV (&el1_dev)
-#endif /* EL1 */
-
-#ifdef CONFIG_DEPCA
- extern int depca_probe(struct device *);
- static struct device depca_dev = {
- "depca0", 0,0,0,0, 0, 0, 0, 0, 0, NEXT_DEV, depca_probe,
- };
-# undef NEXT_DEV
-# define NEXT_DEV (&depca_dev)
-#endif /* CONFIG_DEPCA */
-
-
-#ifdef CONFIG_ATP /* AT-LAN-TEC (RealTek) pocket adaptor. */
- extern int atp_probe(struct device *);
- static struct device atp_dev = {
- "atp0", 0,0,0,0, 0, 0, 0, 0, 0, NEXT_DEV, atp_probe,
- };
-# undef NEXT_DEV
-# define NEXT_DEV (&atp_dev)
-#endif /* CONFIG_ATP */
-
-#ifdef CONFIG_EL3
- extern int el3_probe(struct device *);
- static struct device eliii0_dev = {
- "eliii0", 0,0,0,0, 0, 0, 0, 0, 0, NEXT_DEV, el3_probe,
- };
-# undef NEXT_DEV
-# define NEXT_DEV (&eliii0_dev)
-#endif /* CONFIG_3C509 aka EL3 */
-
-#ifdef CONFIG_ZNET
- extern int znet_probe(struct device *);
- static struct device znet_dev = {
- "znet", 0,0,0,0, 0, 0, 0, 0, 0, NEXT_DEV, znet_probe, };
-# undef NEXT_DEV
-# define NEXT_DEV (&znet_dev)
-#endif /* CONFIG_ZNET */
+/* The first device defaults to I/O base '0', which means autoprobe. */
+#ifdef EI8390
+# define ETH0_ADDR EI8390
+#else
+# define ETH0_ADDR 0
+#endif
+#ifdef EI8390_IRQ
+# define ETH0_IRQ EI8390_IRQ
+#else
+# define ETH0_IRQ 0
+#endif
+/* "eth0" defaults to autoprobe, other use a base of "-0x20", "don't probe".
+ Enable these with boot-time setup. 0.99pl13+ can optionally autoprobe. */
-#ifdef CONFIG_EEXPRESS
- extern int express_probe(struct device *);
- static struct device express0_dev = {
- "exp0", 0,0,0,0, 0, 0, 0, 0, 0, NEXT_DEV, express_probe, };
-# undef NEXT_DEV
-# define NEXT_DEV (&express0_dev)
-#endif /* CONFIG_EEPRESS */
+static struct device eth3_dev = {
+ "eth3", 0,0,0,0,0xffe0 /* I/O base*/, 0,0,0,0, NEXT_DEV, ethif_probe };
+static struct device eth2_dev = {
+ "eth2", 0,0,0,0,0xffe0 /* I/O base*/, 0,0,0,0, &eth3_dev, ethif_probe };
+static struct device eth1_dev = {
+ "eth1", 0,0,0,0,0xffe0 /* I/O base*/, 0,0,0,0, &eth2_dev, ethif_probe };
-#ifdef CONFIG_AT1500
- extern int at1500_probe(struct device *);
- static struct device lance_dev = {
- "le0",
- 0,0,0,0, 0 /* I/O Base */, 0 /* pre-set IRQ */,
- 0, 0, 0, NEXT_DEV, at1500_probe,
- };
-# undef NEXT_DEV
-# define NEXT_DEV (&lance_dev)
-#endif /* AT1500BT */
+static struct device eth0_dev = {
+ "eth0", 0, 0, 0, 0, ETH0_ADDR, ETH0_IRQ, 0, 0, 0, &eth1_dev, ethif_probe };
-#if defined(EI8390) || defined(CONFIG_EL2) || defined(CONFIG_NE2000) \
- || defined(CONFIG_WD80x3) || defined(CONFIG_HPLAN)
-# ifndef EI8390
-# define EI8390 0
-# endif
-# ifndef EI8390_IRQ
-# define EI8390_IRQ 0
-# endif
- extern int ethif_init(struct device *);
- static struct device ei8390_dev = {
- "eth0",
- 0, /* auto-config */
- 0,
- 0,
- 0,
- EI8390,
- EI8390_IRQ,
- 0, 0, 0,
- NEXT_DEV,
- ethif_init
- };
# undef NEXT_DEV
-# define NEXT_DEV (&ei8390_dev)
-#endif /* The EI8390 drivers. */
+# define NEXT_DEV (&eth0_dev)
#if defined(PLIP) || defined(CONFIG_PLIP)
extern int plip_init(struct device *);
diff -u --recursive --new-file pl12/linux/net/inet/dev.c linux/net/inet/dev.c
--- pl12/linux/net/inet/dev.c Sat Aug 14 14:32:05 1993
+++ linux/net/inet/dev.c Tue Aug 31 05:00:04 1993
@@ -18,6 +18,7 @@
*/
#include <asm/segment.h>
#include <asm/system.h>
+#include <asm/bitops.h>
#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
@@ -29,6 +30,7 @@
#include <linux/in.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
+#include <linux/if_ether.h>
#include "inet.h"
#include "dev.h"
#include "eth.h"
@@ -368,9 +370,40 @@
sti();
}
+/*
+ * Receive a packet from a device driver and queue it for the upper
+ * (protocol) levels. It always succeeds.
+ */
+void
+netif_rx(struct sk_buff *skb)
+{
+ /* Set any necessary flags. */
+ skb->lock = 0;
+ skb->sk = NULL;
+
+ /* and add it to the "backlog" queue. */
+ cli();
+ if (backlog == NULL) {
+ skb->prev = skb;
+ skb->next = skb;
+ backlog = skb;
+ } else {
+ skb->prev = (struct sk_buff *) backlog->prev;
+ skb->next = (struct sk_buff *) backlog;
+ skb->next->prev = skb;
+ skb->prev->next = skb;
+ }
+ sti();
+
+ /* If any packet arrived, mark it for processing. */
+ if (backlog != NULL) mark_bh(INET_BH);
+
+ return;
+}
+
/*
- * Fetch a packet from a device driver.
+ * The old interface to fetch a packet from a device driver.
* This function is the base level entry point for all drivers that
* want to send a packet to the upper (protocol) levels. It takes
* care of de-multiplexing the packet to the various modules based
@@ -389,18 +422,20 @@
int len2;
if (dev == NULL || buff == NULL || len <= 0) return(1);
- if (dropping && backlog != NULL) {
- return(1);
- }
- if (dropping) printk("INET: dev_rint: no longer dropping packets.\n");
- dropping = 0;
-
if (flags & IN_SKBUFF) {
skb = (struct sk_buff *) buff;
} else {
+ if (dropping) {
+ if (backlog != NULL)
+ return(1);
+ printk("INET: dev_rint: no longer dropping packets.\n");
+ dropping = 0;
+ }
+
skb = (struct sk_buff *) kmalloc(sizeof(*skb) + len, GFP_ATOMIC);
if (skb == NULL) {
- printk("dev_rint: packet dropped (no memory) !\n");
+ printk("dev_rint: packet dropped on %s (no memory) !\n",
+ dev->name);
dropping = 1;
return(1);
}
@@ -426,25 +461,8 @@
}
skb->len = len;
skb->dev = dev;
- skb->sk = NULL;
-
- /* Now add it to the backlog. */
- cli();
- if (backlog == NULL) {
- skb->prev = skb;
- skb->next = skb;
- backlog = skb;
- } else {
- skb->prev = (struct sk_buff *) backlog->prev;
- skb->next = (struct sk_buff *) backlog;
- skb->next->prev = skb;
- skb->prev->next = skb;
- }
- sti();
-
- /* If any packet arrived, mark it for processing. */
- if (backlog != NULL) mark_bh(INET_BH);
+ netif_rx(skb);
/* OK, all done. */
return(0);
}
@@ -475,16 +493,11 @@
struct packet_type *ptype;
unsigned short type;
unsigned char flag = 0;
- static volatile int in_bh = 0;
+ static volatile char in_bh = 0;
- /* Check && mark our BUSY state. */
- cli();
- if (in_bh != 0) {
- sti();
- return;
- }
- in_bh = 1;
- sti();
+ /* Atomically check and mark our BUSY state. */
+ if (set_bit(1, (void*)&in_bh))
+ return;
/* Can we send anything now? */
dev_transmit();
@@ -671,14 +684,46 @@
return(pos - arg);
}
+/* Print device statistics. */
+char *sprintf_stats(char *buffer, struct device *dev)
+{
+ char *pos = buffer;
+ struct enet_statistics *stats = (dev->get_stats ? dev->get_stats(dev): NULL);
+
+ if (stats)
+ pos += sprintf(pos, "%6s:%7d %4d %4d %4d %4d %8d %4d %4d %4d %5d %4d\n",
+ dev->name,
+ stats->rx_packets, stats->rx_errors,
+ stats->rx_dropped + stats->rx_missed_errors,
+ stats->rx_fifo_errors,
+ stats->rx_length_errors + stats->rx_over_errors
+ + stats->rx_crc_errors + stats->rx_frame_errors,
+ stats->tx_packets, stats->tx_errors, stats->tx_dropped,
+ stats->tx_fifo_errors, stats->collisions,
+ stats->tx_carrier_errors + stats->tx_aborted_errors
+ + stats->tx_window_errors + stats->tx_heartbeat_errors);
+ else
+ pos += sprintf(pos, "%6s: No statistics available.\n", dev->name);
+
+ return pos;
+}
/* Called from the PROCfs module. */
int
dev_get_info(char *buffer)
{
- return(dev_ifconf(buffer));
-}
+ char *pos = buffer;
+ struct device *dev;
+ pos +=
+ sprintf(pos,
+ "Inter-| Receive | Transmit\n"
+ " face |packets errs drop fifo frame|packets errs drop fifo colls carrier\n");
+ for (dev = dev_base; dev != NULL; dev = dev->next) {
+ pos = sprintf_stats(pos, dev);
+ }
+ return pos - buffer;
+}
/* Perform the SIOCxIFxxx calls. */
static int
@@ -702,18 +747,18 @@
ret = 0;
break;
case SIOCSIFFLAGS:
- ret = dev->flags;
- dev->flags = ifr.ifr_flags & (
+ {
+ int old_flags = dev->flags;
+ dev->flags = ifr.ifr_flags & (
IFF_UP | IFF_BROADCAST | IFF_DEBUG | IFF_LOOPBACK |
IFF_POINTOPOINT | IFF_NOTRAILERS | IFF_RUNNING |
IFF_NOARP | IFF_PROMISC | IFF_ALLMULTI);
- if ((ret & IFF_UP) && ((dev->flags & IFF_UP) == 0)) {
+ if ((old_flags & IFF_UP) && ((dev->flags & IFF_UP) == 0)) {
ret = dev_close(dev);
- } else {
- if (((ret & IFF_UP) == 0) && (dev->flags & IFF_UP)) {
- ret = dev_open(dev);
- } else ret = 0;
- }
+ } else
+ ret = (! (old_flags & IFF_UP) && (dev->flags & IFF_UP))
+ ? dev_open(dev) : 0;
+ }
break;
case SIOCGIFADDR:
(*(struct sockaddr_in *)
@@ -820,9 +865,55 @@
int ret;
switch(cmd) {
- case IP_SET_DEV:
- printk("INET: Warning: old-style ioctl(IP_SET_DEV) called!\n");
- return(-EINVAL);
+ case IP_SET_DEV:
+ { /* Maintain backwards-compatibility, to be deleted for 1.00. */
+ struct device *dev;
+ /* The old 'struct ip_config'. */
+ struct ip_config {
+ char name[MAX_IP_NAME];
+ unsigned long paddr, router, net,up:1,destroy:1;
+ } ipc;
+ int retval, loopback;
+
+ printk("INET: Warning: old-style ioctl(IP_SET_DEV) called!\n");
+ if (!suser())
+ return (-EPERM);
+
+ verify_area (VERIFY_WRITE, arg, sizeof (ipc));
+ memcpy_fromfs(&ipc, arg, sizeof (ipc));
+ ipc.name[MAX_IP_NAME-1] = 0;
+ loopback = (strcmp(ipc.name, "loopback") == 0);
+ dev = dev_get( loopback ? "lo" : ipc.name);
+ if (dev == NULL)
+ return -EINVAL;
+ ipc.destroy = 0;
+ dev->pa_addr = ipc.paddr;
+ dev->family = AF_INET;
+ dev->pa_mask = get_mask(dev->pa_addr);
+ dev->pa_brdaddr = dev->pa_addr | ~dev->pa_mask;
+ if (ipc.net != 0xffffffff) {
+ dev->flags |= IFF_BROADCAST;
+ dev->pa_brdaddr = ipc.net;
+ }
+
+ /* To be proper we should delete the route here. */
+ if (ipc.up == 0)
+ return (dev->flags & IFF_UP != 0) ? dev_close(dev) : 0;
+
+ if ((dev->flags & IFF_UP) == 0
+ && (retval = dev_open(dev)) != 0)
+ return retval;
+ printk("%s: adding HOST route of %8.8x.\n", dev->name,
+ htonl(ipc.paddr));
+ rt_add(RTF_HOST, ipc.paddr, 0, dev);
+ if (ipc.router != 0 && ipc.router != -1) {
+ rt_add(RTF_GATEWAY, ipc.paddr, ipc.router, dev);
+ printk("%s: adding GATEWAY route of %8.8x.\n",
+ dev->name, htonl(ipc.paddr));
+
+ }
+ return 0;
+ }
case SIOCGIFCONF:
(void) dev_ifconf((char *) arg);
ret = 0;
diff -u --recursive --new-file pl12/linux/net/inet/dev.h linux/net/inet/dev.h
--- pl12/linux/net/inet/dev.h Fri Aug 13 04:24:31 1993
+++ linux/net/inet/dev.h Sat Aug 28 00:48:47 1993
@@ -169,6 +169,9 @@
extern int dev_close(struct device *dev);
extern void dev_queue_xmit(struct sk_buff *skb, struct device *dev,
int pri);
+#define HAVE_NETIF_RX 1
+extern void netif_rx(struct sk_buff *skb);
+/* The old interface to netif_rx(). */
extern int dev_rint(unsigned char *buff, long len, int flags,
struct device * dev);
extern void dev_transmit(void);
diff -u --recursive --new-file pl12/linux/net/inet/el2.c linux/net/inet/el2.c
--- pl12/linux/net/inet/el2.c Fri Aug 13 04:24:27 1993
+++ linux/net/inet/el2.c Mon Aug 30 23:59:57 1993
@@ -16,7 +16,7 @@
*/
static char *version =
- "el2.c:v0.99.12B 8/12/93 Donald Becker (becker@super.org)\n";
+ "el2.c:v0.99.13 8/30/93 Donald Becker (becker@super.org)\n";
#include <linux/config.h>
#include <linux/kernel.h>
@@ -30,9 +30,9 @@
#include "8390.h"
#include "el2reg.h"
-int el2autoprobe(int ioaddr, struct device *dev);
+int el2_probe(struct device *dev);
int el2_pio_autoprobe(struct device *dev);
-int el2probe(int ioaddr, struct device *dev);
+int el2probe1(int ioaddr, struct device *dev);
static int el2_open(struct device *dev);
static int el2_close(struct device *dev);
@@ -55,13 +55,15 @@
static int ports[] = {0x300,0x310,0x330,0x350,0x250,0x280,0x2a0,0x2e0,0};
int
-el2autoprobe(int ioaddr, struct device *dev)
+el2_probe(struct device *dev)
{
int *addr, addrs[] = { 0xddffe, 0xd9ffe, 0xcdffe, 0xc9ffe, 0};
+ short ioaddr = dev->base_addr;
- /* Non-autoprobe case first: */
+ if (ioaddr < 0)
+ return ENXIO; /* Don't probe at all. */
if (ioaddr > 0)
- return el2probe(ioaddr, dev);
+ return ! el2probe1(ioaddr, dev);
for (addr = addrs; *addr; addr++) {
int i;
@@ -70,13 +72,19 @@
for(i = 7; i >= 0; i--, base_bits >>= 1)
if (base_bits & 0x1)
break;
- if (base_bits == 1 && el2probe(ports[i], dev))
- return dev->base_addr;
+ if (base_bits != 1)
+ continue;
+#ifdef HAVE_PORTRESERVE
+ if (check_region(ports[i], 16))
+ continue;
+#endif
+ if (el2probe1(ports[i], dev))
+ return 0;
}
-#ifdef probe_nonshared_memory
+#ifndef no_probe_nonshared_memory
return el2_pio_autoprobe(dev);
#else
- return 0;
+ return ENODEV;
#endif
}
@@ -87,14 +95,18 @@
{
int i;
for (i = 0; i < 8; i++) {
+#ifdef HAVE_PORTRESERVE
+ if (check_region(ports[i], 16))
+ continue;
+#endif
/* Reset and/or avoid any lurking NE2000 */
if (inb_p(ports[i] + 0x408) == 0xff)
continue;
if (inb(ports[i] + 0x403) == (0x80 >> i) /* Preliminary check */
- && el2probe(ports[i], dev))
- return dev->base_addr;
+ && el2probe1(ports[i], dev))
+ return 0;
}
- return 0;
+ return ENODEV;
}
/* Probe for the Etherlink II card at I/O port base IOADDR,
@@ -101,7 +113,7 @@
returning non-zero on sucess. If found, set the station
address and memory parameters in DEVICE. */
int
-el2probe(int ioaddr, struct device *dev)
+el2probe1(int ioaddr, struct device *dev)
{
int i, iobase_reg, membase_reg, saved_406;
unsigned char *station_addr = dev->dev_addr;
@@ -134,6 +146,9 @@
return 0;
}
+#ifdef HAVE_PORTRESERVE
+ snarf_region(ioaddr, 16);
+#endif
ethdev_init(dev);
/* Map the 8390 back into the window. */
diff -u --recursive --new-file pl12/linux/net/inet/hp.c linux/net/inet/hp.c
--- pl12/linux/net/inet/hp.c Fri Aug 13 04:24:29 1993
+++ linux/net/inet/hp.c Tue Aug 31 00:02:40 1993
@@ -13,7 +13,7 @@
*/
static char *version =
- "hp.c:v0.99.12+ 8/12/93 Donald Becker (becker@super.org)\n";
+ "hp.c:v0.99.13 8/30/93 Donald Becker (becker@super.org)\n";
#include <linux/config.h>
#include <linux/kernel.h>
@@ -40,7 +40,7 @@
#define HP_8BSTOP_PG 0x80 /* Last page +1 of RX ring */
#define HP_16BSTOP_PG 0xFF /* Last page +1 of RX ring */
-int hpprobe(int ioaddr, struct device *dev);
+int hp_probe(struct device *dev);
int hpprobe1(int ioaddr, struct device *dev);
static void hp_reset_8390(struct device *dev);
@@ -59,17 +59,27 @@
Also initialize the card and fill in STATION_ADDR with the station
address. */
-int hpprobe(int ioaddr, struct device *dev)
+int hp_probe(struct device *dev)
{
int *port, ports[] = {0x300, 0x320, 0x340, 0x280, 0x2C0, 0x200, 0x240, 0};
+ short ioaddr = dev->base_addr;
+ if (ioaddr < 0)
+ return ENXIO; /* Don't probe at all. */
if (ioaddr > 0x100)
- return hpprobe1(ioaddr, dev);
+ return ! hpprobe1(ioaddr, dev);
- for (port = &ports[0]; *port; port++)
- if (inb_p(*port) != 0xff && hpprobe1(*port, dev))
- return dev->base_addr;
- return 0;
+ for (port = &ports[0]; *port; port++) {
+#ifdef HAVE_PORTRESERVE
+ if (check_region(*port, 32))
+ continue;
+#endif
+ if (inb_p(*port) != 0xff && hpprobe1(*port, dev)) {
+ return 0;
+ }
+ }
+ dev->base_addr = ioaddr;
+ return ENODEV;
}
int hpprobe1(int ioaddr, struct device *dev)
@@ -139,6 +149,10 @@
return 0;
}
}
+
+#ifdef HAVE_PORTRESERVE
+ snarf_region(ioaddr, 32);
+#endif
if (ei_debug > 1)
printk(version);
diff -u --recursive --new-file pl12/linux/net/inet/ip.c linux/net/inet/ip.c
--- pl12/linux/net/inet/ip.c Fri Aug 6 20:40:18 1993
+++ linux/net/inet/ip.c Sat Sep 4 00:00:14 1993
@@ -5,10 +5,11 @@
*
* The Internet Protocol (IP) module.
*
- * Version: @(#)ip.c 1.0.16 06/02/93
+ * Version: @(#)ip.c 1.0.16b 9/1/93
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
+ * Donald Becker, <becker@super.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -382,6 +383,27 @@
return(0);
}
+/* This is a version of ip_compute_csum() optimized for IP headers, which
+ always checksum on 4 octet boundaries. */
+static inline unsigned short
+ip_fast_csum(unsigned char * buff, int wlen)
+{
+ unsigned long sum = 0;
+ __asm__("\t clc\n"
+ "1:\n"
+ "\t lodsl\n"
+ "\t adcl %%eax, %%ebx\n"
+ "\t loop 1b\n"
+ "\t adcl $0, %%ebx\n"
+ "\t movl %%ebx, %%eax\n"
+ "\t shrl $16, %%eax\n"
+ "\t addw %%ax, %%bx\n"
+ "\t adcw $0, %%bx\n"
+ : "=b" (sum) , "=S" (buff)
+ : "0" (sum), "c" (wlen) ,"1" (buff)
+ : "ax", "cx", "si", "bx" );
+ return (~sum) & 0xffff;
+}
/*
* This routine does all the checksum computations that don't
@@ -429,23 +451,21 @@
return(sum & 0xffff);
}
-
-/* Check the header of an incoming IP datagram. */
+/* Check the header of an incoming IP datagram. This version is still used in slhc.c. */
int
ip_csum(struct iphdr *iph)
{
- if (iph->check == 0) return(0);
- if (ip_compute_csum((unsigned char *)iph, iph->ihl*4) == 0) return(0);
+ if (iph->check == 0 || ip_fast_csum((unsigned char *)iph, iph->ihl) == 0)
+ return(0);
return(1);
}
-
/* Generate a checksym for an outgoing IP datagram. */
static void
ip_send_check(struct iphdr *iph)
{
iph->check = 0;
- iph->check = ip_compute_csum((unsigned char *)iph, iph->ihl*4);
+ iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
}
@@ -554,21 +574,20 @@
int
ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
{
- struct iphdr *iph;
+ struct iphdr *iph = skb->h.iph;
unsigned char hash;
unsigned char flag = 0;
+ unsigned char opts_p = 0; /* Set iff the packet has options. */
struct inet_protocol *ipprot;
static struct options opt; /* since we don't use these yet, and they
take up stack space. */
int brd;
- iph = skb->h.iph;
- memset((char *) &opt, 0, sizeof(opt));
DPRINTF((DBG_IP, "<<\n"));
- ip_print(iph);
/* Is the datagram acceptable? */
- if (ip_csum(iph) || do_options(iph, &opt) || iph->version != 4) {
+ if (iph->version != 4
+ || (iph->check != 0 && ip_fast_csum((unsigned char *)iph, iph->ihl) !=0)) {
DPRINTF((DBG_IP, "\nIP: *** datagram error ***\n"));
DPRINTF((DBG_IP, " SRC = %s ", in_ntoa(iph->saddr)));
DPRINTF((DBG_IP, " DST = %s (ignored)\n", in_ntoa(iph->daddr)));
@@ -577,7 +596,15 @@
return(0);
}
- /* Do any IP forwarding required. */
+ if (iph->ihl != 5) { /* Fast path for the typical optionless IP packet. */
+ ip_print(iph); /* Bogus, only for debugging. */
+ memset((char *) &opt, 0, sizeof(opt));
+ if (do_options(iph, &opt) != 0)
+ return 0;
+ opts_p = 1;
+ }
+
+ /* Do any IP forwarding required. chk_addr() is expensive -- avoid it someday. */
if ((brd = chk_addr(iph->daddr)) == 0) {
#ifdef CONFIG_IP_FORWARD
ip_forward(skb, dev);
@@ -588,17 +615,12 @@
}
/*
- * Deal with fragments: not really...
- * Fragmentation is definitely a required part of IP (yeah, guys,
- * I read Linux-Activists.NET too :-), but the current "sk_buff"
- * allocation stuff doesn't make things simpler. When we're all
- * done cleaning up the mess, we'll add Ross Biro's "mbuf" stuff
- * to the code, which will replace the sk_buff stuff completely.
- * That will (a) make the code even cleaner, (b) allow me to do
- * the DDI (Device Driver Interface) the way I want to, and (c),
- * it will allow for easy addition of fragging. Any takers? -FvK
- */
- if ((iph->frag_off & 32) || (ntohs(iph->frag_off) & 0x1fff)) {
+ * Reassemble IP fragments. */
+
+ if ((iph->frag_off & 0x0020) || (ntohs(iph->frag_off) & 0x1fff)) {
+#ifdef CONFIG_IP_DEFRAG
+ ip_defrag(skb);
+#else
printk("\nIP: *** datagram fragmentation not yet implemented ***\n");
printk(" SRC = %s ", in_ntoa(iph->saddr));
printk(" DST = %s (ignored)\n", in_ntoa(iph->daddr));
@@ -606,6 +628,7 @@
skb->sk = NULL;
kfree_skb(skb, FREE_WRITE);
return(0);
+#endif
}
/* Point into the IP datagram, just past the header. */
@@ -646,7 +669,7 @@
* based on the datagram protocol. We should really
* check the protocol handler's return values here...
*/
- ipprot->handler(skb2, dev, &opt, iph->daddr,
+ ipprot->handler(skb2, dev, opts_p ? &opt : 0, iph->daddr,
(ntohs(iph->tot_len) - (iph->ihl * 4)),
iph->saddr, 0, ipprot);
diff -u --recursive --new-file pl12/linux/net/inet/lance.c linux/net/inet/lance.c
--- pl12/linux/net/inet/lance.c Fri Aug 13 04:56:54 1993
+++ linux/net/inet/lance.c Fri Sep 3 22:50:10 1993
@@ -7,13 +7,14 @@
distributed according to the terms of the GNU Public License,
incorporated herein by reference.
- This driver should work with the Allied Telesis 1500, and NE2100 clones.
+ This driver is for the Allied Telesis AT1500, and should work with
+ NE2100 clones.
The author may be reached as becker@super.org or
C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715
*/
-static char *version = "lance.c:v0.08 8/12/93 becker@super.org\n";
+static char *version = "lance.c:v0.12 9/3/93 becker@super.org\n";
#include <linux/config.h>
#include <linux/kernel.h>
@@ -22,6 +23,7 @@
/*#include <linux/interrupt.h>*/
#include <linux/ptrace.h>
#include <linux/errno.h>
+#include <linux/ioport.h>
#include <asm/io.h>
#include <asm/dma.h>
/*#include <asm/system.h>*/
@@ -32,12 +34,12 @@
#include "skbuff.h"
#include "arp.h"
+#ifndef HAVE_AUTOIRQ
/* From auto_irq.c, should be in a *.h file. */
extern void autoirq_setup(int waittime);
extern int autoirq_report(int waittime);
extern struct device *irq2dev_map[16];
-
-extern void printk_stats(struct enet_statistics *stats);
+#endif
#ifdef LANCE_DEBUG
int lance_debug = LANCE_DEBUG;
@@ -60,6 +62,7 @@
#define LANCE_ADDR 0x12
#define LANCE_RESET 0x14
#define LANCE_BUS_IF 0x16
+#define LANCE_TOTAL_SIZE 0x18
/* The LANCE Rx and Tx ring descriptors. */
struct lance_rx_head {
@@ -96,14 +99,17 @@
int pad0, pad1; /* Used for alignment */
};
-/* This is a temporary solution to the lack of a ethercard low-memory
- allocation scheme. We need it for bus-master or DMA ethercards if
- they are to work >16M memory systems. */
+/* We need a ethercard low-memory allocation scheme for for bus-master or
+ DMA ethercards if they are to work >16M memory systems. This is a
+ temporary solution to the lack of one, but it limits us to a single
+ AT1500 and <16M. Bummer. */
+
#define PKT_BUF_SZ 1550
static char rx_buffs[PKT_BUF_SZ][RING_SIZE];
-int at1500_init(int ioaddr, struct device *dev);
+int at1500_probe1(struct device *dev);
static int lance_open(struct device *dev);
+static void lance_init_ring(struct device *dev);
static int lance_start_xmit(struct sk_buff *skb, struct device *dev);
static int lance_rx(struct device *dev);
static void lance_interrupt(int reg_ptr);
@@ -119,33 +125,52 @@
int at1500_probe(struct device *dev)
{
int *port, ports[] = {0x300, 0x320, 0x340, 0x360, 0};
- int ioaddr = dev->base_addr;
-
- if (ioaddr > 0x100)
- return ! at1500_init(ioaddr, dev);
+ int base_addr = dev->base_addr;
+ if (base_addr < 0)
+ return ENXIO; /* Don't probe at all. */
+ if (base_addr > 0x100) /* Check a single specified location. */
+ return at1500_probe1(dev);
+
+ /* First probe for the ethercard ID, 0x57, and then look for a LANCE
+ chip. */
+
for (port = &ports[0]; *port; port++) {
- /* Probe for the Allied-Telesys vendor ID. This will not detect
- other NE2100-like ethercards, which must use a hard-wired ioaddr.
- There must be a better way to detect a LANCE... */
- int ioaddr = *port;
- if (inb(ioaddr) != 0x00
- || inb(ioaddr+1) != 0x00
- || inb(ioaddr+2) != 0xF4)
+ int probe_addr = *port;
+ short temp;
+
+#ifdef HAVE_PORTRESERVE
+ if (check_region(probe_addr, LANCE_TOTAL_SIZE))
+ continue;
+#endif
+ if (inb(probe_addr + 14) != 0x57
+ || inb(probe_addr + 15) != 0x57)
+ continue;
+
+ /* Reset the LANCE. Un-Reset needed only for the real NE2100. */
+ temp = inw(probe_addr+LANCE_RESET); /* Reset the LANCE */
+ outw(temp, probe_addr+LANCE_RESET); /* "Un-reset" */
+
+ outw(0x0000, probe_addr+LANCE_ADDR); /* Switch to window 0 */
+ if (inw(probe_addr+LANCE_DATA) != 0x0004)
continue;
- if (at1500_init(ioaddr, dev))
+ dev->base_addr = probe_addr;
+ if (at1500_probe1(dev) == 0)
return 0;
}
- return 1; /* ENODEV would be more accurate. */
+
+ dev->base_addr = base_addr;
+ return ENODEV; /* ENODEV would be more accurate. */
}
int
-at1500_init(int ioaddr, struct device *dev)
+at1500_probe1(struct device *dev)
{
struct lance_private *lp;
+ short ioaddr = dev->base_addr;
+
int i;
- dev->base_addr = ioaddr;
printk("%s: LANCE at %#3x, address", dev->name, ioaddr);
/* There is a 16 byte station address PROM at the base address.
@@ -163,12 +188,16 @@
if ((int)dev->priv & 0xff000000 || (int) rx_buffs & 0xff000000) {
printk(" disabled (buff %#x > 16M).\n", (int)rx_buffs);
- return 0;
+ return -ENOMEM;
}
memset(dev->priv, 0, sizeof(struct lance_private));
lp = (struct lance_private *)dev->priv;
+ if ((int)(lp->rx_ring) & 0x07)
+ printk("%s: LANCE Rx and Tx rings not on even boundary.\n",
+ dev->name);
+
/* Un-Reset the LANCE, needed only for the NE2100. */
outw(0, ioaddr+LANCE_RESET);
@@ -199,11 +228,14 @@
printk(", using IRQ %d.\n", dev->irq);
else {
printk(", failed to detect IRQ line.\n");
- return 0;
+ return -EAGAIN;
}
} else
printk(" assigned IRQ %d.\n", dev->irq);
+ /* The DMA channel may be passed in on this parameter. */
+ dev->dma = dev->mem_start & 0x07;
+
#ifndef NE2100 /* The NE2100 might not understand */
/* Turn on auto-select of media (10baseT or BNC) so that the user
can watch the LEDs even if the board isn't opened. */
@@ -211,9 +243,9 @@
outw(0x0002, ioaddr+LANCE_BUS_IF);
#endif
- if ((int)(lp->rx_ring) & 0x07)
- printk("%s: LANCE Rx and Tx rings not on even boundary.\n",
- dev->name);
+#ifdef HAVE_PORTRESERVE
+ snarf_region(ioaddr, LANCE_TOTAL_SIZE);
+#endif
if (lance_debug > 0)
printk(version);
@@ -225,7 +257,6 @@
dev->get_stats = &lance_get_stats;
dev->mem_start = 0;
- dev->rmem_end = 0x00ffffff; /* Bogus, needed for dev_rint(). */
/* Fill in the generic field of the device structure. */
for (i = 0; i < DEV_NUMBUFFS; i++)
@@ -253,7 +284,7 @@
dev->pa_mask = 0;
dev->pa_alen = sizeof(unsigned long);
- return ioaddr;
+ return 0;
}
@@ -268,8 +299,7 @@
return -EAGAIN;
}
- if (lp->dma < 1)
- lp->dma = DEFAULT_DMA;
+ lp->dma = dev->dma ? dev->dma : DEFAULT_DMA;
if (request_dma(lp->dma)) {
free_irq(dev->irq);
@@ -287,7 +317,8 @@
/* Un-Reset the LANCE, needed only for the NE2100. */
outw(0, ioaddr+LANCE_RESET);
-#ifndef NE2100 /* The NE2100 might not understand */
+#ifndef NE2100
+ /* This is really 79C960-specific, NE2100 might not understand */
/* Turn on auto-select of media (10baseT or BNC). */
outw(0x0002, ioaddr+LANCE_ADDR);
outw(0x0002, ioaddr+LANCE_BUS_IF);
@@ -298,23 +329,7 @@
dev->name, dev->irq, lp->dma, lp->tx_ring, lp->rx_ring,
&lp->init_block);
- lp->cur_rx = lp->cur_tx = 0;
- lp->dirty_rx = lp->dirty_tx = 0;
-
- for (i = 0; i < RING_SIZE; i++) {
- lp->rx_ring[i].base = (int)rx_buffs | 0x80000000 + i*PKT_BUF_SZ;
- lp->rx_ring[i].buf_length = -PKT_BUF_SZ;
- lp->tx_ring[i].base = 0;
- }
-
- lp->init_block.mode = 0x0000;
- for (i = 0; i < 6; i++)
- lp->init_block.phys_addr[i] = dev->dev_addr[i];
- lp->init_block.filter[0] = 0x00000000;
- lp->init_block.filter[1] = 0x00000000;
- lp->init_block.rx_ring = (int)lp->rx_ring | RING_LEN_BITS;
- lp->init_block.tx_ring = (int)lp->tx_ring | RING_LEN_BITS;
-
+ lance_init_ring(dev);
/* Re-initialize the LANCE, and start it when done. */
outw(0x0001, ioaddr+LANCE_ADDR);
outw((short) &lp->init_block, ioaddr+LANCE_DATA);
@@ -343,6 +358,31 @@
return 0; /* Always succeed */
}
+/* Initialize the LANCE Rx and Tx rings. */
+static void
+lance_init_ring(struct device *dev)
+{
+ struct lance_private *lp = (struct lance_private *)dev->priv;
+ int i;
+
+ lp->cur_rx = lp->cur_tx = 0;
+ lp->dirty_rx = lp->dirty_tx = 0;
+
+ for (i = 0; i < RING_SIZE; i++) {
+ lp->rx_ring[i].base = (int)rx_buffs | 0x80000000 + i*PKT_BUF_SZ;
+ lp->rx_ring[i].buf_length = -PKT_BUF_SZ;
+ lp->tx_ring[i].base = 0;
+ }
+
+ lp->init_block.mode = 0x0000;
+ for (i = 0; i < 6; i++)
+ lp->init_block.phys_addr[i] = dev->dev_addr[i];
+ lp->init_block.filter[0] = 0x00000000;
+ lp->init_block.filter[1] = 0x00000000;
+ lp->init_block.rx_ring = (int)lp->rx_ring | RING_LEN_BITS;
+ lp->init_block.tx_ring = (int)lp->tx_ring | RING_LEN_BITS;
+}
+
static int
lance_start_xmit(struct sk_buff *skb, struct device *dev)
{
@@ -352,18 +392,16 @@
/* Transmitter timeout, serious problems. */
if (dev->tbusy) {
int tickssofar = jiffies - dev->trans_start;
- int entry = lp->cur_tx++;
if (tickssofar < 5)
return 1;
outw(0, ioaddr+LANCE_ADDR);
- printk("%s: transmit timed out, status %4.4x.\n", dev->name,
- inw(ioaddr+LANCE_DATA));
+ printk("%s: transmit timed out, status %4.4x, resetting.\n",
+ dev->name, inw(ioaddr+LANCE_DATA));
- if (lp->tx_ring[(entry+1) & RING_MOD_MASK].base >= 0)
- dev->tbusy=0;
- else
- outw(0x00, ioaddr+LANCE_DATA),
- outw(0x43, ioaddr+LANCE_DATA);;
+ lance_init_ring(dev);
+ outw(0x43, ioaddr+LANCE_DATA);
+
+ dev->tbusy=0;
dev->trans_start = jiffies;
return 0;
@@ -446,7 +484,7 @@
lance_interrupt(int reg_ptr)
{
int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2);
- struct device *dev = irq2dev_map[irq];
+ struct device *dev = (struct device *)(irq2dev_map[irq]);
struct lance_private *lp;
int csr0, ioaddr;
@@ -510,6 +548,7 @@
kfree_skb (skb-1, FREE_WRITE);
dirty_tx = ++lp->dirty_tx & RING_MOD_MASK;
}
+ /* mark_bh(INET_BH); */
}
/* Clear the interrupts we've handled. */
@@ -531,21 +570,10 @@
struct lance_private *lp = (struct lance_private *)dev->priv;
int entry = lp->cur_rx & RING_MOD_MASK;
- /* Check to see if we own this entry. */
+ /* If we own the next entry, it's a new packet. Send it up. */
while (lp->rx_ring[entry].base >= 0) {
int status = lp->rx_ring[entry].base >> 24;
- if (lance_debug > 5) {
- unsigned char *pkt =
- (unsigned char *)(lp->rx_ring[entry].base & 0x00ffffff);
- printk("%s: Rx packet at ring entry %d, len %d status %2.2x.\n",
- dev->name, entry, lp->rx_ring[entry].msg_length,
- lp->rx_ring[entry].base >> 24);
- printk("%s: Rx %2.2x %2.2x %2.2x ... %2.2x %2.2x %2.2x %2.2x...%2.2x len %2.2x %2.2x %2.2x %2.2x.\n",
- dev->name, pkt[0], pkt[1], pkt[2], pkt[5], pkt[6],
- pkt[7], pkt[8], pkt[11], pkt[12], pkt[13],
- pkt[14], pkt[15]);
- }
- /* If so, copy it to the upper layers. */
+
if (status & 0x40) { /* There was an error. */
lp->stats.rx_errors++;
if (status & 0x20) lp->stats.rx_frame_errors++;
@@ -553,12 +581,33 @@
if (status & 0x08) lp->stats.rx_crc_errors++;
if (status & 0x04) lp->stats.rx_fifo_errors++;
} else {
- if (dev_rint((unsigned char *)(lp->rx_ring[entry].base
- & 0x00ffffff),
- lp->rx_ring[entry].msg_length, 0, dev)) {
+ /* Malloc up new buffer, compatible with net-2e. */
+ short pkt_len = lp->rx_ring[entry].msg_length;
+ int sksize = sizeof(struct sk_buff) + pkt_len;
+ struct sk_buff *skb;
+ skb = (struct sk_buff *) kmalloc(sksize, GFP_ATOMIC);
+ if (skb == NULL) {
+ printk("%s: Memory squeeze, deferring packet.\n", dev->name);
+ lp->stats.rx_dropped++; /* Really, deferred. */
+ break;
+ }
+ skb->mem_len = sksize;
+ skb->mem_addr = skb;
+ skb->len = pkt_len;
+ skb->dev = dev;
+ memcpy((unsigned char *) (skb + 1),
+ (unsigned char *)(lp->rx_ring[entry].base & 0x00ffffff),
+ pkt_len);
+#ifdef HAVE_NETIF_RX
+ netif_rx(skb);
+#else
+ skb->lock = 0;
+ if (dev_rint((unsigned char*)skb, pkt_len, IN_SKBUFF, dev) != 0) {
+ kfree_s(skb, sksize);
lp->stats.rx_dropped++;
break;
}
+#endif
lp->stats.rx_packets++;
}
@@ -565,6 +614,10 @@
lp->rx_ring[entry].base |= 0x80000000;
entry = (entry+1) & RING_MOD_MASK;
}
+
+ /* We should check that at least two ring entries are free. If not,
+ we should free one and mark stats->rx_dropped++. */
+
lp->cur_rx = entry;
return 0;
@@ -587,10 +640,6 @@
if (lance_debug > 1)
printk("%s: Shutting down ethercard, status was %2.2x.\n",
dev->name, inw(ioaddr+LANCE_DATA));
-#ifdef PRINTK_STATS
- if (lance_debug > 2)
- printk_stats(&lp->stats);
-#endif
/* We stop the LANCE here -- it occasionally polls
memory if we don't. */
diff -u --recursive --new-file pl12/linux/net/inet/loopback.c linux/net/inet/loopback.c
--- pl12/linux/net/inet/loopback.c Sat Jul 31 15:42:22 1993
+++ linux/net/inet/loopback.c Fri Aug 20 17:58:22 1993
@@ -5,10 +5,11 @@
*
* Pseudo-driver for the loopback interface.
*
- * Version: @(#)loopback.c 1.0.4 05/25/93
+ * Version: @(#)loopback.c 1.0.4b 08/16/93
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
+ * Donald Becker, <becker@super.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -30,6 +31,7 @@
#include <linux/errno.h>
#include <linux/fcntl.h>
#include <linux/in.h>
+#include <linux/if_ether.h> /* For the statistics structure. */
#include "inet.h"
#include "dev.h"
#include "eth.h"
@@ -44,6 +46,7 @@
static int
loopback_xmit(struct sk_buff *skb, struct device *dev)
{
+ struct enet_statistics *stats = (struct enet_statistics *)dev->priv;
int done;
DPRINTF((DBG_LOOPB, "loopback_xmit(dev=%X, skb=%X)\n", dev, skb));
@@ -52,17 +55,27 @@
cli();
if (dev->tbusy != 0) {
sti();
+ stats->tx_errors++;
return(1);
}
dev->tbusy = 1;
sti();
- done = dev_rint((unsigned char *)(skb+1), skb->len, 0, dev);
- if (skb->free) kfree_skb(skb, FREE_WRITE);
+ skb->lock = 0;
- while (done != 1) {
- done = dev_rint(NULL, 0, 0, dev);
- }
+ stats->tx_packets++;
+
+ /* Copy the packet only if it isn't marked as free. */
+
+ done = dev_rint((unsigned char *)(skb->free ? skb : skb + 1), skb->len,
+ skb->free ? IN_SKBUFF : 0, dev);
+
+ if (done != 0)
+ stats->rx_errors++;
+ else
+ stats->rx_packets++;
+
+
dev->tbusy = 0;
#if 1
@@ -83,6 +96,11 @@
return(0);
}
+static struct enet_statistics *
+get_stats(struct device *dev)
+{
+ return (struct enet_statistics *)dev->priv;
+}
/* Initialize the rest of the LOOPBACK device. */
int
@@ -118,6 +136,9 @@
dev->pa_brdaddr = in_aton("127.255.255.255");
dev->pa_mask = in_aton("255.0.0.0");
dev->pa_alen = sizeof(unsigned long);
-
+ dev->priv = kmalloc(sizeof(struct enet_statistics), GFP_KERNEL);
+ memset(dev->priv, 0, sizeof(struct enet_statistics));
+ dev->get_stats = get_stats;
+
return(0);
};
diff -u --recursive --new-file pl12/linux/net/inet/ne.c linux/net/inet/ne.c
--- pl12/linux/net/inet/ne.c Fri Aug 13 05:57:28 1993
+++ linux/net/inet/ne.c Mon Aug 30 23:35:36 1993
@@ -17,11 +17,12 @@
/* Routines for the NatSemi-based designs (NE[12]000). */
static char *version =
- "ne.c:v0.99-12B 8/12/93 Donald Becker (becker@super.org)\n";
+ "ne.c:v0.99-13 8/30/93 Donald Becker (becker@super.org)\n";
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
+#include <linux/errno.h>
#include <asm/system.h>
#include <asm/io.h>
#ifndef port_read
@@ -41,7 +42,7 @@
#define NESM_START_PG 0x40 /* First page of TX buffer */
#define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */
-int neprobe(int ioaddr, struct device *dev);
+int ne_probe(struct device *dev);
static int neprobe1(int ioaddr, struct device *dev, int verbose);
static void ne_reset_8390(struct device *dev);
@@ -72,17 +73,28 @@
E2010 starts at 0x100 and ends at 0x4000.
E2010-x starts at 0x100 and ends at 0xffff. */
-int neprobe(int ioaddr, struct device *dev)
+int ne_probe(struct device *dev)
{
int *port, ports[] = {0x300, 0x280, 0x320, 0x340, 0x360, 0};
+ short ioaddr = dev->base_addr;
+ if (ioaddr < 0)
+ return ENXIO; /* Don't probe at all. */
if (ioaddr > 0x100)
- return neprobe1(ioaddr, dev, 1);
+ return ! neprobe1(ioaddr, dev, 1);
- for (port = &ports[0]; *port; port++)
- if (inb_p(*port) != 0xff && neprobe1(*port, dev, 0))
- return dev->base_addr = *port;
- return 0;
+ for (port = &ports[0]; *port; port++) {
+#ifdef HAVE_PORTRESERVE
+ if (check_region(*port, 32))
+ continue;
+#endif
+ if (inb_p(*port) != 0xff && neprobe1(*port, dev, 0)) {
+ dev->base_addr = *port;
+ return 0;
+ }
+ }
+ dev->base_addr = ioaddr;
+ return ENODEV;
}
static int neprobe1(int ioaddr, struct device *dev, int verbose)
@@ -216,12 +228,15 @@
}
}
- printk("\n%s: %s found at %#x, using IRQ %d.\n",
- dev->name, name, ioaddr, dev->irq);
-
dev->base_addr = ioaddr;
+#ifdef HAVE_PORTRESERVE
+ snarf_region(ioaddr, 32);
+#endif
+
ethdev_init(dev);
+ printk("\n%s: %s found at %#x, using IRQ %d.\n",
+ dev->name, name, ioaddr, dev->irq);
if (ei_debug > 0)
printk(version);
diff -u --recursive --new-file pl12/linux/net/inet/route.c linux/net/inet/route.c
--- pl12/linux/net/inet/route.c Sat Aug 7 18:36:52 1993
+++ linux/net/inet/route.c Fri Aug 20 01:18:19 1993
@@ -219,8 +219,10 @@
dev = dev_check(((struct sockaddr_in *) &r->rt_dst)->sin_addr.s_addr);
else
if ((rt = rt_route(((struct sockaddr_in *) &r->rt_gateway)->sin_addr.
- s_addr,NULL))) dev = rt->rt_dev;
- else dev = NULL;
+ s_addr,NULL)))
+ dev = rt->rt_dev;
+ else
+ dev = NULL;
DPRINTF((DBG_RT, "RT: dev for %s gw ",
in_ntoa((*(struct sockaddr_in *)&r->rt_dst).sin_addr.s_addr)));
@@ -258,12 +260,14 @@
pos = buffer;
- pos += sprintf(pos, "Iface\tDestination\tGateway \tFlags\tRefCnt\tUse\n");
+ pos += sprintf(pos,
+ "Iface\tDestination\tGateway \tFlags\tRefCnt\tUse\tMetric\n");
+ /* This isn't quite right -- r->rt_dst is a struct! */
for (r = rt_base; r != NULL; r = r->rt_next) {
- pos += sprintf(pos, "%s\t%08X\t%08X\t%02X\t%d\t%d\n",
+ pos += sprintf(pos, "%s\t%08X\t%08X\t%02X\t%d\t%d\t%d\n",
r->rt_dev->name, r->rt_dst, r->rt_gateway,
- r->rt_flags, r->rt_refcnt, r->rt_use);
+ r->rt_flags, r->rt_refcnt, r->rt_use, r->rt_metric);
}
return(pos - buffer);
}
@@ -317,7 +321,9 @@
int
rt_ioctl(unsigned int cmd, void *arg)
{
+ struct device *dev;
struct rtentry rt;
+ char namebuf[32];
int ret;
switch(cmd) {
@@ -325,16 +331,17 @@
ret = dbg_ioctl(arg, DBG_RT);
break;
case SIOCADDRT:
- if (!suser()) return(-EPERM);
- verify_area(VERIFY_WRITE, arg, sizeof(struct rtentry));
- memcpy_fromfs(&rt, arg, sizeof(struct rtentry));
- ret = rt_new(&rt);
- break;
case SIOCDELRT:
if (!suser()) return(-EPERM);
verify_area(VERIFY_WRITE, arg, sizeof(struct rtentry));
memcpy_fromfs(&rt, arg, sizeof(struct rtentry));
- ret = rt_kill(&rt);
+ if (rt.rt_dev) {
+ verify_area(VERIFY_WRITE, rt.rt_dev, sizeof namebuf);
+ memcpy_fromfs(&namebuf, rt.rt_dev, sizeof namebuf);
+ dev = dev_get(namebuf);
+ rt.rt_dev = dev;
+ }
+ ret = (cmd == SIOCDELRT) ? rt_kill(&rt) : rt_new(&rt);
break;
default:
ret = -EINVAL;
diff -u --recursive --new-file pl12/linux/net/inet/slip.c linux/net/inet/slip.c
--- pl12/linux/net/inet/slip.c Sat Jul 31 15:42:22 1993
+++ linux/net/inet/slip.c Thu Aug 19 09:46:23 1993
@@ -688,7 +688,7 @@
if (already++ == 0) {
printk("SLIP: version %s (%d channels): ",
SLIP_VERSION, SL_NRUNIT);
-
+ printk("CSLIP code copyright 1989 Regents of the University of California\n");
/* Fill in our LDISC request block. */
sl_ldisc.flags = 0;
sl_ldisc.open = slip_open;
diff -u --recursive --new-file pl12/linux/net/inet/sock.c linux/net/inet/sock.c
--- pl12/linux/net/inet/sock.c Sat Jul 31 15:42:22 1993
+++ linux/net/inet/sock.c Wed Aug 18 19:19:51 1993
@@ -967,6 +967,8 @@
sti();
return(-EADDRINUSE);
}
+ if (sk2->num != snum) continue; /* more than one */
+ if (sk2->saddr != sk->saddr) continue; /* socket per slot ! -FB */
if (!sk2->reuse) {
sti();
return(-EADDRINUSE);
diff -u --recursive --new-file pl12/linux/net/inet/tcp.c linux/net/inet/tcp.c
--- pl12/linux/net/inet/tcp.c Wed Aug 11 20:41:15 1993
+++ linux/net/inet/tcp.c Wed Aug 18 19:20:37 1993
@@ -1434,6 +1434,7 @@
t1->source = th->dest;
t1->seq = th->ack_seq; /* add one so it will be in the right range */
t1->rst = 1;
+ t1->ack_seq = ntohl(ntohl(th->seq)+1); /* send correct ack -FB */
t1->window = 0; /* should be set to 0 -FB */
t1->ack = 0;
t1->syn = 0;
diff -u --recursive --new-file pl12/linux/net/inet/wd.c linux/net/inet/wd.c
--- pl12/linux/net/inet/wd.c Fri Aug 13 04:24:28 1993
+++ linux/net/inet/wd.c Mon Aug 30 23:40:32 1993
@@ -15,11 +15,12 @@
*/
static char *version =
- "wd.c:v0.99-12 8/12/93 Donald Becker (becker@super.org)\n";
+ "wd.c:v0.99-13 8/30/93 Donald Becker (becker@super.org)\n";
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
+#include <linux/errno.h>
#include <asm/io.h>
#include <asm/system.h>
#include <memory.h>
@@ -59,19 +60,28 @@
The wdprobe1() routine initializes the card and fills the
station address field. */
-int wdprobe(int ioaddr, struct device *dev)
+int wd_probe(struct device *dev)
{
int *port, ports[] = {0x300, 0x280, 0x380, 0x240, 0};
+ short ioaddr = dev->base_addr;
+ if (ioaddr < 0)
+ return ENXIO; /* Don't probe at all. */
if (ioaddr > 0x100)
- return wdprobe1(ioaddr, dev);
+ return ! wdprobe1(ioaddr, dev);
- for (port = &ports[0]; *port; port++)
+ for (port = &ports[0]; *port; port++) {
+#ifdef HAVE_PORTRESERVE
+ if (check_region(*port, 32))
+ continue;
+#endif
if (inb(*port + 8) != 0xff
&& inb(*port + 9) != 0xff /* Extra check to avoid soundcard. */
&& wdprobe1(*port, dev))
- return *port;
- return 0;
+ return 0;
+ }
+ dev->base_addr = ioaddr;
+ return ENODEV;
}
int wdprobe1(int ioaddr, struct device *dev)
@@ -93,7 +103,7 @@
printk(" %2.2X", station_addr[i] = inb(ioaddr + 8 + i));
/* The following PureData probe code was contributed by
- Mike Jagdis <jaggy@purplet.demon.co.uk>. Puredata seem to do software
+ Mike Jagdis <jaggy@purplet.demon.co.uk>. Puredata does software
configuration differently from others so we have to check for them.
This detects an 8 bit, 16 bit or dumb (Toshiba, jumpered) card.
*/
@@ -192,6 +202,9 @@
}
/* OK, were are certain this is going to work. Setup the device. */
+#ifdef HAVE_PORTRESERVE
+ snarf_region(ioaddr, 32);
+#endif
ethdev_init(dev);
ei_status.name = model_name;
@@ -231,8 +244,9 @@
ei_status.reg5 = ((dev->mem_start>>19) & 0x1f) | NIC16;
if (ei_status.word16)
- outb(ISA16 | ei_status.reg5, ioaddr+WD_CMDREG5);
+ outb(ei_status.reg5, ioaddr+WD_CMDREG5);
outb(ei_status.reg0, ioaddr); /* WD_CMDREG */
+
return ei_open(dev);
}
@@ -273,7 +287,8 @@
}
/* Block input and output are easy on shared memory ethercards, and trivial
- on the Western digital card where there is no choice of how to do it. */
+ on the Western digital card where there is no choice of how to do it.
+ The only complication is if the ring buffer wraps. */
static int
wd_block_input(struct device *dev, int count, char *buf, int ring_offset)
@@ -281,7 +296,7 @@
void *xfer_start = (void *)(dev->mem_start + ring_offset
- (WD_START_PG<<8));
- /* This mapout won't be necessary when wd_close_card is called. */
+ /* This mapout isn't necessary if wd_close_card is called. */
#if !defined(WD_no_mapout)
int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */
@@ -299,12 +314,6 @@
return dev->rmem_start + count;
}
memcpy(buf, xfer_start, count);
- if (ei_debug > 4) {
- unsigned short *board = (unsigned short *) xfer_start;
- printk("%s: wd8013 block_input(cnt=%d offset=%3x addr=%#x) = %2x %2x %2x...\n",
- dev->name, count, ring_offset, xfer_start,
- board[-1], board[0], board[1]);
- }
#if !defined(WD_no_mapout)
/* Turn off 16 bit access so that reboot works. */
@@ -314,8 +323,6 @@
return ring_offset + count;
}
-/* This could only be outputting to the transmit buffer. The
- ping-pong transmit setup doesn't work with this yet. */
static void
wd_block_output(struct device *dev, int count, const unsigned char *buf,
int start_page)
@@ -332,9 +339,6 @@
#endif
memcpy(shmem, buf, count);
- if (ei_debug > 4)
- printk("%s: wd80*3 block_output(addr=%#x cnt=%d) -> %2x=%2x %2x=%2x %d...\n",
- shmem, count, shmem[23], buf[23], shmem[24], buf[24], memcmp(shmem,buf,count));
#if !defined(WD_no_mapout)
/* Turn off 16 bit access so that reboot works. */
diff -u --recursive --new-file pl12/linux/net/socket.c linux/net/socket.c
--- pl12/linux/net/socket.c Wed Jul 7 10:39:58 1993
+++ linux/net/socket.c Sat Sep 4 02:45:52 1993
@@ -806,7 +806,7 @@
* we have this level of indirection. Not a lot of overhead, since more of
* the work is done via read/write/select directly.
*/
-extern "C" int
+asmlinkage int
sys_socketcall(int call, unsigned long *args)
{
switch(call) {
diff -u --recursive --new-file pl12/linux/net/unix/sock.c linux/net/unix/sock.c
--- pl12/linux/net/unix/sock.c Mon Aug 9 18:02:33 1993
+++ linux/net/unix/sock.c Sat Sep 4 14:02:42 1993
@@ -737,7 +737,7 @@
if (UN_BUF_AVAIL(upd) || peerupd)
put_fs_long(UN_BUF_AVAIL(upd),(unsigned long *)arg);
else
- put_fs_long(1,(unsigned long *)arg); /* read EOF */
+ put_fs_long(0,(unsigned long *)arg);
break;
case TIOCOUTQ:
if (sock->flags & SO_ACCEPTCON) return(-EINVAL);