| 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, ð3_dev, ethif_probe }; |
| +static struct device eth1_dev = { |
| + "eth1", 0,0,0,0,0xffe0 /* I/O base*/, 0,0,0,0, ð2_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, ð1_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 (ð0_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); |