From f41aeca9ff06b9deef948cd4520460c53b9ae811 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 14 Sep 1993 16:47:10 +0000 Subject: [PATCH] Release 0.4.0 Mon Sep 13 05:00:11 1993 Eric Youngdale * [Makefile] [if1632/relay.c] [include/dlls.h] [selector.c] [loader/wine.c] [tools/build.c] Added ability to generate missing functions statistics. Mon Sep 13 12:09:47 1993 Scott A. Laird (scott@curly) * [WIN31-APPLETS] Added new file. * [if1632/kernel.spec] Added definitions for GetProfile{Int,String} and SetHandleCount. * [if1632/keyboard.spec] Created interface specification for Keyboard driver DLL. * [if1632/relay.c] Added keyboard.dll to list of included DLLs. * [if1632/user.spec] Added LoadAccelerators definition. * [loader/resource.c] Added LoadAccelerators stub. * [misc/file.c] Changed OpenFile, and added SetHandleCount (for winfile.exe) * [misc/keyboard.c] Added keyboard code. * [misc/profile.c] [misc/xt.c] Moved GetPrivateProfile* commands here, and added GetProfile* commands. Mon Sep 13 10:24:37 1993 Andrew Bulhak * [windows/utility.c] Implemented MulDiv(), OutputDebugString() and wvsprintf() Fri Sep 10 09:13:30 1993 John Brezak * [*/Makefile] Created patch to allow BSD make to build wine. * [windows/win.c] Fixed NULL pointer reference. * [windows/message.c] [misc/xt.c] Defined HZ to handle system specific timing. * [windows/graphics.c] Use M_PI is PI * [objects/pallete.c] NetBSD does not have /usr/include/values.h and MAXINT is INT_MAX. * [dump.c] [ldt.c] [wine.c] ifdef'ed linux headers for linux compile. * [loader/ldtlib.c] Add NetBSD system calls when compiled on that system. * [loader/selector.c] Use mmap(MAP_ANON, ...) for NetBSD. * [if1632/call.S] Fixed selector assumptions. Thu Sep 9 20:01:37 1993 David Metcalfe * [controls/WinButton*] [controls/button.c] [controls/widget.c] [windows/win.c] [windows/class.c] Added 3D button control and tied into CreateWindow() Thu Sep 9 07:35:24 1993 Scott Laird * [if1632/sound.spec] Created interface specification for SOUND DLL. * [if1632/win87em.spec] Added more functions to the WIN87EM DLL interface specification * [misc/emulate.c] Created stubs for the new math emulation functions. * [misc/sound.c] Created stubs for the SOUND DLL. Sun Sep 5 21:02:10 1993 John Burton * [if1632/kernel.spec] Added interface specifications for OpenFile, _lclose, _lread, _lopen, and _lwrite. * [include/windows.h] Added OF_ macros * [misc/file.c] Implemented OpenFile, _lclose, _lread, _lopen and _lwrite. Fri Sep 3 18:47:03 1993 Alexandre Julliard * [windows/dc.c] Bug fix * [objects/text.c] Bug fix Fri Sep 3 18:47:03 1993 Bob Amstadt * [objects/linedda.c] Finished LineDDA(). --- ALPHA-diffs | 1419 -------- ALPHA-pl13.diff | 7864 +++++++++++++++++++++++++++++++++++++++++ ChangeLog | 115 + README | 37 +- WIN31-APPLETS | 45 + bsdmake.patch | 147 + controls/Makefile | 4 +- controls/WinButton.c | 605 ++++ controls/WinButton.h | 109 + controls/WinButtonP.h | 123 + controls/button.c | 86 + controls/widgets.c | 27 +- if1632/Makefile | 15 +- if1632/call.S | 18 +- if1632/gdi.spec | 1 + if1632/kernel.spec | 11 +- if1632/keyboard.spec | 27 + if1632/relay.c | 43 +- if1632/shell.spec | 2 +- if1632/sound.spec | 17 + if1632/user.spec | 2 + if1632/win87em.spec | 6 + include/dlls.h | 5 + include/neexe.h | 1 + include/windows.h | 40 + loader/dump.c | 2 + loader/ldt.c | 26 +- loader/ldtlib.c | 71 + loader/resource.c | 12 + loader/selector.c | 118 +- loader/wine.c | 24 +- misc/Makefile | 3 +- misc/emulate.c | 53 + misc/file.c | 208 ++ misc/keyboard.c | 109 + misc/profile.c | 40 + misc/sound.c | 75 + misc/xt.c | 18 +- objects/linedda.c | 31 +- objects/palette.c | 6 + objects/text.c | 10 +- signal-diffs | 90 - test/btnlook.c | 147 + test/btnlook.exe | Bin 0 -> 11827 bytes tools/Makefile | 8 +- tools/build.c | 21 +- windows/Makefile | 2 +- windows/class.c | 2 +- windows/dc.c | 1 - windows/graphics.c | 3 + windows/message.c | 4 + windows/utility.c | 304 ++ windows/win.c | 93 +- 53 files changed, 10624 insertions(+), 1626 deletions(-) delete mode 100644 ALPHA-diffs create mode 100644 ALPHA-pl13.diff create mode 100644 WIN31-APPLETS create mode 100644 bsdmake.patch create mode 100644 controls/WinButton.c create mode 100644 controls/WinButton.h create mode 100644 controls/WinButtonP.h create mode 100644 controls/button.c create mode 100644 if1632/keyboard.spec create mode 100644 if1632/sound.spec create mode 100644 misc/emulate.c create mode 100644 misc/file.c create mode 100644 misc/keyboard.c create mode 100644 misc/profile.c create mode 100644 misc/sound.c delete mode 100644 signal-diffs create mode 100755 test/btnlook.c create mode 100755 test/btnlook.exe create mode 100644 windows/utility.c diff --git a/ALPHA-diffs b/ALPHA-diffs deleted file mode 100644 index 1bc93961f8f..00000000000 --- a/ALPHA-diffs +++ /dev/null @@ -1,1419 +0,0 @@ -diff -u --recursive --new-files pl12/linux/config.in linux/config.in ---- pl12/linux/config.in Sun Aug 15 11:24:56 1993 -+++ linux/config.in Sat Aug 21 10:51:27 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 -diff -u --recursive --new-files 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-files pl12/linux/fs/binfmt_elf.c linux/fs/binfmt_elf.c ---- pl12/linux/fs/binfmt_elf.c -+++ linux/fs/binfmt_elf.c Fri Aug 20 08:59:30 1993 -@@ -0,0 +1,358 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+extern "C" int sys_exit(int exit_code); -+extern "C" int sys_close(unsigned fd); -+extern "C" 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 -+ -+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->bmap || -+ !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) -+ 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) 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) { -+ 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; ip_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) -+ 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-files 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 Fri Aug 20 08:59:31 1993 -@@ -50,7 +50,7 @@ - - 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; -@@ -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; -@@ -649,6 +649,7 @@ - } - } - -+ bprm.sh_bang = sh_bang; - fmt = formats; - do { - int (*fn)(struct linux_binprm *, struct pt_regs *) = fmt->load_binary; -@@ -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; - }; -@@ -818,6 +834,8 @@ - return -ENOEXEC; - } - -+ if (N_FLAGS(ex)) return -ENOEXEC; -+ - /* Now use mmap to map the library into memory. */ - error = do_mmap(file, ex.a_entry, ex.a_text + ex.a_data, - PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE, -diff -u --recursive --new-files 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 Thu Aug 19 10:04:52 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-files 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-files 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-files 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 Tue Aug 17 23:40:11 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 -@@ -376,6 +376,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; - } -diff -u --recursive --new-files 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-files 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 Tue Aug 17 23:40:11 1993 -@@ -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; -diff -u --recursive --new-files 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-files 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-files 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 Fri Aug 20 08:59:31 1993 -@@ -15,6 +15,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 +32,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-files pl12/linux/include/linux/elf.h linux/include/linux/elf.h ---- pl12/linux/include/linux/elf.h -+++ linux/include/linux/elf.h Fri Aug 20 08:59:31 1993 -@@ -0,0 +1,306 @@ -+#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 -+#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-files 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-files 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-files 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-files 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 Thu Aug 19 18:45:38 1993 -@@ -584,6 +584,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-files 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-files 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-files 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-files 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 Aug 21 11:14:59 1993 -@@ -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; -diff -u --recursive --new-files 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 Aug 21 10:38:00 1993 -@@ -22,6 +22,31 @@ - - extern "C" int do_signal(unsigned long oldmask, struct pt_regs * regs); - -+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; -+}; -+ - extern "C" int sys_sgetmask(void) - { - return current->blocked; -@@ -151,15 +176,32 @@ - /* - * 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) -+extern "C" 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; - } - - /* -@@ -186,32 +228,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 -@@ -317,8 +353,8 @@ - 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"); -+ if (regs->ss != USER_DS) -+ printk("Warning: signal handler with nonstandard stack segment\n"); - for (mask = 1 ; mask ; sa++,signr++,mask += mask) { - if (mask > handler_signal) - break; -@@ -331,6 +367,9 @@ - __asm__("testb $0,%%fs:%0": :"m" (*(char *) sa_handler)); - setup_frame(&frame,eip,regs,signr,sa_handler,oldmask); - eip = sa_handler; -+ 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-files 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 Aug 21 10:23:07 1993 -@@ -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) -diff -u --recursive --new-files 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 Aug 21 11:37:00 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: -@@ -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-files 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 --git a/ALPHA-pl13.diff b/ALPHA-pl13.diff new file mode 100644 index 00000000000..6f675a5bb71 --- /dev/null +++ b/ALPHA-pl13.diff @@ -0,0 +1,7864 @@ +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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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 ++ ++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; ip_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 + #include + +-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 + #include + +-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 ++#include ++ + #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 ++ + /* + * 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 + #include + #include + #include +@@ -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 ++#include + + #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< + #include + #include ++#include + + 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 + + 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 ++#include + + #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 + #include + +-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 + #include + ++/* 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 + #include ++#include + + /* + * 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 + #include + #include ++#include + + #include + #include +@@ -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 + #include + #include ++#include + + #include + #include +@@ -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 + #include + #include ++#include + + #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 + #include + #include ++#include + + #include + #include +@@ -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 + #include + #include ++#include ++ + #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;ji_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 + #include + +-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 + #include + +-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 + #include + #include ++#include + ++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 + #include + +-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<>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 + #include +@@ -23,6 +23,14 @@ + #include + #include + #include ++ ++#ifndef PRE_PL13 ++#include ++#else ++#define snarf_region(base,extent) do {;}while(0) ++#define check_region(base,extent) (0) ++#endif ++ + /*#include */ + #include + #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 . */ + #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 +-#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 ++#include + + #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 + #include ++#include + #include + #include + #include +@@ -29,6 +30,7 @@ + #include + #include + #include ++#include + #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 + #include +@@ -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 + #include +@@ -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, + * Fred N. van Kempen, ++ * Donald Becker, + * + * 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 + #include +@@ -22,6 +23,7 @@ + /*#include */ + #include + #include ++#include + #include + #include + /*#include */ +@@ -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, + * Fred N. van Kempen, ++ * Donald Becker, + * + * 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 + #include + #include ++#include /* 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 + #include + #include ++#include + #include + #include + #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 + #include + #include ++#include + #include + #include + #include +@@ -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 . Puredata seem to do software ++ Mike Jagdis . 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); diff --git a/ChangeLog b/ChangeLog index c88a3c03819..0ff96cb3a8f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,118 @@ +Mon Sep 13 05:00:11 1993 Eric Youngdale + + * [Makefile] [if1632/relay.c] [include/dlls.h] [selector.c] + [loader/wine.c] [tools/build.c] + Added ability to generate missing functions statistics. + +Mon Sep 13 12:09:47 1993 Scott A. Laird (scott@curly) + + * [WIN31-APPLETS] + Added new file. + + * [if1632/kernel.spec] + Added definitions for GetProfile{Int,String} and SetHandleCount. + + * [if1632/keyboard.spec] + Created interface specification for Keyboard driver DLL. + + * [if1632/relay.c] + Added keyboard.dll to list of included DLLs. + + * [if1632/user.spec] + Added LoadAccelerators definition. + + * [loader/resource.c] + Added LoadAccelerators stub. + + * [misc/file.c] + Changed OpenFile, and added SetHandleCount (for winfile.exe) + + * [misc/keyboard.c] + Added keyboard code. + + * [misc/profile.c] [misc/xt.c] + Moved GetPrivateProfile* commands here, and added GetProfile* + commands. + +Mon Sep 13 10:24:37 1993 Andrew Bulhak + + * [windows/utility.c] + Implemented MulDiv(), OutputDebugString() and wvsprintf() + +Fri Sep 10 09:13:30 1993 John Brezak + + * [*/Makefile] + Created patch to allow BSD make to build wine. + + * [windows/win.c] + Fixed NULL pointer reference. + + * [windows/message.c] [misc/xt.c] + Defined HZ to handle system specific timing. + + * [windows/graphics.c] + Use M_PI is PI + + * [objects/pallete.c] + NetBSD does not have /usr/include/values.h and MAXINT is INT_MAX. + + * [dump.c] [ldt.c] [wine.c] + ifdef'ed linux headers for linux compile. + + * [loader/ldtlib.c] + Add NetBSD system calls when compiled on that system. + + * [loader/selector.c] + Use mmap(MAP_ANON, ...) for NetBSD. + + * [if1632/call.S] + Fixed selector assumptions. + +Thu Sep 9 20:01:37 1993 David Metcalfe + + * [controls/WinButton*] [controls/button.c] [controls/widget.c] + [windows/win.c] [windows/class.c] + Added 3D button control and tied into CreateWindow() + +Thu Sep 9 07:35:24 1993 Scott Laird + + * [if1632/sound.spec] + Created interface specification for SOUND DLL. + + * [if1632/win87em.spec] + Added more functions to the WIN87EM DLL interface specification + + * [misc/emulate.c] + Created stubs for the new math emulation functions. + + * [misc/sound.c] + Created stubs for the SOUND DLL. + +Sun Sep 5 21:02:10 1993 John Burton + + * [if1632/kernel.spec] + Added interface specifications for OpenFile, _lclose, _lread, _lopen, + and _lwrite. + + * [include/windows.h] + Added OF_ macros + + * [misc/file.c] + Implemented OpenFile, _lclose, _lread, _lopen and _lwrite. + +Fri Sep 3 18:47:03 1993 Alexandre Julliard + + * [windows/dc.c] + Bug fix + + * [objects/text.c] + Bug fix + +Fri Sep 3 18:47:03 1993 Bob Amstadt + + * [objects/linedda.c] + Finished LineDDA(). + Fri Sep 3 11:52:18 1993 Bob Amstadt * [windows/timer.c] diff --git a/README b/README index ff6e23d00ef..7b8666f3ec6 100644 --- a/README +++ b/README @@ -4,14 +4,47 @@ License. INSTALLATION: +Linux: + Uncompress and untar this archive into the directory of your choice. This release requires a Linux version 0.99 pl12 kernel with -ALPHA-diffs and sognal-diffs. Apply ALPHA-diffs first, and then -signal-diffs. +ALPHA-pl13-diffs. + +NetBSD: + + If you use BSD make rather than GNU make, you must apply the patches +in the file "bsdmake.patch". This release requires NetBSD 0.9 with +additional patches. + +All: To build Wine, first do a "make depend" and then a "make". The executable "wine" will be built. +Grab a copy of Windows sol.exe (Solitaire) and run it with the command: + + wine sol.exe + +Have a nice game of solitaire, but be careful. Emulation isn't perfect. +So, occassionally it will crash. + +WHAT'S NEW with version 0.4.0: (see ChangeLog for details) + - Wine now compiles and runs under NetBSD. Patches are + required for NetBSD. + - Wine stat patches included. Add "-DWINESTAT" to the definition + of COPTS in the main Makefile to activate. + - Preliminary keyboard handling. + - Button control window implemented. + - many other new functions added. + +WHAT'S NEW with version 0.3.1: (see ChangeLog for details) + - LineDDA() completed + - numerous bug fixes + - INT 1Ah implemented + - SOUND DLL implemented + - More of WIN87EM DLL implemented + - OpenFile() and friends implemented + WHAT'S NEW with version 0.3.0: (see ChangeLog for details) - Mouse capture - Text justification and underlining diff --git a/WIN31-APPLETS b/WIN31-APPLETS new file mode 100644 index 00000000000..edc64e4b6d0 --- /dev/null +++ b/WIN31-APPLETS @@ -0,0 +1,45 @@ + Status of MS Windows 3.1 Applets + + +September 13, 1993 + +I copied the following DLLs from my Windows (3.1) directory to my Wine +directory. Below I show how most of the programs included with +Windows 3.1 died. + + commdlg.dll olesvr.dll recorder.dll + olecli.dll pbrush.dll toolhelp.dll + +Scott Laird (lair@midway.uchicago.edu) + + +calc.exe dies no USER.89 (CreateDialog) +calendar.exe dies no KERNEL.60 (FindResource) +cardfile.exe cannot read relocation info +charmap.exe dies no USER.89 (CreateDialog) +clipbrd.exe dies no error +clock.exe dies no KERNEL.60 (FindResource) +control.exe dies no KERNEL.90 (lstrlen) +drwatson.exe dies no KERNEL.36 (GetCurrentTask) +mplayer.exe no MMSYSTEM.dll +notepad.exe dies no error +nwpopup.exe dies no KERNEL.47 (GetModuleHandle) +packager.exe cannot read relocation info +pbrush.exe cannot read relocation info +pifedit.exe dies no KERNEL.60 (FindResource) +printman.exe dies no KERNEL.107 (SetErrorMode) +progman.exe dies no error +recorder.exe cannot read relocation info +regedit.exe dies no KERNEL.90 (lstrlen) +sol.exe ** RUNS ** +soundrec.exe no MMSYSTEM.dll +sysedit.exe dies no USER.159 (GetSubMenu) +terminal.exe dies int21 2a +winfile.exe DOS ax=2fdf, dies no KERNEL.107 +winhelp.exe dies no KERNEL.60 (FindResource) +winmine.exe dies no USER.256 (GetDesktopWindow) +winpopup.exe no NETAPI +wintutor.exe 'Cannot load WINTUTOR.DAT' (file present) +write.exe cannot read relocation info + + diff --git a/bsdmake.patch b/bsdmake.patch new file mode 100644 index 00000000000..42f0ea1f8b6 --- /dev/null +++ b/bsdmake.patch @@ -0,0 +1,147 @@ +*** ./windows/Makefile.orig Fri Sep 3 16:37:58 1993 +--- ./windows/Makefile Thu Sep 9 22:56:21 1993 +*************** +*** 14,19 **** + depend: + $(CC) $(CFLAGS) -M *.c > .depend + +! ifeq (.depend,$(wildcard .depend)) +! include .depend +! endif +--- 14,19 ---- + depend: + $(CC) $(CFLAGS) -M *.c > .depend + +! .if exists(.depend) +! .include ".depend" +! .endif +*** ./tools/Makefile.orig Tue Jul 20 18:40:18 1993 +--- ./tools/Makefile Thu Sep 9 22:56:21 1993 +*************** +*** 12,17 **** + # + # Dependency lists + # +! ifeq (.depend,$(wildcard .depend)) +! include .depend +! endif +--- 12,21 ---- + # + # Dependency lists + # +! .if exists(.depend) +! .include ".depend" +! .endif +! +! #ifeq (.depend,$(wildcard .depend)) +! #include .depend +! #endif +*** ./objects/Makefile.orig Fri Sep 3 16:39:20 1993 +--- ./objects/Makefile Thu Sep 9 22:56:23 1993 +*************** +*** 14,19 **** + depend: + $(CC) $(CFLAGS) -M *.c > .depend + +! ifeq (.depend,$(wildcard .depend)) +! include .depend +! endif +--- 14,19 ---- + depend: + $(CC) $(CFLAGS) -M *.c > .depend + +! .if exists(.depend) +! .include ".depend" +! .endif +*** ./misc/Makefile.orig Thu Sep 9 11:16:49 1993 +--- ./misc/Makefile Thu Sep 9 22:56:23 1993 +*************** +*** 13,18 **** + depend: + $(CC) $(CFLAGS) -M *.c > .depend + +! ifeq (.depend,$(wildcard .depend)) +! include .depend +! endif +--- 13,18 ---- + depend: + $(CC) $(CFLAGS) -M *.c > .depend + +! .if exists(.depend) +! .include ".depend" +! .endif +*** ./memory/Makefile.orig Tue Jul 20 18:43:02 1993 +--- ./memory/Makefile Thu Sep 9 22:56:34 1993 +*************** +*** 13,18 **** + depend: + $(CC) $(CFLAGS) -M *.c > .depend + +! ifeq (.depend,$(wildcard .depend)) +! include .depend +! endif +--- 13,18 ---- + depend: + $(CC) $(CFLAGS) -M *.c > .depend + +! .if exists(.depend) +! .include ".depend" +! .endif +*** ./loader/Makefile.orig Mon Aug 30 20:44:18 1993 +--- ./loader/Makefile Thu Sep 9 22:56:36 1993 +*************** +*** 13,18 **** + depend: + $(CC) $(CFLAGS) -M *.c > .depend + +! ifeq (.depend,$(wildcard .depend)) +! include .depend +! endif +--- 13,18 ---- + depend: + $(CC) $(CFLAGS) -M *.c > .depend + +! .if exists(.depend) +! .include ".depend" +! .endif +*** ./if1632/Makefile.orig Thu Sep 9 11:15:58 1993 +--- ./if1632/Makefile Thu Sep 9 22:56:38 1993 +*************** +*** 42,50 **** + depend: + $(CC) $(CFLAGS) -M *.c > .depend + +! ifeq (.depend,$(wildcard .depend)) +! include .depend +! endif + + + +--- 42,50 ---- + depend: + $(CC) $(CFLAGS) -M *.c > .depend + +! .if exists(.depend) +! .include ".depend" +! .endif + + + +*** ./controls/Makefile.orig Mon Aug 30 19:40:39 1993 +--- ./controls/Makefile Thu Sep 9 22:56:43 1993 +*************** +*** 14,19 **** + depend: + $(CC) $(CFLAGS) -M *.c > .depend + +! ifeq (.depend,$(wildcard .depend)) +! include .depend +! endif +--- 14,20 ---- + depend: + $(CC) $(CFLAGS) -M *.c > .depend + +! .if exists(.depend) +! .include ".depend" +! .endif +! diff --git a/controls/Makefile b/controls/Makefile index 4c7b67a7a78..dc3c1878bc5 100644 --- a/controls/Makefile +++ b/controls/Makefile @@ -1,7 +1,7 @@ CFLAGS=$(COPTS) $(DEBUGOPTS) -I$(INCLUDE_DIR) -OBJS=menu.o widgets.o SmeMenuButto.o WinLabel.o WinCommand.o WinMenuButto.o -# WinButton.o +OBJS=menu.o widgets.o button.o SmeMenuButto.o WinLabel.o WinCommand.o \ + WinMenuButto.o WinButton.o default: controls.o diff --git a/controls/WinButton.c b/controls/WinButton.c new file mode 100644 index 00000000000..59773cedf73 --- /dev/null +++ b/controls/WinButton.c @@ -0,0 +1,605 @@ +/*********************************************************** +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts, +and the Massachusetts Institute of Technology, Cambridge, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the names of Digital or MIT not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +/* + * Modifications for Wine + * + * 8/28/93 David Metcalfe (david@prism.demon.co.uk) + * Created from Command widget and added 3D effect + */ + +/* + * WinButton.c - WinButton button widget + */ + +#include +#include +#include +#include +#include +#include "WinButtonP.h" +#include + +#define DEFAULT_HIGHLIGHT_THICKNESS 0 +#define DEFAULT_SHAPE_HIGHLIGHT 32767 + +/**************************************************************** + * + * Full class record constant + * + ****************************************************************/ + +/* Private Data */ + +static char defaultTranslations[] = + ": highlight() \n\ + : reset() \n\ + : set() \n\ + : notify() unset() "; + +#define offset(field) XtOffsetOf(WinButtonRec, field) +static XtResource resources[] = { + {XtNcallback, XtCCallback, XtRCallback, sizeof(XtPointer), + offset(winbutton.callbacks), XtRCallback, (XtPointer)NULL}, + {XtNhighlightThickness, XtCThickness, XtRDimension, sizeof(Dimension), + offset(winbutton.highlight_thickness), XtRImmediate, + (XtPointer) DEFAULT_SHAPE_HIGHLIGHT}, + {XtNshapeStyle, XtCShapeStyle, XtRShapeStyle, sizeof(int), + offset(winbutton.shape_style), XtRImmediate, + (XtPointer)XawShapeRectangle}, + {XtNcornerRoundPercent, XtCCornerRoundPercent, + XtRDimension, sizeof(Dimension), + offset(winbutton.corner_round), XtRImmediate, (XtPointer) 25}, + {XtNshadowThickness, XtCShadowThickness, XtRDimension, sizeof(Dimension), + offset(winbutton.shadow_thickness), XtRImmediate, (XtPointer) 2}, + {XtNshadowHighlight, XtCShadowHighlight, XtRPixel, sizeof(Pixel), + offset(winbutton.shadow_highlight), XtRString, (XtPointer) "white"}, + {XtNshadowShade, XtCShadowShade, XtRPixel, sizeof(Pixel), + offset(winbutton.shadow_shade), XtRString, (XtPointer) "grey25"}, +}; +#undef offset + +static Boolean SetValues(); +static void Initialize(), Redisplay(), Set(), Reset(), Notify(), Unset(); +static void Highlight(), Unhighlight(), Destroy(), PaintWinButtonWidget(); +static void ClassInitialize(); +static Boolean ShapeButton(); +static void Realize(), Resize(); + +static XtActionsRec actionsList[] = { + {"set", Set}, + {"notify", Notify}, + {"highlight", Highlight}, + {"reset", Reset}, + {"unset", Unset}, + {"unhighlight", Unhighlight} +}; + +#define SuperClass ((WinLabelWidgetClass)&winLabelClassRec) + +WinButtonClassRec winButtonClassRec = { + { + (WidgetClass) SuperClass, /* superclass */ + "WinButton", /* class_name */ + sizeof(WinButtonRec), /* size */ + ClassInitialize, /* class_initialize */ + NULL, /* class_part_initialize */ + FALSE, /* class_inited */ + Initialize, /* initialize */ + NULL, /* initialize_hook */ + Realize, /* realize */ + actionsList, /* actions */ + XtNumber(actionsList), /* num_actions */ + resources, /* resources */ + XtNumber(resources), /* resource_count */ + NULLQUARK, /* xrm_class */ + FALSE, /* compress_motion */ + TRUE, /* compress_exposure */ + TRUE, /* compress_enterleave */ + FALSE, /* visible_interest */ + Destroy, /* destroy */ + Resize, /* resize */ + Redisplay, /* expose */ + SetValues, /* set_values */ + NULL, /* set_values_hook */ + XtInheritSetValuesAlmost, /* set_values_almost */ + NULL, /* get_values_hook */ + NULL, /* accept_focus */ + XtVersion, /* version */ + NULL, /* callback_private */ + defaultTranslations, /* tm_table */ + XtInheritQueryGeometry, /* query_geometry */ + XtInheritDisplayAccelerator, /* display_accelerator */ + NULL /* extension */ + }, /* CoreClass fields initialization */ + { + XtInheritChangeSensitive /* change_sensitive */ + }, /* SimpleClass fields initialization */ + { + 0, /* field not used */ + }, /* WinLabelClass fields initialization */ + { + 0, /* field not used */ + }, /* WinButtonClass fields initialization */ +}; + + /* for public consumption */ +WidgetClass winButtonWidgetClass = (WidgetClass) &winButtonClassRec; + +/**************************************************************** + * + * Private Procedures + * + ****************************************************************/ + +static GC +Get_GC(cbw, fg, bg) +WinButtonWidget cbw; +Pixel fg, bg; +{ + XGCValues values; + + values.foreground = fg; + values.background = bg; + values.font = cbw->winlabel.font->fid; + values.cap_style = CapProjecting; + + if (cbw->winbutton.highlight_thickness > 1 ) + values.line_width = cbw->winbutton.highlight_thickness; + else + values.line_width = 0; + + return XtGetGC((Widget)cbw, + (GCForeground|GCBackground|GCFont|GCLineWidth|GCCapStyle), + &values); +} + +static void +Get_Shadow_GCs(cbw) +WinButtonWidget cbw; +{ + XGCValues values; + + values.foreground = cbw->winbutton.shadow_highlight; + values.line_width = cbw->winbutton.shadow_thickness; + values.cap_style = CapProjecting; + cbw->winbutton.shadow_highlight_gc = + XtGetGC((Widget)cbw, (GCForeground|GCLineWidth|GCCapStyle), &values); + + values.foreground = cbw->winbutton.shadow_shade; + values.line_width = cbw->winbutton.shadow_thickness; + values.cap_style = CapProjecting; + cbw->winbutton.shadow_shade_gc = + XtGetGC((Widget)cbw, (GCForeground|GCLineWidth|GCCapStyle), &values); +} + + +/* ARGSUSED */ +static void +Initialize(request, new, args, num_args) +Widget request, new; +ArgList args; /* unused */ +Cardinal *num_args; /* unused */ +{ + WinButtonWidget cbw = (WinButtonWidget) new; + int shape_event_base, shape_error_base; + + if (cbw->winbutton.shape_style != XawShapeRectangle + && !XShapeQueryExtension(XtDisplay(new), &shape_event_base, + &shape_error_base)) + cbw->winbutton.shape_style = XawShapeRectangle; + if (cbw->winbutton.highlight_thickness == DEFAULT_SHAPE_HIGHLIGHT) { + if (cbw->winbutton.shape_style != XawShapeRectangle) + cbw->winbutton.highlight_thickness = 0; + else + cbw->winbutton.highlight_thickness = DEFAULT_HIGHLIGHT_THICKNESS; + } + + XtVaSetValues(new, XtNbackground, "grey75"); + cbw->winbutton.normal_GC = Get_GC(cbw, cbw->winlabel.foreground, + cbw->core.background_pixel); + cbw->winbutton.inverse_GC = Get_GC(cbw, cbw->core.background_pixel, + cbw->winlabel.foreground); + XtReleaseGC(new, cbw->winlabel.normal_GC); + cbw->winlabel.normal_GC = cbw->winbutton.normal_GC; + + Get_Shadow_GCs(cbw); + + cbw->winbutton.set = FALSE; + cbw->winbutton.highlighted = HighlightNone; +} + +static Region +HighlightRegion(cbw) +WinButtonWidget cbw; +{ + static Region outerRegion = NULL, innerRegion, emptyRegion; + XRectangle rect; + + if (cbw->winbutton.highlight_thickness == 0 || + cbw->winbutton.highlight_thickness > + (Dimension) ((Dimension) Min(cbw->core.width, cbw->core.height)/2)) + return(NULL); + + if (outerRegion == NULL) { + /* save time by allocating scratch regions only once. */ + outerRegion = XCreateRegion(); + innerRegion = XCreateRegion(); + emptyRegion = XCreateRegion(); + } + + rect.x = rect.y = 0; + rect.width = cbw->core.width; + rect.height = cbw->core.height; + XUnionRectWithRegion( &rect, emptyRegion, outerRegion ); + rect.x = rect.y = cbw->winbutton.highlight_thickness; + rect.width -= cbw->winbutton.highlight_thickness * 2; + rect.height -= cbw->winbutton.highlight_thickness * 2; + XUnionRectWithRegion( &rect, emptyRegion, innerRegion ); + XSubtractRegion( outerRegion, innerRegion, outerRegion ); + return outerRegion; +} + +/*************************** +* +* Action Procedures +* +***************************/ + +/* ARGSUSED */ +static void +Set(w,event,params,num_params) +Widget w; +XEvent *event; +String *params; /* unused */ +Cardinal *num_params; /* unused */ +{ + WinButtonWidget cbw = (WinButtonWidget)w; + + if (cbw->winbutton.set) + return; + + cbw->winbutton.set= TRUE; + if (XtIsRealized(w)) + PaintWinButtonWidget(w, (Region) NULL, TRUE); +} + +/* ARGSUSED */ +static void +Unset(w,event,params,num_params) +Widget w; +XEvent *event; +String *params; /* unused */ +Cardinal *num_params; +{ + WinButtonWidget cbw = (WinButtonWidget)w; + + if (!cbw->winbutton.set) + return; + + cbw->winbutton.set = FALSE; + if (XtIsRealized(w)) { + XClearWindow(XtDisplay(w), XtWindow(w)); + PaintWinButtonWidget(w, (Region) NULL, TRUE); + } +} + +/* ARGSUSED */ +static void +Reset(w,event,params,num_params) +Widget w; +XEvent *event; +String *params; /* unused */ +Cardinal *num_params; /* unused */ +{ + WinButtonWidget cbw = (WinButtonWidget)w; + + if (cbw->winbutton.set) { + cbw->winbutton.highlighted = HighlightNone; + Unset(w, event, params, num_params); + } + else + Unhighlight(w, event, params, num_params); +} + +/* ARGSUSED */ +static void +Highlight(w,event,params,num_params) +Widget w; +XEvent *event; +String *params; +Cardinal *num_params; +{ + WinButtonWidget cbw = (WinButtonWidget)w; + + if ( *num_params == (Cardinal) 0) + cbw->winbutton.highlighted = HighlightWhenUnset; + else { + if ( *num_params != (Cardinal) 1) + XtWarning("Too many parameters passed to highlight action table."); + switch (params[0][0]) { + case 'A': + case 'a': + cbw->winbutton.highlighted = HighlightAlways; + break; + default: + cbw->winbutton.highlighted = HighlightWhenUnset; + break; + } + } + + if (XtIsRealized(w)) + PaintWinButtonWidget(w, HighlightRegion(cbw), TRUE); +} + +/* ARGSUSED */ +static void +Unhighlight(w,event,params,num_params) +Widget w; +XEvent *event; +String *params; /* unused */ +Cardinal *num_params; /* unused */ +{ + WinButtonWidget cbw = (WinButtonWidget)w; + + cbw->winbutton.highlighted = HighlightNone; + if (XtIsRealized(w)) + PaintWinButtonWidget(w, HighlightRegion(cbw), TRUE); +} + +/* ARGSUSED */ +static void +Notify(w,event,params,num_params) +Widget w; +XEvent *event; +String *params; /* unused */ +Cardinal *num_params; /* unused */ +{ + WinButtonWidget cbw = (WinButtonWidget)w; + + /* check to be sure state is still Set so that user can cancel + the action (e.g. by moving outside the window, in the default + bindings. + */ + if (cbw->winbutton.set) + XtCallCallbackList(w, cbw->winbutton.callbacks, NULL); +} + +/* + * Repaint the widget window + */ + +/************************ +* +* REDISPLAY (DRAW) +* +************************/ + +/* ARGSUSED */ +static void +Redisplay(w, event, region) +Widget w; +XEvent *event; +Region region; +{ + PaintWinButtonWidget(w, region, FALSE); +} + +/* Function Name: PaintWinButtonWidget + * Description: Paints the winbutton widget. + * Arguments: w - the winbutton widget. + * region - region to paint (passed to the superclass). + * change - did it change either set or highlight state? + * Returns: none + */ + +static void +PaintWinButtonWidget(w, region, change) +Widget w; +Region region; +Boolean change; +{ + WinButtonWidget cbw = (WinButtonWidget) w; + Boolean very_thick; + GC norm_gc, rev_gc; + int offset; + + very_thick = cbw->winbutton.highlight_thickness > + (Dimension)((Dimension) Min(cbw->core.width, + cbw->core.height)/2); + + offset = cbw->winbutton.shadow_thickness / 2; + if (cbw->winbutton.set) { + XClearWindow(XtDisplay(w), XtWindow(w)); + region = NULL; /* Force label to repaint text. */ + } + else { + XDrawLine(XtDisplay(w), XtWindow(w), cbw->winbutton.shadow_highlight_gc, + offset, offset, cbw->core.width - offset, offset); + XDrawLine(XtDisplay(w), XtWindow(w), cbw->winbutton.shadow_highlight_gc, + offset, offset, offset, cbw->core.height - offset); + XDrawLine(XtDisplay(w), XtWindow(w), cbw->winbutton.shadow_shade_gc, + offset, cbw->core.height - offset + 1, + cbw->core.width - offset, cbw->core.height - offset); + XDrawLine(XtDisplay(w), XtWindow(w), cbw->winbutton.shadow_shade_gc, + cbw->core.width - offset, offset + 1, + cbw->core.width - offset, cbw->core.height - offset); + } + + if (cbw->winbutton.highlight_thickness <= 0) + { + (*SuperClass->core_class.expose) (w, (XEvent *) NULL, region); + return; + } + +/* + * If we are set then use the same colors as if we are not highlighted. + */ + + if (cbw->winbutton.set == (cbw->winbutton.highlighted == HighlightNone)) { + norm_gc = cbw->winbutton.inverse_GC; + rev_gc = cbw->winbutton.normal_GC; + } + else { + norm_gc = cbw->winbutton.normal_GC; + rev_gc = cbw->winbutton.inverse_GC; + } + + if ( !( (!change && (cbw->winbutton.highlighted == HighlightNone)) || + ((cbw->winbutton.highlighted == HighlightWhenUnset) && + (cbw->winbutton.set))) ) { + if (very_thick) { + cbw->winlabel.normal_GC = norm_gc; /* Give the label the right GC. */ + XFillRectangle(XtDisplay(w),XtWindow(w), rev_gc, + 0, 0, cbw->core.width, cbw->core.height); + } + else { + /* wide lines are centered on the path, so indent it */ + int offset = cbw->winbutton.highlight_thickness/2; + XDrawRectangle(XtDisplay(w),XtWindow(w), rev_gc, offset, offset, + cbw->core.width - cbw->winbutton.highlight_thickness, + cbw->core.height - cbw->winbutton.highlight_thickness); + } + } + (*SuperClass->core_class.expose) (w, (XEvent *) NULL, region); +} + +static void +Destroy(w) +Widget w; +{ + WinButtonWidget cbw = (WinButtonWidget) w; + + /* so WinLabel can release it */ + if (cbw->winlabel.normal_GC == cbw->winbutton.normal_GC) + XtReleaseGC( w, cbw->winbutton.inverse_GC ); + else + XtReleaseGC( w, cbw->winbutton.normal_GC ); +} + +/* + * Set specified arguments into widget + */ + +/* ARGSUSED */ +static Boolean +SetValues (current, request, new) +Widget current, request, new; +{ + WinButtonWidget oldcbw = (WinButtonWidget) current; + WinButtonWidget cbw = (WinButtonWidget) new; + Boolean redisplay = False; + + if ( oldcbw->core.sensitive != cbw->core.sensitive && !cbw->core.sensitive) { + /* about to become insensitive */ + cbw->winbutton.set = FALSE; + cbw->winbutton.highlighted = HighlightNone; + redisplay = TRUE; + } + + if ( (oldcbw->winlabel.foreground != cbw->winlabel.foreground) || + (oldcbw->core.background_pixel != cbw->core.background_pixel) || + (oldcbw->winbutton.highlight_thickness != + cbw->winbutton.highlight_thickness) || + (oldcbw->winlabel.font != cbw->winlabel.font) ) + { + if (oldcbw->winlabel.normal_GC == oldcbw->winbutton.normal_GC) + /* WinLabel has release one of these */ + XtReleaseGC(new, cbw->winbutton.inverse_GC); + else + XtReleaseGC(new, cbw->winbutton.normal_GC); + + cbw->winbutton.normal_GC = Get_GC(cbw, cbw->winlabel.foreground, + cbw->core.background_pixel); + cbw->winbutton.inverse_GC = Get_GC(cbw, cbw->core.background_pixel, + cbw->winlabel.foreground); + XtReleaseGC(new, cbw->winlabel.normal_GC); + cbw->winlabel.normal_GC = (cbw->winbutton.set + ? cbw->winbutton.inverse_GC + : cbw->winbutton.normal_GC); + + redisplay = True; + } + + if ( XtIsRealized(new) + && oldcbw->winbutton.shape_style != cbw->winbutton.shape_style + && !ShapeButton(cbw, TRUE)) + { + cbw->winbutton.shape_style = oldcbw->winbutton.shape_style; + } + + return (redisplay); +} + +static void ClassInitialize() +{ + XawInitializeWidgetSet(); + XtSetTypeConverter( XtRString, XtRShapeStyle, XmuCvtStringToShapeStyle, + NULL, 0, XtCacheNone, NULL ); +} + + +static Boolean +ShapeButton(cbw, checkRectangular) +WinButtonWidget cbw; +Boolean checkRectangular; +{ + Dimension corner_size; + + if ( (cbw->winbutton.shape_style == XawShapeRoundedRectangle) ) { + corner_size = (cbw->core.width < cbw->core.height) ? cbw->core.width + : cbw->core.height; + corner_size = (int) (corner_size * cbw->winbutton.corner_round) / 100; + } + + if (checkRectangular || cbw->winbutton.shape_style != XawShapeRectangle) { + if (!XmuReshapeWidget((Widget) cbw, cbw->winbutton.shape_style, + corner_size, corner_size)) { + cbw->winbutton.shape_style = XawShapeRectangle; + return(False); + } + } + return(TRUE); +} + +static void Realize(w, valueMask, attributes) + Widget w; + Mask *valueMask; + XSetWindowAttributes *attributes; +{ + (*winButtonWidgetClass->core_class.superclass->core_class.realize) + (w, valueMask, attributes); + + ShapeButton( (WinButtonWidget) w, FALSE); +} + +static void Resize(w) + Widget w; +{ + if (XtIsRealized(w)) + ShapeButton( (WinButtonWidget) w, FALSE); + + (*winButtonWidgetClass->core_class.superclass->core_class.resize)(w); +} + diff --git a/controls/WinButton.h b/controls/WinButton.h new file mode 100644 index 00000000000..54dee6a8732 --- /dev/null +++ b/controls/WinButton.h @@ -0,0 +1,109 @@ +/*********************************************************** +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts, +and the Massachusetts Institute of Technology, Cambridge, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the names of Digital or MIT not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +/* + * Modifications for Wine + * + * 8/28/93 David Metcalfe (david@prism.demon.co.uk) + * Created from Command widget and added 3D effect + */ + +#ifndef _WinButton_h +#define _WinButton_h + +#include "WinLabel.h" + +/* WinButton widget resources: + + Name Class RepType Default Value + ---- ----- ------- ------------- + accelerators Accelerators AcceleratorTable NULL + ancestorSensitive AncestorSensitive Boolean True + background Background Pixel XtDefaultBackground + backgroundPixmap Pixmap Pixmap XtUnspecifiedPixmap + bitmap Pixmap Pixmap None + borderColor BorderColor Pixel XtDefaultForeground + borderPixmap Pixmap Pixmap XtUnspecifiedPixmap + borderWidth BorderWidth Dimension 1 + callback Callback XtCallbackList NULL + colormap Colormap Colormap parent's colormap + cornerRoundPercent CornerRoundPercent Dimension 25 + cursor Cursor Cursor None + cursorName Cursor String NULL + depth Depth int parent's depth + destroyCallback Callback XtCallbackList NULL + encoding Encoding UnsignedChar XawTextEncoding8bit + font Font XFontStruct* XtDefaultFont + foreground Foreground Pixel XtDefaultForeground + height Height Dimension text height + highlightThickness Thickness Dimension 0 if shaped, else 2 + insensitiveBorder Insensitive Pixmap Gray + internalHeight Height Dimension 2 + internalWidth Width Dimension 4 + justify Justify XtJustify XtJustifyCenter + label Label String NULL + leftBitmap LeftBitmap Pixmap None + mappedWhenManaged MappedWhenManaged Boolean True + pointerColor Foreground Pixel XtDefaultForeground + pointerColorBackground Background Pixel XtDefaultBackground + resize Resize Boolean True + screen Screen Screen parent's Screen + sensitive Sensitive Boolean True + shadowHighlight ShadowHighlight Pixel White + shadowShade ShadowShade Pixel Grey25 + shadowThickness ShadowThickness Dimension 2 + shapeStyle ShapeStyle ShapeStyle Rectangle + translations Translations TranslationTable see doc or source + width Width Dimension text width + x Position Position 0 + y Position Position 0 + +*/ + +#define XtNhighlightThickness "highlightThickness" + +#define XtNshapeStyle "shapeStyle" +#define XtCShapeStyle "ShapeStyle" +#define XtRShapeStyle "ShapeStyle" +#define XtNcornerRoundPercent "cornerRoundPercent" +#define XtCCornerRoundPercent "CornerRoundPercent" +#define XtNshadowThickness "shadowThickness" +#define XtCShadowThickness "ShadowThickness" +#define XtNshadowHighlight "shadowHighlight" +#define XtCShadowHighlight "ShadowHighlight" +#define XtNshadowShade "shadowShade" +#define XtCShadowShade "ShadowShade" + +#define XawShapeRectangle XmuShapeRectangle +#define XawShapeOval XmuShapeOval +#define XawShapeEllipse XmuShapeEllipse +#define XawShapeRoundedRectangle XmuShapeRoundedRectangle + +extern WidgetClass winButtonWidgetClass; + +typedef struct _WinButtonClassRec *WinButtonWidgetClass; +typedef struct _WinButtonRec *WinButtonWidget; + +#endif /* _WinButton_h */ +/* DON'T ADD STUFF AFTER THIS */ diff --git a/controls/WinButtonP.h b/controls/WinButtonP.h new file mode 100644 index 00000000000..207f19ac3e9 --- /dev/null +++ b/controls/WinButtonP.h @@ -0,0 +1,123 @@ +/*********************************************************** +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts, +and the Massachusetts Institute of Technology, Cambridge, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the names of Digital or MIT not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +/* + * Modifications for Wine + * + * 8/28/93 David Metcalfe (david@prism.demon.co.uk) + * Created from Command widget and added 3D effect + */ + +/* + * WinButtonP.h - Private definitions for WinButton widget + * + */ + +#ifndef _WinButtonP_h +#define _WinButtonP_h + +#include "WinButton.h" +#include "WinLabelP.h" + +/*********************************************************************** + * + * WinButton Widget Private Data + * + ***********************************************************************/ + +typedef enum { + HighlightNone, /* Do not highlight. */ + HighlightWhenUnset, /* Highlight only when unset, this is + to preserve current command widget + functionality. */ + HighlightAlways /* Always highlight, lets the toggle widget + and other subclasses do the right thing. */ +} XtCommandHighlight; + +/************************************ + * + * Class structure + * + ***********************************/ + + + /* New fields for the WinButton widget class record */ +typedef struct _WinButtonClass + { + int makes_compiler_happy; /* not used */ + } WinButtonClassPart; + + /* Full class record declaration */ +typedef struct _WinButtonClassRec { + CoreClassPart core_class; + SimpleClassPart simple_class; + WinLabelClassPart winlabel_class; + WinButtonClassPart winbutton_class; +} WinButtonClassRec; + +extern WinButtonClassRec winButtonClassRec; + +/*************************************** + * + * Instance (widget) structure + * + **************************************/ + + /* New fields for the WinButton widget record */ +typedef struct { + /* resources */ + Dimension highlight_thickness; + Dimension shadow_thickness; + Pixel shadow_shade; + Pixel shadow_highlight; + XtCallbackList callbacks; + + /* private state */ + Pixmap gray_pixmap; + GC normal_GC; + GC inverse_GC; + GC shadow_highlight_gc; + GC shadow_shade_gc; + Boolean set; + XtCommandHighlight highlighted; + /* more resources */ + int shape_style; + Dimension corner_round; +} WinButtonPart; + + +/* XtEventsPtr eventTable;*/ + + + /* Full widget declaration */ +typedef struct _WinButtonRec { + CorePart core; + SimplePart simple; + WinLabelPart winlabel; + WinButtonPart winbutton; +} WinButtonRec; + +#endif /* _WinButtonP_h */ + + diff --git a/controls/button.c b/controls/button.c new file mode 100644 index 00000000000..3a65bc027fa --- /dev/null +++ b/controls/button.c @@ -0,0 +1,86 @@ +/* + * Interface code to button widgets + * + * Copyright David W. Metcalfe, 1993 + * + */ + +static char Copyright[] = "Copyright David W. Metcalfe, 1993"; + +#include +#include +#include "WinButton.h" +#include "windows.h" +#include "heap.h" +#include "win.h" + +static void BUTTON_WinButtonCallback(Widget w, XtPointer client_data, + XtPointer call_data); + +void BUTTON_CreateButton(LPSTR className, LPSTR buttonLabel, HWND hwnd) +{ + WND *wndPtr = WIN_FindWndPtr(hwnd); + WND *parentPtr = WIN_FindWndPtr(wndPtr->hwndParent); + DWORD style; + char widgetName[15]; + +#ifdef DEBUG_BUTTON + printf("button: label = %s, x = %d, y = %d\n", buttonLabel, + wndPtr->rectClient.left, wndPtr->rectClient.top); + printf(" width = %d, height = %d\n", + wndPtr->rectClient.right - wndPtr->rectClient.left, + wndPtr->rectClient.bottom - wndPtr->rectClient.top); +#endif + + if (!wndPtr) + return; + + style = wndPtr->dwStyle & 0x0000000F; + + switch (style) + { + case BS_PUSHBUTTON: + case BS_DEFPUSHBUTTON: + sprintf(widgetName, "%s%d", className, wndPtr->wIDmenu); + wndPtr->winWidget = XtVaCreateManagedWidget(widgetName, + winButtonWidgetClass, + parentPtr->winWidget, + XtNlabel, buttonLabel, + XtNx, wndPtr->rectClient.left, + XtNy, wndPtr->rectClient.top, + XtNwidth, wndPtr->rectClient.right - + wndPtr->rectClient.left, + XtNheight, wndPtr->rectClient.bottom - + wndPtr->rectClient.top, + XtVaTypedArg, XtNbackground, XtRString, + "grey70", strlen("grey75")+1, + NULL); + + XtAddCallback(wndPtr->winWidget, XtNcallback, + BUTTON_WinButtonCallback, (XtPointer) hwnd); + break; + + default: + printf("CreateButton: Unsupported button style %lX\n", + wndPtr->dwStyle); + } + + GlobalUnlock(hwnd); + GlobalUnlock(wndPtr->hwndParent); +} + +static void BUTTON_WinButtonCallback(Widget w, XtPointer client_data, + XtPointer call_data) +{ + HWND hwnd = (HWND) client_data; + WND *wndPtr; + wndPtr = WIN_FindWndPtr(hwnd); + + CallWindowProc(wndPtr->lpfnWndProc, wndPtr->hwndParent, WM_COMMAND, + wndPtr->wIDmenu, MAKELPARAM(hwnd, BN_CLICKED)); + + GlobalUnlock(hwnd); +} + + + diff --git a/controls/widgets.c b/controls/widgets.c index f80a23ea12c..3c68d9cc782 100644 --- a/controls/widgets.c +++ b/controls/widgets.c @@ -7,6 +7,7 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "windows.h" +#include "win.h" static LONG WIDGETS_ButtonWndProc( HWND hwnd, WORD message, @@ -71,18 +72,20 @@ static LONG WIDGETS_ButtonWndProc( HWND hwnd, WORD message, return 0; case WM_PAINT: - { - HDC hdc; - PAINTSTRUCT ps; - RECT rect; - - hdc = BeginPaint( hwnd, &ps ); - GetClientRect( hwnd, &rect ); - DrawText(hdc, "Button", -1, &rect, - DT_SINGLELINE | DT_CENTER | DT_VCENTER ); - EndPaint( hwnd, &ps ); - return 0; - } + { + PAINTSTRUCT ps; + BeginPaint( hwnd, &ps ); + EndPaint( hwnd, &ps ); + return 0; + } + + case WM_COMMAND: + { + WND *wndParent; + wndParent = WIN_FindWndPtr(hwnd); + CallWindowProc(wndParent->lpfnWndProc, hwnd, message, wParam, lParam); + return 0; + } default: return DefWindowProc( hwnd, message, wParam, lParam ); diff --git a/if1632/Makefile b/if1632/Makefile index 1f12d6c9984..eac92189073 100644 --- a/if1632/Makefile +++ b/if1632/Makefile @@ -1,9 +1,10 @@ CFLAGS=$(COPTS) $(DEBUGOPTS) -I$(INCLUDE_DIR) BUILDOBJS=dll_kernel.o dll_user.o dll_gdi.o dll_unixlib.o \ - dll_win87em.o dll_shell.o \ + dll_win87em.o dll_shell.o dll_sound.o dll_keyboard.o\ dll_kernel_tab.o dll_user_tab.o dll_gdi_tab.o dll_unixlib_tab.o \ - dll_win87em_tab.o dll_shell_tab.o + dll_win87em_tab.o dll_shell_tab.o \ + dll_sound_tab.o dll_keyboard_tab.o MUST_BE_LINKED_FIRST=call.o $(BUILDOBJS) @@ -35,9 +36,19 @@ dll_win87em.S dll_win87em_tab.c: ../tools/build win87em.spec dll_shell.S dll_shell_tab.c: ../tools/build shell.spec ../tools/build shell.spec +dll_sound.S dll_sound_tab.c: ../tools/build sound.spec + ../tools/build sound.spec + +dll_keyboard.S dll_keyboard_tab.c: ../tools/build keyboard.spec + ../tools/build keyboard.spec + depend: $(CC) $(CFLAGS) -M *.c > .depend ifeq (.depend,$(wildcard .depend)) include .depend endif + + + + diff --git a/if1632/call.S b/if1632/call.S index c5e9e05da49..e09c1f5f19f 100644 --- a/if1632/call.S +++ b/if1632/call.S @@ -1,6 +1,12 @@ /* * Copyright Robert J. Amstadt, 1993 */ +#ifdef linux +#define UDATASEL 0x2b +#endif +#ifdef __NetBSD__ +#define UDATASEL 0x27 +#endif .data jump_target: return_value: @@ -95,7 +101,11 @@ _CallToInit16: movw %ax,%ss movl %esp,%eax movl %eax,%ebp - +#if 1 + movw $ UDATASEL,%ax + movw %ax,%fs + movw %ax,%gs +#endif /* * Call entry point */ @@ -114,7 +124,7 @@ _CallToInit16: * GDT usage. */ pushl %eax - movw $0x2b,%ax + movw $ UDATASEL,%ax movw %ax,%ds movw %ax,%es movw %ax,%fs @@ -194,7 +204,7 @@ _CallTo16: * GDT usage. */ pushl %eax - movw $0x2b,%ax + movw $ UDATASEL,%ax movw %ax,%ds movw %ax,%es movw %ax,%fs @@ -249,7 +259,7 @@ _CallTo32: * Restore segment registers. */ pushl %eax - movw $0x2b,%ax + movw $ UDATASEL,%ax movw %ax,%ds movw %ax,%es popl %eax diff --git a/if1632/gdi.spec b/if1632/gdi.spec index f0810fe6ca6..6af75c1f901 100644 --- a/if1632/gdi.spec +++ b/if1632/gdi.spec @@ -111,6 +111,7 @@ length 490 105 pascal SelectVisRgn(word word) SelectVisRgn(1 2) 106 pascal SetBitmapBits(word long ptr) SetBitmapBits(1 2 3) 117 pascal SetDCOrg(word s_word s_word) SetDCOrg(1 2 3) +128 pascal MulDiv(s_word s_word s_word) MulDiv(1 2 3) 129 pascal SaveVisRgn(word) SaveVisRgn(1) 130 pascal RestoreVisRgn(word) RestoreVisRgn(1) 131 pascal InquireVisRgn(word) InquireVisRgn(1) diff --git a/if1632/kernel.spec b/if1632/kernel.spec index 655d8d79483..bfeb1b4a7ae 100644 --- a/if1632/kernel.spec +++ b/if1632/kernel.spec @@ -2,7 +2,7 @@ # name kernel id 1 -length 410 +length 415 3 return GetVersion 0 0x301 4 pascal LocalInit(word word word) LocalInit(1 2 3) @@ -32,6 +32,11 @@ length 410 50 pascal GetProcAddress(word ptr) GetProcAddress(1 2) 51 pascal MakeProcInstance(ptr word) CALLBACK_MakeProcInstance(1 2) 52 pascal FreeProcInstance(ptr) FreeProcInstance(1) +74 pascal OpenFile(ptr ptr word) KERNEL_OpenFile(1 2 3) +81 pascal _lclose(word) KERNEL__lclose(1) +82 pascal _lread(word ptr word) KERNEL__lread(1 2 3) +85 pascal _lopen(ptr word) KERNEL__lopen(1 2) +86 pascal _lwrite(word ptr word) KERNEL__lwrite(1 2 3) 91 register InitTask(word word word word word word word word word word) KERNEL_InitTask() @@ -40,6 +45,7 @@ length 410 KERNEL_DOS3Call() 111 pascal GlobalWire(word) GlobalLock(1) 112 pascal GlobalUnWire(word) GlobalUnlock(1) +115 pascal OutputDebugString(ptr) OutputDebugString(1) 121 return LocalShrink 4 0 127 pascal GetPrivateProfileInt(ptr ptr s_word ptr) GetPrivateProfileInt(1 2 3 4) @@ -57,3 +63,6 @@ length 410 192 pascal GlobalPageUnlock(word) GlobalUnlock(1) 197 pascal GlobalFix(word) GlobalLock(1) 198 pascal GlobalUnfix(word) GlobalUnlock(1) +57 pascal GetProfileInt(ptr ptr word) GetProfileInt(1 2 3) +58 pascal GetProfileString(ptr ptr ptr ptr word) GetProfileString(1 2 3 4 5) +199 pascal SetHandleCount(word) SetHandleCount(1) diff --git a/if1632/keyboard.spec b/if1632/keyboard.spec new file mode 100644 index 00000000000..e090c343063 --- /dev/null +++ b/if1632/keyboard.spec @@ -0,0 +1,27 @@ +# $Id: keyboard.spec,v 1.1 1993/09/10 05:32:12 scott Exp $ +# +name keyboard +id 8 +length 137 + +#1 pascal Inquire +#2 pascal Enable +#3 pascal Disable +4 pascal ToAscii(word word ptr ptr word) ToAscii(1 2 3 4 5) +5 pascal AnsiToOem(ptr ptr) AnsiToOem(1 2) +6 pascal OemToAnsi(ptr ptr) OemToAnsi(1 2) +#7 pascal SetSpeed +#100 pascal ScreenSwitchEnable +#126 pascal GetTableSeg +#127 pascal NewTable +128 pascal OemKeyScan(word) OemKeyScan(1) +129 pascal VkKeyScan(byte) VkKeyScan(1) +130 pascal GetKeyboardType(byte) GetKeyboardType(1) +131 pascal MapVirtualKey(word word) MapVirtualKey(1 2) +132 pascal GetKbCodePage() GetKbCodePage() +133 pascal GetKeyNameText(long ptr word) GetKeyNameText(1 2 3) +134 pascal AnsiToOemBuff(ptr ptr word) AnsiToOemBuff(1 2 3) +135 pascal OemToAnsiBuff(ptr ptr word) OemToAnsiBuff(1 2 3) +#136 pascal EnableKbSysReq +#137 pascal GetBiosKeyProc + diff --git a/if1632/relay.c b/if1632/relay.c index 1c8691c9ef8..cf93fe74997 100644 --- a/if1632/relay.c +++ b/if1632/relay.c @@ -7,17 +7,19 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include #include #include +#ifdef linux #include #include #include #include +#endif #include #include "neexe.h" #include "segmem.h" #include "prototypes.h" #include "dlls.h" -#define N_BUILTINS 6 +#define N_BUILTINS 8 struct dll_name_table_entry_s dll_builtin_table[N_BUILTINS] = { @@ -27,6 +29,8 @@ struct dll_name_table_entry_s dll_builtin_table[N_BUILTINS] = { "UNIXLIB", UNIXLIB_table, 10, 4 }, { "WIN87EM", WIN87EM_table, 10, 5 }, { "SHELL", SHELL_table, 256, 6 }, + { "SOUND", SOUND_table, 20, 7 }, + { "KEYBOARD",KEYBOARD_table,137, 8 }, }; unsigned short *Stack16Frame; @@ -239,3 +243,40 @@ ReturnArg(int arg) { return arg; } + +#ifdef WINESTAT +void winestat(){ + int i, j; + double perc; + int used, implemented; + int tused, timplemented; + struct dll_table_entry_s *table; + + tused = 0; + timplemented = 0; + for (i = 0; i < N_BUILTINS; i++) { + table = dll_builtin_table[i].dll_table; + used = 0; + implemented = 0; + for(j=0; j < dll_builtin_table[i].dll_table_length; j++) { + if(table[j].used){ + used++; + if (table[j].handler) implemented++; + else + printf("%s.%d\n", + dll_builtin_table[i].dll_name, + j); + }; + }; + tused += used; + timplemented += implemented; + if(used) + perc = implemented * 100.00 / used; + else + perc = 0.0; + printf("%s: %d %d %3.1f\n", dll_builtin_table[i].dll_name, implemented, used, perc); + }; + perc = timplemented * 100.00 / tused; + printf("TOTAL: %d %d %3.1f\n",timplemented, tused, perc); +} +#endif /* WINESTAT */ diff --git a/if1632/shell.spec b/if1632/shell.spec index 436d68bcf24..0a027573509 100644 --- a/if1632/shell.spec +++ b/if1632/shell.spec @@ -1,5 +1,5 @@ # $Id: shell.spec,v 1.3 1993/07/04 04:04:21 root Exp root $ # name shell -id 5 +id 6 length 256 diff --git a/if1632/sound.spec b/if1632/sound.spec new file mode 100644 index 00000000000..0e7d0126e34 --- /dev/null +++ b/if1632/sound.spec @@ -0,0 +1,17 @@ +# $Id: win87em.spec,v 1.3 1993/07/04 04:04:21 root Exp root $ +# +name sound +id 7 +length 20 + +1 pascal OPENSOUND() OpenSound() +2 pascal CLOSESOUND() CloseSound() +3 pascal SETVOICEQUEUESIZE(word word) SetVoiceQueueSize(1 2) +4 pascal SETVOICENOTE(word word word word) SetVoiceNote(1 2 3 4) +5 pascal SETVOICEACCENT(word word word word word) + SetVoiceAccent(1 2 3 4 5) +6 pascal SETVOICEENVELOPE(word word word) SetVoiceEnvelope(1 2 3) +7 pascal SETSOUNDNOISE(word word) SetSoundNoise(1 2) +8 pascal SETVOICESOUND(word long word) SetVoiceSound(1 2 3) +9 pascal STARTSOUND() StartSound() +10 pascal STOPSOUND() StopSound() diff --git a/if1632/user.spec b/if1632/user.spec index 575926b15ab..1da0c4d0198 100644 --- a/if1632/user.spec +++ b/if1632/user.spec @@ -83,3 +83,5 @@ length 540 373 pascal SubtractRect(ptr ptr ptr) SubtractRect(1 2 3) 403 pascal UnregisterClass(ptr word) UnregisterClass(1 2) 411 pascal AppendMenu(word word word ptr) AppendMenu(1 2 3 4) +177 pascal LoadAccelerators(word ptr) LoadAccelerators(1 2) +421 pascal wvsprintf(ptr ptr ptr) wvsprintf(1 2 3) diff --git a/if1632/win87em.spec b/if1632/win87em.spec index 11c57207887..6e71cbc8da4 100644 --- a/if1632/win87em.spec +++ b/if1632/win87em.spec @@ -3,3 +3,9 @@ name win87em id 5 length 10 + +1 register _fpMath(word word word word + word word word word) WIN87_fpmath() +3 pascal __WinEm87Info(ptr word) WIN87_WinEm87Info(1 2) +4 pascal __WinEm87Restore(ptr word) WIN87_WinEm87Restore(1 2) +5 pascal __WinEm87Save(ptr word) WIN87_WinEm87Save(1 2) diff --git a/include/dlls.h b/include/dlls.h index a4c44839739..a0af4b0420c 100644 --- a/include/dlls.h +++ b/include/dlls.h @@ -36,6 +36,9 @@ struct dll_table_entry_s char *export_name; void *handler; /* Address of function to process request */ int handler_type; /* C or PASCAL calling convention */ +#ifdef WINESTAT + int used; /* Number of times this function referenced */ +#endif int n_args; /* Number of arguments passed to function */ DLL_ARG args[DLL_MAX_ARGS]; /* Argument conversion data */ }; @@ -54,5 +57,7 @@ extern struct dll_table_entry_s GDI_table[]; extern struct dll_table_entry_s UNIXLIB_table[]; extern struct dll_table_entry_s WIN87EM_table[]; extern struct dll_table_entry_s SHELL_table[]; +extern struct dll_table_entry_s SOUND_table[]; +extern struct dll_table_entry_s KEYBOARD_table[]; #endif /* DLLS_H */ diff --git a/include/neexe.h b/include/neexe.h index deb99ab7d0f..e610ba45ad0 100644 --- a/include/neexe.h +++ b/include/neexe.h @@ -136,6 +136,7 @@ struct relocation_entry_s /* Used by Windows 3.0 programs, like when getting selector to be given to makeprocinst */ #define NE_RELTYPE_INT1 4 +#define NE_RELTYPE_OFFSET16 5 /* * DOS PSP */ diff --git a/include/windows.h b/include/windows.h index 9d74b29e335..278770b7540 100644 --- a/include/windows.h +++ b/include/windows.h @@ -45,6 +45,9 @@ typedef int *LPCATCHBUF; #define NULL (void *)0 #endif +#define MAKELPARAM(low, high) ((LONG)(((WORD)(low)) | \ + (((DWORD)((WORD)(high))) << 16))) + typedef struct { short left, top, right, bottom; } RECT; typedef RECT *LPRECT; typedef RECT *NPRECT; @@ -697,6 +700,20 @@ typedef OFSTRUCT *LPOFSTRUCT; #define OF_READ 0x0000 #define OF_WRITE 0x0001 #define OF_READWRITE 0x0002 +#define OF_CANCEL 0x0800 +#define OF_CREATE 0x1000 +#define OF_DELETE 0x0200 +#define OF_EXIST 0x4000 +#define OF_PARSE 0x0100 +#define OF_PROMPT 0x2000 +#define OF_REOPEN 0x8000 +#define OF_SHARE_COMPAT 0x0000 +#define OF_SHARE_DENY_NONE 0x0040 +#define OF_SHARE_DENY_READ 0x0030 +#define OF_SHARE_DENY_WRITE 0x0020 +#define OF_SHARE_EXCLUSIVE 0x0010 +#define OF_VERIFY 0x0400 + typedef struct { @@ -905,6 +922,29 @@ enum { SW_HIDE, SW_SHOWNORMAL, SW_NORMAL, SW_SHOWMINIMIZED, SW_SHOWMAXIMIZED, #define WS_CHILDWINDOW (WS_CHILD) #define WS_TILEDWINDOW (WS_OVERLAPPEDWINDOW) +/* Button control styles */ +#define BS_PUSHBUTTON 0x00000000L +#define BS_DEFPUSHBUTTON 0x00000001L +#define BS_CHECKBOX 0x00000002L +#define BS_AUTOCHECKBOX 0x00000003L +#define BS_RADIOBUTTON 0x00000004L +#define BS_3STATE 0x00000005L +#define BS_AUTO3STATE 0x00000006L +#define BS_GROUPBOX 0x00000007L +#define BS_USERBUTTON 0x00000008L +#define BS_AUTORADIOBUTTON 0x00000009L +#define BS_OWNERDRAW 0x0000000BL +#define BS_LEFTTEXT 0x00000020L + +/* Button notification codes */ +#define BN_CLICKED 0 +#define BN_PAINT 1 +#define BN_HILITE 2 +#define BN_UNLITE 3 +#define BN_DISABLE 4 +#define BN_DOUBLECLICKED 5 + + #define GMEM_MOVEABLE 0x0002 #define F(ret,name) ret name(void); diff --git a/loader/dump.c b/loader/dump.c index 96b1c44929b..42fee12c923 100644 --- a/loader/dump.c +++ b/loader/dump.c @@ -7,9 +7,11 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include #include #include +#ifdef linux #include #include #include +#endif #include #include "neexe.h" #include "segmem.h" diff --git a/loader/ldt.c b/loader/ldt.c index 326ac5edfd0..235f1eb50df 100644 --- a/loader/ldt.c +++ b/loader/ldt.c @@ -4,27 +4,35 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include #include #include -#include -#include -#include + #include "prototypes.h" +#ifdef __NetBSD__ +#include +#endif /********************************************************************** * print_ldt */ +/* XXX These are *real* 386 descriptors !! */ void print_ldt() { char buffer[0x10000]; - struct modify_ldt_ldt_s ldt_info; unsigned long *lp; unsigned long base_addr, limit; int type, dpl, i; +#ifdef __NetBSD__ + struct segment_descriptor *sd; +#endif if (get_ldt(buffer) < 0) exit(1); lp = (unsigned long *) buffer; +#ifdef __NetBSD__ + sd = (struct segment_descriptor *) buffer; +#endif + for (i = 0; i < 32; i++, lp++) { /* First 32 bits of descriptor */ @@ -35,9 +43,15 @@ print_ldt() /* First 32 bits of descriptor */ base_addr |= (*lp & 0xFF000000) | ((*lp << 16) & 0x00FF0000); limit |= (*lp & 0x000F0000); - type = (*lp >> 9) & 7; +#ifdef linux + type = (*lp >> 10) & 5; dpl = (*lp >> 13) & 3; - +#endif +#ifdef __NetBSD__ + type = sd->sd_type; + dpl = sd->sd_dpl; + sd++; +#endif if (*lp & 1000) { printf("Entry %2d: Base %08.8x, Limit %05.5x, DPL %d, Type %d\n", diff --git a/loader/ldtlib.c b/loader/ldtlib.c index 4eeec36ba9d..65bf92ced2d 100644 --- a/loader/ldtlib.c +++ b/loader/ldtlib.c @@ -4,16 +4,66 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include #include #include +#ifdef linux #include #include #include _syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount) +#endif +#ifdef __NetBSD__ +#include +extern int i386_get_ldt(int, union descriptor *, int); +extern int i386_set_ldt(int, union descriptor *, int); + +struct segment_descriptor * +make_sd(unsigned base, unsigned limit, int contents, int read_exec_only, int seg32, int inpgs) +{ +#if 1 + static long d[2]; + + d[0] = ((base & 0x0000ffff) << 16) | + (limit & 0x0ffff); + d[1] = (base & 0xff000000) | + ((base & 0x00ff0000)>>16) | + (limit & 0xf0000) | + (contents << 10) | + ((read_exec_only ^ 1) << 9) | + (seg32 << 22) | + (inpgs << 23) | + 0xf000; + + printf("%x %x\n", d[1], d[0]); + + return ((struct segment_descriptor *)d); +#else + static struct segment_descriptor d; + + d.sd_lolimit = limit & 0x0000ffff; + d.sd_lobase = base & 0x00ffffff; + d.sd_type = contents & 0x01f; + d.sd_dpl = SEL_UPL & 0x3; + d.sd_p = 1; + d.sd_hilimit = (limit & 0x00ff0000) >> 16; + d.sd_xx = 0; + d.sd_def32 = seg32?1:0; + d.sd_gran = inpgs?1:0; + d.sd_hibase = (base & 0xff000000) >> 24; + return ((struct segment_descriptor *)&d); +#endif +} +#endif + int get_ldt(void *buffer) { +#ifdef linux return modify_ldt(0, buffer, 32 * sizeof(struct modify_ldt_ldt_s)); +#endif +#ifdef __NetBSD__ + return i386_get_ldt(0, (union descriptor *)buffer, 32); +#endif } int @@ -21,6 +71,7 @@ set_ldt_entry(int entry, unsigned long base, unsigned int limit, int seg_32bit_flag, int contents, int read_only_flag, int limit_in_pages_flag) { +#ifdef linux struct modify_ldt_ldt_s ldt_info; ldt_info.entry_number = entry; @@ -32,4 +83,24 @@ set_ldt_entry(int entry, unsigned long base, unsigned int limit, ldt_info.limit_in_pages = limit_in_pages_flag; return modify_ldt(1, &ldt_info, sizeof(ldt_info)); +#endif +#ifdef __NetBSD__ + struct segment_descriptor *sd; + int ret; + +#ifdef DEBUG + printf("set_ldt_entry: entry=%x base=%x limit=%x%s %s-bit contents=%d %s\n", + entry, base, limit, limit_in_pages_flag?"-pages":"", + seg_32bit_flag?"32":"16", + contents, read_only_flag?"read-only":""); +#endif + + sd = make_sd(base, limit, contents, read_only_flag, seg_32bit_flag, limit_in_pages_flag); + ret = i386_set_ldt(entry, (union descriptor *)sd, 1); + if (ret < 0) + perror("i386_set_ldt"); + + return ret; + +#endif } diff --git a/loader/resource.c b/loader/resource.c index f469a483879..4a3c60eef9c 100644 --- a/loader/resource.c +++ b/loader/resource.c @@ -274,6 +274,7 @@ LoadString(HANDLE instance, WORD resource_id, LPSTR buffer, int buflen) HICON LoadIcon(HANDLE instance, LPSTR icon_name) { + fprintf(stderr,"LoadIcon: (%d),%d\n",instance,icon_name); return 0; } @@ -283,6 +284,17 @@ LoadIcon(HANDLE instance, LPSTR icon_name) HCURSOR LoadCursor(HANDLE instance, LPSTR cursor_name) { + fprintf(stderr,"LoadCursor: (%d),%d\n",instance,cursor_name); + return 0; +} + +/********************************************************************** + * LoadAccelerators + */ +HANDLE +LoadAccelerators(HANDLE instance, LPSTR lpTableName) +{ + fprintf(stderr,"LoadAccelerators: (%d),%d\n",instance,lpTableName); return 0; } diff --git a/loader/selector.c b/loader/selector.c index bff46c5a4a9..4ecb448f58f 100644 --- a/loader/selector.c +++ b/loader/selector.c @@ -7,17 +7,37 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include #include #include +#ifdef linux #include #include #include #include #include +#endif +#ifdef __NetBSD__ +#include +#endif #include #include "neexe.h" #include "segmem.h" #include "prototypes.h" #include "wine.h" + +#ifdef linux +#define DEV_ZERO +#define UTEXTSEL 0x23 +#endif + +#ifdef __NetBSD__ +#include +#define PAGE_SIZE getpagesize() +#define MODIFY_LDT_CONTENTS_DATA 0 +#define MODIFY_LDT_CONTENTS_STACK 1 +#define MODIFY_LDT_CONTENTS_CODE 2 +#define UTEXTSEL 0x1f +#endif + #define MAX_SELECTORS 512 static struct segment_descriptor_s * EnvironmentSelector = NULL; @@ -42,19 +62,21 @@ GetNextSegment(unsigned int flags, unsigned int limit) { struct segment_descriptor_s *selectors, *s; int sel_idx; +#ifdef DEV_ZERO FILE *zfile; +#endif sel_idx = next_unused_selector++; /* * Fill in selector info. */ - zfile = fopen("/dev/zero","r"); - s = malloc(sizeof(*s)); s->flags = NE_SEGFLAGS_DATA; s->selector = (sel_idx << 3) | 0x0007; s->length = limit; +#ifdef DEV_ZERO + zfile = fopen("/dev/zero","r"); s->base_addr = (void *) mmap((char *) (s->selector << 16), ((s->length + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)), @@ -62,6 +84,14 @@ GetNextSegment(unsigned int flags, unsigned int limit) MAP_FIXED | MAP_PRIVATE, fileno(zfile), 0); fclose(zfile); +#else + s->base_addr = (void *) mmap((char *) (s->selector << 16), + ((s->length + PAGE_SIZE - 1) & + ~(PAGE_SIZE - 1)), + PROT_EXEC | PROT_READ | PROT_WRITE, + MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0); + +#endif if (set_ldt_entry(sel_idx, (unsigned long) s->base_addr, (s->length - 1) & 0xffff, 0, @@ -99,6 +129,9 @@ unsigned int GetEntryDLLName(char * dll_name, char * function, int * sel, ordinal = FindOrdinalFromName(dll_table, function); *sel = dll_table[ordinal].selector; *addr = (unsigned int) dll_table[ordinal].address; +#ifdef WINESTAT + dll_table[ordinal].used++; +#endif return 0; }; @@ -136,6 +169,9 @@ unsigned int GetEntryDLLOrdinal(char * dll_name, int ordinal, int * sel, if(dll_table) { *sel = dll_table[ordinal].selector; *addr = (unsigned int) dll_table[ordinal].address; +#ifdef WINESTAT + dll_table[ordinal].used++; +#endif return 0; }; @@ -239,7 +275,11 @@ GetDOSEnvironment() * CreateEnvironment */ static struct segment_descriptor_s * +#ifdef DEV_ZERO CreateEnvironment(FILE *zfile) +#else +CreateEnvironment(void) +#endif { char *p; int sel_idx; @@ -248,17 +288,24 @@ CreateEnvironment(FILE *zfile) s = (struct segment_descriptor_s *) malloc(sizeof(struct segment_descriptor_s)); - sel_idx = next_unused_selector; + sel_idx = next_unused_selector++; /* * Create memory to hold environment. */ s->flags = NE_SEGFLAGS_DATA; - s->selector = (next_unused_selector++ << 3) | 0x0007; + s->selector = (sel_idx << 3) | 0x0007; s->length = PAGE_SIZE; +#ifdef DEV_ZERO s->base_addr = (void *) mmap((char *) (s->selector << 16), PAGE_SIZE, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, fileno(zfile), 0); +#else + s->base_addr = (void *) mmap((char *) (s->selector << 16), + PAGE_SIZE, + PROT_EXEC | PROT_READ | PROT_WRITE, + MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0); +#endif /* * Fill environment with meaningless babble. @@ -287,7 +334,11 @@ CreateEnvironment(FILE *zfile) * CreateThunks */ static struct segment_descriptor_s * +#ifdef DEV_ZERO CreateThunks(FILE *zfile) +#else +CreateThunks(void) +#endif { int sel_idx; struct segment_descriptor_s * s; @@ -295,17 +346,24 @@ CreateThunks(FILE *zfile) s = (struct segment_descriptor_s *) malloc(sizeof(struct segment_descriptor_s)); - sel_idx = next_unused_selector; + sel_idx = next_unused_selector++; /* * Create memory to hold environment. */ s->flags = 0; - s->selector = (next_unused_selector++ << 3) | 0x0007; + s->selector = (sel_idx << 3) | 0x0007; s->length = 0x10000; +#ifdef DEV_ZERO s->base_addr = (void *) mmap((char *) (s->selector << 16), s->length, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, fileno(zfile), 0); +#else + s->base_addr = (void *) mmap((char *) (s->selector << 16), + s->length, + PROT_EXEC | PROT_READ | PROT_WRITE, + MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0); +#endif /* @@ -324,7 +382,11 @@ CreateThunks(FILE *zfile) * CreatePSP */ static struct segment_descriptor_s * +#ifdef DEV_ZERO CreatePSP(FILE *zfile) +#else +CreatePSP(void) +#endif { struct dos_psp_s *psp; unsigned short *usp; @@ -336,17 +398,24 @@ CreatePSP(FILE *zfile) s = (struct segment_descriptor_s *) malloc(sizeof(struct segment_descriptor_s)); - sel_idx = next_unused_selector; + sel_idx = next_unused_selector++; /* * Create memory to hold PSP. */ s->flags = NE_SEGFLAGS_DATA; - s->selector = (next_unused_selector++ << 3) | 0x0007; + s->selector = (sel_idx << 3) | 0x0007; s->length = PAGE_SIZE; +#ifdef DEV_ZERO s->base_addr = (void *) mmap((char *) (s->selector << 16), PAGE_SIZE, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, fileno(zfile), 0); +#else + s->base_addr = (void *) mmap((char *) (s->selector << 16), + PAGE_SIZE, + PROT_EXEC | PROT_READ | PROT_WRITE, + MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0); +#endif /* * Fill PSP @@ -357,13 +426,13 @@ CreatePSP(FILE *zfile) psp->pspDispatcher[0] = 0x9a; usp = (unsigned short *) &psp->pspDispatcher[1]; *usp = (unsigned short) KERNEL_Ordinal_102; - *(usp + 1) = 0x23; + *(usp + 1) = UTEXTSEL; psp->pspTerminateVector[0] = (unsigned short) UNIXLIB_Ordinal_0; - psp->pspTerminateVector[1] = 0x0023; + psp->pspTerminateVector[1] = UTEXTSEL; psp->pspControlCVector[0] = (unsigned short) UNIXLIB_Ordinal_0; - psp->pspControlCVector[1] = 0x0023; + psp->pspControlCVector[1] = UTEXTSEL; psp->pspCritErrorVector[0] = (unsigned short) UNIXLIB_Ordinal_0; - psp->pspCritErrorVector[1] = 0x0023; + psp->pspCritErrorVector[1] = UTEXTSEL; psp->pspEnvironment = EnvironmentSelector->selector; p1 = psp->pspCommandTail; @@ -409,7 +478,9 @@ CreateSelectors(struct w_files * wpnt) int SelectorTableLength; int i; int status; +#ifdef DEV_ZERO FILE * zfile; +#endif int old_length, file_image_length; /* @@ -424,7 +495,9 @@ CreateSelectors(struct w_files * wpnt) * Step through the segment table in the exe header. */ s = selectors; +#ifdef DEV_ZERO zfile = fopen("/dev/zero","r"); +#endif for (i = 0; i < ne_header->n_segment_tab; i++, s++) { #ifdef DEBUG_SEGMENT @@ -497,11 +570,19 @@ CreateSelectors(struct w_files * wpnt) if (s->flags & NE_SEGFLAGS_EXECUTEONLY) read_only = 1; } +#ifdef DEV_ZERO s->base_addr = (void *) mmap((char *) (s->selector << 16), (s->length + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1), PROT_EXEC | PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, fileno(zfile), 0); +#else + s->base_addr = + (void *) mmap((char *) (s->selector << 16), + (s->length + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1), + PROT_EXEC | PROT_READ | PROT_WRITE, + MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0); +#endif if (seg_table[i].seg_data_offset != 0) { /* @@ -524,6 +605,11 @@ CreateSelectors(struct w_files * wpnt) ran_out++; return NULL; } +#ifdef DEBUG_SEGMENT + printf(" SELECTOR %04.4x, %s\n", + s->selector, + contents == MODIFY_LDT_CONTENTS_CODE ? "CODE" : "DATA"); +#endif /* * If this is the automatic data segment, then we must initialize * the local heap. @@ -543,12 +629,20 @@ CreateSelectors(struct w_files * wpnt) next_unused_selector += ne_header->n_segment_tab; if(!EnvironmentSelector) { +#ifdef DEV_ZERO EnvironmentSelector = CreateEnvironment(zfile); PSP_Selector = CreatePSP(zfile); MakeProcThunks = CreateThunks(zfile); +#else + EnvironmentSelector = CreateEnvironment(); + PSP_Selector = CreatePSP(); + MakeProcThunks = CreateThunks(); +#endif }; +#ifdef DEV_ZERO fclose(zfile); +#endif return selectors; } diff --git a/loader/wine.c b/loader/wine.c index 9abdfdcf21d..ad268249201 100644 --- a/loader/wine.c +++ b/loader/wine.c @@ -7,10 +7,12 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include #include #include +#ifdef linux #include #include #include #include +#endif #include #include #include "neexe.h" @@ -222,6 +224,9 @@ LoadImage(char * filename, char * modulename) _WinMain(int argc, char **argv) { int segment; +#ifdef WINESTAT + char * cp; +#endif struct w_files * wpnt; int cs_reg, ds_reg, ss_reg, ip_reg, sp_reg; int i; @@ -270,6 +275,16 @@ _WinMain(int argc, char **argv) ss_reg = wine_files->selector_table[wine_files->ne_header->ss-1].selector; sp_reg = wine_files->ne_header->sp; +#ifdef WINESTAT + cp = strrchr(argv[0], '/'); + if(!cp) cp = argv[0]; + else cp++; + if(strcmp(cp,"winestat") == 0) { + winestat(); + exit(0); + }; +#endif + init_wine_signals(); rv = CallToInit16(cs_reg << 16 | ip_reg, ss_reg << 16 | sp_reg, ds_reg); @@ -489,12 +504,13 @@ FixupSegment(struct w_files * wpnt, int segment_num) default: #ifndef DEBUG_FIXUP - printf("%d: ADDR TYPE %d, TYPE %d, OFFSET %04.4x, ", + fprintf(stderr,"%d: ADDR TYPE %d, TYPE %d, OFFSET %04.4x, ", i + 1, rep->address_type, rep->relocation_type, rep->offset); - printf("TARGET %04.4x %04.4x\n", rep->target1, rep->target2); + fprintf(stderr,"TARGET %04.4x %04.4x\n", rep->target1, rep->target2); #endif free(rep1); + return -1; } @@ -530,13 +546,15 @@ FixupSegment(struct w_files * wpnt, int segment_num) next_addr = *sp; *sp = (unsigned short) selector; sp = (unsigned short *) ((char *) sel->base_addr + next_addr); + if (rep->relocation_type == NE_RELTYPE_INT1) break; + } while (next_addr != 0xffff); break; default: -#ifdef DEBUG_FIXUP +#ifndef DEBUG_FIXUP printf("%d: ADDR TYPE %d, TYPE %d, OFFSET %04.4x, ", i + 1, rep->address_type, rep->relocation_type, rep->offset); diff --git a/misc/Makefile b/misc/Makefile index 4cbfdea18ad..faeeeb60880 100644 --- a/misc/Makefile +++ b/misc/Makefile @@ -1,6 +1,7 @@ CFLAGS=$(COPTS) $(DEBUGOPTS) -I$(INCLUDE_DIR) -OBJS=dos.o kernel.o user.o xt.o rect.o +OBJS=dos.o kernel.o user.o xt.o rect.o file.o sound.o emulate.o \ + keyboard.o profile.o default: misc.o diff --git a/misc/emulate.c b/misc/emulate.c new file mode 100644 index 00000000000..c53aaa9e70e --- /dev/null +++ b/misc/emulate.c @@ -0,0 +1,53 @@ +static char RCSId[] = "$Id: heap.c,v 1.3 1993/07/04 04:04:21 root Exp root $"; +static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; + +#include "prototypes.h" +#include "regfunc.h" + +struct Win87EmInfoStruct { + unsigned short Version; + unsigned short SizeSaveArea; + unsigned short WinDataSeg; + unsigned short WinCodeSeg; + unsigned short Have80x87; + unsigned short Unused; +}; + + + + +int +WIN87_fpmath() +{ + printf( "_fpmath: (%d)\n",_BX); + + + switch(_BX ) + { + case 11: + return 1; + default: + return 0; + } + +} + +int +WIN87_WinEm87Info(struct Win87EmInfoStruct *pWIS, int cbWin87EmInfoStruct) +{ + printf( "__WinEm87Info(%p,%d)\n",pWIS,cbWin87EmInfoStruct); +} + +int +WIN87_WinEm87Restore(void *pWin87EmSaveArea, int cbWin87EmSaveArea) +{ + printf( "__WinEm87Restore(%p,%d)\n",pWin87EmSaveArea,cbWin87EmSaveArea); +} + +int +WIN87_WinEm87Save(void *pWin87EmSaveArea, int cbWin87EmSaveArea) +{ + printf( "__WinEm87Save(%p,%d)\n",pWin87EmSaveArea,cbWin87EmSaveArea); +} + + diff --git a/misc/file.c b/misc/file.c new file mode 100644 index 00000000000..2a1388a8365 --- /dev/null +++ b/misc/file.c @@ -0,0 +1,208 @@ +/************************************************************************ + * FILE.C Copyright (C) 1993 John Burton + * + * File I/O routines for the Linux Wine Project. + * + * There are two main parts to this module - first there are the + * actual emulation functions, and secondly a routine for translating + * DOS filenames into UNIX style filenames. + * + * For each DOS drive letter, we need to store the location in the unix + * file system to map that drive to, and the current directory for that + * drive. + * + * Finally we need to store the current drive letter in this module. + * + * WARNING : Many options of OpenFile are not yet implemeted. + * + * + ************************************************************************/ + +#include +#include +#include +#include +#include +#include + +/*************************************************************************** + This structure stores the infomation needed for a single DOS drive + ***************************************************************************/ +struct DosDriveStruct +{ + char RootDirectory [256]; /* Unix base for this drive letter */ + char CurrentDirectory [256]; /* Current directory for this drive */ +}; + +/*************************************************************************** + Table for DOS drives + ***************************************************************************/ +struct DosDriveStruct DosDrives[] = +{ + {"/mnt/floppy1" , ""}, + {"/mnt/floppy2" , ""}, + {"/mnt/HardDisk", "/wine"}, + {"" , "/wine/Wine"} +}; + +#define NUM_DRIVES (sizeof (DosDrives) / sizeof (struct DosDriveStruct)) + + +/************************************************************************** + Global variable to store current drive letter (0 = A, 1 = B etc) + **************************************************************************/ +int CurrentDrive = 2; + +/************************************************************************** + ParseDOSFileName + + Return a fully specified DOS filename with the disk letter separated from + the path information. + **************************************************************************/ +void ParseDOSFileName (char *UnixFileName, char *DosFileName, int *Drive) +{ + int character; + + for (character = 0; character < strlen(DosFileName); character++) + { + if (DosFileName[character] == '\\') + DosFileName[character] = '/'; + } + + + if (DosFileName[1] == ':') + { + *Drive = DosFileName[0] - 'A'; + if (*Drive > 26) + *Drive = *Drive - 'a' + 'A'; + DosFileName = DosFileName + 2; + } + else + *Drive = CurrentDrive; + + if (DosFileName[0] == '/') + { + strcpy (UnixFileName, DosDrives[*Drive].RootDirectory); + strcat (UnixFileName, DosFileName); + return; + } + + strcpy (UnixFileName, DosDrives[*Drive].RootDirectory); + strcat (UnixFileName, DosDrives[*Drive].CurrentDirectory); + strcat (UnixFileName, "/"); + strcat (UnixFileName, DosFileName); + return; +} + + +/*************************************************************************** + _lopen + + Emulate the _lopen windows call + ***************************************************************************/ +WORD KERNEL__lopen (LPSTR lpPathName, WORD iReadWrite) +{ + char UnixFileName[256]; + int Drive; + int handle; + + ParseDOSFileName (UnixFileName, lpPathName, &Drive); + + + + handle = open (UnixFileName, iReadWrite); + +#ifdef DEBUG_FILE + fprintf (stderr, "_lopen: %s (Handle = %d)\n", UnixFileName, handle); +#endif + return handle; +} + +/*************************************************************************** + _lread + ***************************************************************************/ +WORD KERNEL__lread (WORD hFile, LPSTR lpBuffer, WORD wBytes) +{ + int result; + + result = read (hFile, lpBuffer, wBytes); +#ifdef DEBUG_FILE + fprintf(stderr, "_lread: hFile = %d, lpBuffer = %s, wBytes = %d\n", + hFile, lpBuffer, wBytes); +#endif + return result; +} + + +/**************************************************************************** + _lwrite +****************************************************************************/ +WORD KERNEL__lwrite (WORD hFile, LPSTR lpBuffer, WORD wBytes) +{ +#ifdef DEBUG_FILE + fprintf(stderr, "_lwrite: hFile = %d, lpBuffer = %s, wBytes = %d\n", + hFile, lpBuffer, wBytes); +#endif + return write (hFile, lpBuffer, wBytes); +} + +/*************************************************************************** + _lclose + ***************************************************************************/ +WORD KERNEL__lclose (WORD hFile) +{ + close (hFile); +} + +/************************************************************************** + OpenFile + + Warning: This is nearly totally untested. It compiles, that's it... + -SL 9/13/93 + **************************************************************************/ +WORD KERNEL_OpenFile (LPSTR lpFileName, LPOFSTRUCT ofs, WORD wStyle) +{ + int base,flags; + + fprintf(stderr,"Openfile(%s,,%d) ",lpFileName,wStyle); + + base=wStyle&0xF; + flags=wStyle&0xFFF0; + + flags&=0xFF0F; /* strip SHARE bits for now */ + flags&=0xD7FF; /* strip PROMPT & CANCEL bits for now */ + flags&=0x7FFF; /* strip REOPEN bit for now */ + flags&=0xFBFF; /* strib VERIFY bit for now */ + + if(flags&OF_CREATE) { base |=O_CREAT; flags &=0xEFFF; } + + fprintf(stderr,"now %d,%d\n",base,flags); + + if(flags&(OF_DELETE|OF_EXIST)) + { + fprintf(stderr,"Unsupported OpenFile option\n"); + return -1; + } + else + { + return KERNEL__lopen (lpFileName, wStyle); + } +} + +/************************************************************************** + SetHandleCount + + Changes the number of file handles available to the application. Since + Linux isn't limited to 20 files, this one's easy. - SL + **************************************************************************/ + +WORD SetHandleCount (WORD wNumber) +{ + printf("SetHandleCount(%d)\n",wNumber); + return((wNumber, %d)\n",lParam,nSize); + lpBuffer[0]=0; /* This key has no name */ + return 0; +} + +void AnsiToOemBuff(LPSTR lpAnsiStr, LPSTR lpOemStr, int nLength) +{ + printf("AnsiToOemBuff(%s,,%d)\n",lpAnsiStr,nLength); + strncpy(lpOemStr,lpAnsiStr,nLength); /* should translate... */ +} + +void OemToAnsiBuff(LPSTR lpOemStr, LPSTR lpAnsiStr, int nLength) +{ + printf("OemToAnsiBuff(%s,,%d)\n",lpOemStr,nLength); + strncpy(lpAnsiStr,lpOemStr,nLength); /* should translate... */ +} + + + + + + + + + + + + diff --git a/misc/profile.c b/misc/profile.c new file mode 100644 index 00000000000..2924bd65b24 --- /dev/null +++ b/misc/profile.c @@ -0,0 +1,40 @@ +static char RCSId[] = "$Id: profile.c,v 1.1 1993/09/13 16:42:32 scott Exp $"; +static char Copyright[] = "Copyright Alexandre Julliard, 1993"; + +#include "prototypes.h" +#include "windows.h" + + +WORD GetPrivateProfileInt( LPSTR section, LPSTR entry, + short defval, LPSTR filename ) +{ + printf( "GetPrivateProfileInt: %s %s %d %s\n", section, entry, defval, filename ); + return defval; +} + +short GetPrivateProfileString( LPSTR section, LPSTR entry, LPSTR defval, + LPSTR buffer, short count, LPSTR filename ) +{ + printf( "GetPrivateProfileString: %s %s %s %d %s\n", section, entry, defval, count, filename ); + strncpy( buffer, defval, count ); + buffer[count-1] = 0; + return strlen(buffer); +} + + +WORD GetProfileInt( LPSTR lpAppName, LPSTR lpKeyName, int nDefault) +{ + printf("GetProfileInt: %s %s %d\n",lpAppName,lpKeyName,nDefault); + return nDefault; +} + +int GetProfileString(LPSTR lpAppName, LPSTR lpKeyName, LPSTR lpDefault, + LPSTR lpReturnedString, int nSize) +{ + printf( "GetProfileString: %s %s %s %d \n", lpAppName,lpKeyName, + lpDefault, nSize ); + strncpy( lpReturnedString,lpDefault,nSize ); + lpReturnedString[nSize-1] = 0; + return strlen(lpReturnedString); + +} diff --git a/misc/sound.c b/misc/sound.c new file mode 100644 index 00000000000..90e9c7dc1b8 --- /dev/null +++ b/misc/sound.c @@ -0,0 +1,75 @@ +static char RCSId[] = "$Id: heap.c,v 1.3 1993/07/04 04:04:21 root Exp root $"; +static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; + +#include "prototypes.h" + +int OpenSound(void) +{ + printf("OpenSound()\n"); + return -1; +} + +void CloseSound(void) +{ + printf("CloseSound()\n"); +} + +int SetVoiceQueueSize(int nVoice, int nBytes) +{ + printf("SetVoiceQueueSize (%d,%d)\n",nVoice,nBytes); + return 0; +} + +int SetVoiceNote(int nVoice, int nValue, int nLength, int nCdots) +{ + printf("SetVoiceNote (%d,%d,%d,%d)\n",nVoice,nValue,nLength,nCdots); + return 0; +} + +int SetVoiceAccent(int nVoice, int nTempo, int nVolume, int nMode, int nPitch) +{ + printf("SetVoiceAccent(%d,%d,%d,%d,%d)\n", nVoice, nTempo, + nVolume, nMode, nPitch); + return 0; +} + +int SetVoiceEnvelope(int nVoice, int nShape, int nRepeat) +{ + printf("SetVoiceEnvelope(%d,%d,%d)\n",nVoice,nShape,nRepeat); + return 0; +} + +int SetSoundNoise(int nSource, int nDuration) +{ + printf("SetSoundNoise(%d,%d)\n",nSource,nDuration); + return 0; +} + +int SetVoiceSound(int nVoice, long lFrequency, int nDuration) +{ + printf("SetVoiceSound(%d, %d, %d)\n",nVoice,lFrequency, nDuration); + return 0; +} + +int StartSound(void) +{ + return 0; +} + +int StopSound(void) +{ + return 0; +} + + +/* +11 pascal WAITSOUNDSTATE(word) WaitSoundState(1) +12 pascal SYNCALLVOICES() SyncAllVoices() +13 pascal COUNTVOICENOTES(word) CountVoiceNotes(1) +14 pascal GETTHRESHOLDEVENT() GetThresholdEvent() +15 pascal GETTHRESHOLDSTATUS() GetThresholdStatus() +16 pascal SETVOICETHRESHOLD(word word) SetVoiceThreshold(1 2) + + + +*/ diff --git a/misc/xt.c b/misc/xt.c index e4075776e7d..3bb98bbd9e7 100644 --- a/misc/xt.c +++ b/misc/xt.c @@ -20,6 +20,9 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "class.h" #include "gdi.h" +#ifdef __NetBSD__ +#define HZ 100 +#endif Display * XT_display; Screen * XT_screen; @@ -146,21 +149,6 @@ void AdjustWindowRect( LPRECT rect, DWORD style, BOOL menu ) rect->right, rect->bottom, style, menu ); } -WORD GetPrivateProfileInt( LPSTR section, LPSTR entry, - short defval, LPSTR filename ) -{ - printf( "GetPrivateProfileInt: %s %s %d %s\n", section, entry, defval, filename ); - return defval; -} - -short GetPrivateProfileString( LPSTR section, LPSTR entry, LPSTR defval, - LPSTR buffer, short count, LPSTR filename ) -{ - printf( "GetPrivateProfileString: %s %s %s %d %s\n", section, entry, defval, count, filename ); - strncpy( buffer, defval, count ); - buffer[count-1] = 0; - return strlen(buffer); -} BOOL IsIconic( HWND hwnd ) { diff --git a/objects/linedda.c b/objects/linedda.c index f95ea48717e..6d8a1cfef84 100644 --- a/objects/linedda.c +++ b/objects/linedda.c @@ -6,8 +6,7 @@ static char Copyright[] = "Copyright Bob Amstadt, 1993"; -#include -#include +#include #include "win.h" /********************************************************************** @@ -16,4 +15,32 @@ static char Copyright[] = "Copyright Bob Amstadt, 1993"; void LineDDA(short nXStart, short nYStart, short nXEnd, short nYEnd, FARPROC callback, long lParam) { + int x, y; + int b; + int x_diff = nXEnd - nXStart; + int y_diff = nYEnd - nYStart; + + if (x_diff == 0 && y_diff == 0) + return; + + if ((abs(x_diff) < abs(y_diff) && x_diff != 0) || y_diff == 0) + { + b = (nXStart * y_diff) / x_diff - nYStart; + + for (x = nXStart; x <= nXEnd; x++) + { + y = (x * y_diff) / x_diff + b; + CallLineDDAProc(callback, x, y, lParam); + } + } + else + { + b = (nYStart * x_diff) / y_diff - nXStart; + + for (y = nYStart; y <= nYEnd; y++) + { + x = (y * x_diff) / y_diff + b; + CallLineDDAProc(callback, x, y, lParam); + } + } } diff --git a/objects/palette.c b/objects/palette.c index bdde29d0ce6..887f1defccd 100644 --- a/objects/palette.c +++ b/objects/palette.c @@ -7,7 +7,13 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include +#ifdef linux #include +#endif +#ifdef __NetBSD__ +#include +#define MAXINT INT_MAX +#endif #include #include "gdi.h" diff --git a/objects/text.c b/objects/text.c index 43b095a1f8d..97ff35b5b3f 100644 --- a/objects/text.c +++ b/objects/text.c @@ -23,11 +23,17 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; */ int DrawText( HDC hdc, LPSTR str, int count, LPRECT rect, WORD flags ) { + SIZE size; int x = rect->left, y = rect->top; - if (flags & DT_CENTER) x = (rect->left + rect->right) / 2; - if (flags & DT_VCENTER) y = (rect->top + rect->bottom) / 2; if (count == -1) count = strlen(str); + if (!GetTextExtentPoint( hdc, str, count, &size )) return 0; + + if (flags & DT_CENTER) x = (rect->left + rect->right - size.cx) / 2; + else if (flags & DT_RIGHT) x = rect->right - size.cx; + if (flags & DT_VCENTER) y = (rect->top + rect->bottom - size.cy) / 2; + else if (flags & DT_BOTTOM) y = rect->bottom - size.cy; + if (!TextOut( hdc, x, y, str, count )) return 0; return 1; } diff --git a/signal-diffs b/signal-diffs deleted file mode 100644 index 9b49973086b..00000000000 --- a/signal-diffs +++ /dev/null @@ -1,90 +0,0 @@ -diff -c -r linux.99pl12/linux//kernel/signal.c linux//kernel/signal.c -*** linux.99pl12/linux//kernel/signal.c Sat Aug 28 00:24:01 1993 ---- linux//kernel/signal.c Fri Aug 27 22:45:41 1993 -*************** -*** 195,201 **** - 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); ---- 195,202 ---- - COPY(eip); COPY(eflags); - COPY(ecx); COPY(edx); - COPY(ebx); -! regs->esp = context.esp_at_signal; /* Can be different with Wine */ -! COPY(ebp); - COPY(edi); COPY(esi); - COPY(cs); COPY(ss); - COPY(ds); COPY(es); -*************** -*** 353,360 **** - frame = (unsigned long *) regs->esp; - signr = 1; - sa = current->sigaction; -! if (regs->ss != USER_DS) -! printk("Warning: signal handler with nonstandard stack segment\n"); - for (mask = 1 ; mask ; sa++,signr++,mask += mask) { - if (mask > handler_signal) - break; ---- 354,360 ---- - frame = (unsigned long *) regs->esp; - signr = 1; - sa = current->sigaction; -! - for (mask = 1 ; mask ; sa++,signr++,mask += mask) { - if (mask > handler_signal) - break; -*************** -*** 365,370 **** ---- 365,381 ---- - 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)); -+ -+ /* If ss != USER_DS, we cannot rely upon the ss:esp as a */ -+ /* stack. We will instead use USER_DS:sa->sa_restorer */ -+ if (regs->ss != USER_DS) { -+ frame = (unsigned long *) sa->sa_restorer; -+ if(frame == NULL) { -+ printk("No signal handler stack available\n"); -+ do_exit(signr); -+ }; -+ }; -+ - setup_frame(&frame,eip,regs,signr,sa_handler,oldmask); - eip = sa_handler; regs->cs = USER_CS; - current->blocked |= sa->sa_mask; -*************** -*** 371,376 **** ---- 382,392 ---- - oldmask |= sa->sa_mask; - } - regs->esp = (unsigned long) frame; -+ /* When running the Wine program, the segment registers may be holding -+ unusual values */ -+ regs->ss = USER_DS; /* Make sure that this is correct */ -+ regs->ds = USER_DS; /* And the same here */ -+ regs->es = USER_DS; /* And here again */ - regs->eip = eip; /* "return" to the first handler */ - return 1; - } -diff -c -r linux.99pl12/linux//kernel/traps.c linux//kernel/traps.c -*** linux.99pl12/linux//kernel/traps.c Thu Aug 19 00:34:24 1993 ---- linux//kernel/traps.c Fri Aug 27 09:11:01 1993 -*************** -*** 66,71 **** ---- 66,76 ---- - - if ((regs->eflags & VM_MASK) || ((0xffff & regs->cs) == USER_CS)) - return; -+ -+ /* See if we are using the LDT. If so, pass along the signal. */ -+ if((7 & regs->cs) == 7 && current->ldt && (regs->cs >> 3) < 512) -+ 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", diff --git a/test/btnlook.c b/test/btnlook.c new file mode 100755 index 00000000000..d5b8dcd9fc3 --- /dev/null +++ b/test/btnlook.c @@ -0,0 +1,147 @@ +/*------------------------------------------ + BTNLOOK.C -- Button Look Program + ------------------------------------------*/ + +#include +#include + +struct +{ + long style; + char *text; +} +button[] = +{ + BS_PUSHBUTTON, "PUSHBUTTON", + BS_DEFPUSHBUTTON, "DEFPUSHBUTTON", +/* BS_CHECKBOX, "CHECKBOX", + BS_AUTOCHECKBOX, "AUTOCHECKBOX", + BS_RADIOBUTTON, "RADIOBUTTON", + BS_3STATE, "3STATE", + BS_AUTO3STATE, "AUTO3STATE", + BS_GROUPBOX, "GROUPBOX", + BS_USERBUTTON, "USERBUTTON", + BS_AUTORADIOBUTTON, "AUTORADIOBUTTON", + BS_PUSHBOX, "PUSHBOX" +*/}; + +#define NUM (sizeof button / sizeof button[0]) + +long FAR PASCAL _export WndProc(HWND, WORD, WORD, LONG); + +int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, + LPSTR lpszCmdParam, int nCmdShow) +{ + static char szAppName[] = "BtnLook"; + HWND hwnd; + MSG msg; + WNDCLASS wndclass; + + if (!hPrevInstance) + { + wndclass.style = CS_HREDRAW | CS_VREDRAW; + wndclass.lpfnWndProc = WndProc; + wndclass.cbClsExtra = 0; + wndclass.cbWndExtra = 0; + wndclass.hInstance = hInstance; + wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); + wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); + wndclass.hbrBackground = GetStockObject(WHITE_BRUSH); + wndclass.lpszMenuName = NULL; + wndclass.lpszClassName = szAppName; + + RegisterClass(&wndclass); + } + + hwnd = CreateWindow(szAppName, "Button Look", + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, + NULL, NULL, hInstance, NULL); + + ShowWindow(hwnd, nCmdShow); + UpdateWindow(hwnd); + + while (GetMessage(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + return msg.wParam; +} + +long FAR PASCAL _export WndProc(HWND hwnd, WORD message, WORD wParam, LONG lParam) +{ + static char szPrm[] = "wParam LOWORD(lParam) HIWORD(lParam)", + szTop[] = "Control ID Window Handle Notification", + szUnd[] = "__________ _____________ ____________", + szFormat[] = " %5u %4X %5u", + szBuffer[50]; + static HWND hwndButton[NUM]; + static RECT rect; + static int cxChar, cyChar; + HDC hdc; + PAINTSTRUCT ps; + int i; + TEXTMETRIC tm; + + switch (message) + { + case WM_CREATE: + hdc = GetDC(hwnd); + SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT)); + GetTextMetrics(hdc, &tm); + cxChar = tm.tmAveCharWidth; + cyChar = tm.tmHeight + tm.tmExternalLeading; + ReleaseDC(hwnd, hdc); + + for (i = 0; i < NUM; i++) + hwndButton[i] = CreateWindow("button", button[i].text, + WS_CHILD | WS_VISIBLE | button[i].style, + cxChar, cyChar * (1 + 2 * i), + 20 * cxChar, 7 * cyChar / 4, + hwnd, i, + ((LPCREATESTRUCT) lParam)->hInstance, NULL); + return 0; + + case WM_SIZE: + rect.left = 24 * cxChar; + rect.top = 3 * cyChar; + rect.right = LOWORD(lParam); + rect.bottom = HIWORD(lParam); + return 0; + + case WM_PAINT: + InvalidateRect(hwnd, &rect, TRUE); + + hdc = BeginPaint(hwnd, &ps); + SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT)); + SetBkMode(hdc, TRANSPARENT); + TextOut(hdc, 24 * cxChar, 1 * cyChar, szPrm, sizeof szPrm - 1); + TextOut(hdc, 24 * cxChar, 2 * cyChar, szTop, sizeof szTop - 1); + TextOut(hdc, 24 * cxChar, 2 * cyChar, szUnd, sizeof szUnd - 1); + + EndPaint(hwnd, &ps); + return 0; + + case WM_COMMAND: +/* ScrollWindow(hwnd, 0, -cyChar, &rect, &rect); */ + hdc = GetDC(hwnd); + SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT)); + + TextOut(hdc, 24 * cxChar, cyChar * 5, /* (rect.bottom / cyChar - 1), */ + szBuffer, sprintf(szBuffer, szFormat, wParam, + LOWORD(lParam), HIWORD(lParam))); + + ReleaseDC(hwnd, hdc); + ValidateRect(hwnd, NULL); + return 0; + + case WM_DESTROY: + PostQuitMessage(0); + return 0; + } + + return DefWindowProc(hwnd, message, wParam, lParam); +} + diff --git a/test/btnlook.exe b/test/btnlook.exe new file mode 100755 index 0000000000000000000000000000000000000000..b65a5edd08e7859443bfeed25a3f8fa2c59be2ac GIT binary patch literal 11827 zcmeHte|%KcnfG(=onK5K1c(6@W2h2-1Q3Zve#<18n?#1mIGN0V3UNp#B#_LcGk3y| z7ed&vLUN(icHL^%uDV)leW@?o)f%IvQ=nvP*R80nK)cFfcaUWr~h^G2#WjjDEH=< z$GkPIPjJ08?U6@(Ev>Plj%Z{qAA+c(^DYZVE+&Kc6W+R8 zD1*_QtkgW`YG+pS|4{NB9`u}KTpIja+G{DGp2DfrQ+5OOET2L>1%=e7X&${!X|mAz z({0jg!&1qwhCh3;G?`&*WmCw|A*LJp$o%ZB8O9F;QY-_OiDaXpLna;PW4KsAg8{9q z0Dn{QS4gQo@}#1sy~n?v^al=ZlVB&+L=Ec>A3i*4Up?C^iw87M>K@a}m}z_8{$(Et z>ig;kOFmStFYdluQ*w)YYlQ`WSn>}slln9D-Na!_`plB|l^fNQD5m10R?VVVi?s&P znm$sj1wejs_+`qfn5?T9TfA_C5VaKdZV)mGe*b3_3}h4}57(<_6KCi618V2kM3HGjrD^2#(PLEf2S&w|`PdKLy$M(n{4ag~${a2#B z>&_0ypRA{Xee!!5zZdqcCr@GD&4Q=zS5*3r$JcxQ8Y0_ap zPt*C(_i0AomrzF9Xba}YuT}Yc8bhM~e(fPU?LGd86Fo2d`tiisN_4&}SCz;1$d_I- z)9af}^Hl2+`I2Hw92QT1Hu#w^PupP6SX9sX`|>DbF_ZdXxIY6``N*?bC;CZlWiKE_>jO;UnuT#oA`mwO(2`eC$lm?){P`4=1{Y z#qD1!eWx@zST3-dDUg2lfW(RC8V{dhnXkYs{w~{IdfvYMgszW7YN7BsIsYN_ZyOC zSs;`q*B<5t=T|#zITzxE>0B*$fsm=DeftfGg(;p+{rIw0aEFjObUAhKa-z#Z@kyv{ z(+bK2tze;mHIRDY@|tyP4_VkE8jZf1QqOB^SvL;~Sj_oLZ~(KM)Yr7b47oJ5RXfbG zXoxB2!uIPDBdfclg8>B2=fvKJo);fi&!xu=eUKQLzjJWF@|>t?J!N?uN?}wq1pTQu zH1(*?VOAeis_RT|P5b8bZd$8rPn`XVKVVV2?1ff!oh@YFAz^@0IPyt8Sa>x4bniDyGez)aj8Y&B?a5WSc!V_*qMRd+p)2#C;!g$ z?wO;zmkXMD=-pH1#e#bBT`ae1p`5EmfBp1w;c-vu(~&i3uVq*9QbD`YN1|uQvJ_KB z(I8jGKZ=6XiB8sL+|B1dI5|tTNIpRfk^`@4+JfZymxhkjG#oD5W3C!;pN-#E zcdys7@8OMF$wf{%s@OEY9nCjGOvoq@x<1`^aHD3uZ_WLOEyE0Zx`tK!@3ic|gMa`nGz! zJ6+U$`N7zv-lwcm;_~E9X>gx(?94pv`;X-eCZz5wwE1GfJtCyvX7~p{G5vFfr@Om8 zFHxjD{?F5|B$`J)Oq)OuIrATf(B|u35qHZM zbCTPS9XqAIeeBe+Q_>+pzBpK_%l`Fl`9e-odF9%&3xkt2*vK0UX}jDbB%r1LHn>K6 z)t0uuYR6yR-w%o>kIJ9Z9{=UiclP)%Wm=ied)0naz9fK~VLVY))zfJ~r}9WKm#Nnw z+hy9<^*TmsV$M79+(g#}ijOTjY9@6cJqZ>~UQeKR;Bil{e92RnY9B7Js{RW(@9dBU z&(q))HV1wCy81Eu%e1>HDtgwLpuLEcyfSsNo-MGZ9=~#6@rwo4`%>Sy!m80CLI*DI zbN840ardvFaLKWqqIzubDVz^1qitmu7g*7_1s|35m|qiU@X*zA-AH^~nYxUt6b`e=+Bst_i90!^Pdp=EjAZl4D&`kN-U9 zl$>7qb4=&_+TuOtMAv!hvS-a{?(?bSusXz3e%-}BGn-syMquu3zT7<=iI3yjJF#HS zBkUzLL$k19u2{?9GkWrC`xS|Ub*DN&I@3zKp;FY zKh-kaD_>5nA6EV6(aaeoZ2o>1?HZ&05;m?wmBIR93=if}#`ig+zE4}Tp6~O}Z27Dte_GsQ zMkUNKYgJY8fSG8p0L%OwdVXMf>KB)>+~XI!yUu!cNU0;2t%;1MC+w-;`+J0m!u>IEdn(ZgHpV=0V`FKq4m>0*)$_eTJY_?pRzNO$4 zX3Ejx=2V2z&5L&AX4I}rETiqShMb~};&yewY^Fs{dtBy*jpi1rPFs)Do}Qncr#dZ? zd4+mz)}5XV)6?rTA-GPH5=Sgcjw<7ziNv@iu}aKKKUJD+SZC~2A_vS7XkETdJh)g$ zPaLWgB~onuR8U)^$s>uQdFntd7Td>|YI;ZYtsDnuQ(`IYu&X|clwYo1O6RDiCrS^M z971Hf2puaZK1X%gxz0`LF*WLm?z`=Ap-Me;4|JVN=cy+gU*M<%Xj68VW#!mE{izRl zZ^$^LDxnGSJgDo+@u#+HPt1}n*ZXa|n#6{Y0TY^EY3r%9>p{HJ(p$-WANNP>7l}(+ z+`deMe|fO5op8^wRV2>Z_!N*iB=Au?BXi;+WP1D~Jvc-{(#Dd~;6udSP`C;r-0>ma z5^YMLPvkSlRpBQy!j}+LS=bC=C37el!I3p%U<=pb(s8WX)~{*YuGy-52`jWm9_jH9 z`%~W?c|wqfC-_Iw=<6dR=n}*XkMvo=8TOcXKO(?RB4i>+uSkN7P zc<)G&hDj|fRi_@cVlnWv(NBbk=V0`GlIz(gn{X1e?2~Pt)W<`*yZ)pQ+kNVnDC0G_ z>+Bw!8#3Npf^`tJ>k;(5&j-l8SCMkxLR7A-la z9?eO1PV;jHqD7;kxe!%;4k_tS$x#kow$U{W7iBuf7XXO$o^*L)c^I)^Dxaz+ea=g9 zLgvjtD+o(#)<8J@m6umQZuAs6-lJ>T^$o0$ywz!wC-sg03m^LfKQ$3Ym%L1LG5b@} z}!mGU!s!LQtpvdLs#bf)TKxct|SIpSmjZnQ7`R$-A*9ppU8&S@7r-8PC=7L5+ zO`u-|y(oyZ9rQftY|xKES?|lBi$EU}GJ1NE{~_{QKwrX(-#U1%3_8|;t`H>Qwh01R zQGOGs8Po>K{yCY)`Tzg?H}HT!<&kJxFx*sBQBqPgx2Pi0u{GMdp+zaWebJ)Zi;TjW zu+lb9Z>|MnOL)OASHiAHWD{-n1o=)_e_XYJT5sjdHk~!AsHnQ;+B{W6!b&vKR#a12 zl)Wb|s)psZ5QN&#o{Fa58PAyJbow2uugTmQCr^D{ zb$PwdSL>!qr+iJWJgz8_aFO1D^*TnM4w(2K(HOkY8qZ>M)-H07GtWJMB4)Vp+=qMx zR+aH=M7|uGpYd$FDr&I)hf`bzKPcj#>1pxl|7TYxiK5ADvDs|-*O@2f7MLf9g|p_& zbV zBFfJf@~_LsBT~L(${%Ak9_D4A@sr2f0Im521}A^qD9X>Xj~_qYX3x*JL*^v5C8Ce${v>|GVIU--ltE!qkMJMS&qx#7{c60c=lFF3ks+nZyO-?Eo{9_!VgZ zKxL99P$@upk|xp}0GpCDiS7iLoy6}thGtHk(L37Nt#N_0j4GCCb}D7ZW2d=6##)G-HhIR#NH^CONQ?0$>W$UK5ID1B@^z z0T^cnm;-P#gSh~68E}AJ%-}YF7=!r$4>PzO;Bf{E0IstDlmaYZa0kEx4DJM&Xay(( zIGO`+7eM7$fQ0}j7%T!@c_%fnaf}~z&#A^2Jm3dhrftk zV&DLHn?X6iDFzh)xi}x-zyxP8a01-PKnBR;nN|fbkwG;;K7$&70tWX0OkuDR;06XR zfT;{t0TeQD0~9f+1-O-g#{l;lzzZ;)i|PQ18TbHZFsKKZ#lVkN`xyklS%9+-tp>P* z!5V-v2KNChWN<&gVg?TYY~!tCEx>jL>j0i(&;al}g9icHaEPNIK$yXLfDQ(Y01AU9 z1B3wHU``9xoCz6wD_p>f&At)q$5a>-v-!^^`@KnA?BeDUeZ@HJobMKaKIRXzcav( z4Dr7=z{`ePUNJa7&h8kNSB+k5&W?_?EjuXI_Uu?#JG1V!hO=I^ZpnJpx`Bi-yAi}P zo1Q?;6nu5&jYSB$GijwTo9-1#$S=&H2Zgy566VoH;Wla)=F?8$c6wA;Ku-##^t^B< zy(BE8KD-w83CrmZ!rgR1sGt#{l5C=bCWfcqEv_R~ zY@kQQ2kATFdU{4|q!+{%{I$|8QX9>d+UZUyOe>@a$x@8mQk>RGowQNfj9I>g9+I}w z)6zCNC~c?TNxNuJ`V0DZ=^+wK594nSm6>{InQ0%nOpj8)^i66rHD?{RLb!mnWaC{1 zJx$|vFEbs=M2Fak?Nb83TD%Q=jsS10#MO>z)JuZC5$GezQcxjMHx3s&!7_7(xmgAl zH!{4$GaT&nsGr&I5diqJ4%FwsLHdU&K&a30gY%k(?>CSqZ1EYPyliCz7G3Gg%-Mq_ zpm!2iCDw~brW?u0Qf!mDkpf+xNQG^@W(8~(tp7%RJ0`Own@4#&b{1$Y40HJ;t_*$P zck=FDK!uyBh&SKDEzDoQi?V?^}j4{$=3fe->7fs`*J;_{-2|Uyg@D8Ke)bvR~E+OE*z@RDO_{t?G@mPKKA=- zT(6%!^ExNI!_XU?{DhN(ocxr71)r*ts7knY0FUZ>JUsNF*HPnS=A9F zNl>DnbM`1F1DyN=C%@q2O-_Ev$v<-P77y4zaq=rp-sa>OC+~3bE+_AC@@r0h!xHav zavVt#Ly5hb8+3wsCpnJ%meKDx`DgSxS;SR7;OvK-oZ{qPkR+jvy#X(sM(|7W?A4c+ zaIerOj0h9OS>imgOsp1HiazlHF(@{PE#eE}4bn~0Ez%4r^W%Aq$z=+d+Mp9>9e0h- z;qmCy=crprvcu{vh^M=fu_pZ06FpPm7@lx z%AHj;?hN!gT~0@xv$BF<5h>ohGqw3EEvl=o4P=EYyw0ndyiiaFixnwNdt z*Z5XB>*^d;PO7Y_^EiAJ)kfaub-3$XkTw`Fbq(}6S0n55)>PC{ozqvoa#d}mlbBmu z?*qq$e$|%W!@YxGoey5hX5lc0%i#iHPdZ$(*Xhh4G*)LfG&Ht_g5h`voY>eBYTU$c zn!wReOo>E8+d|O@a!M%L-Wm=nA>gWzQd#A#t@jW*z6$Q5>?do~fC^h$6>7+&25HP@ z8x2NHt<&qpxHL3W*5ac!9k#}Tin0|fSFO9sSL*<(*GXF}6xxJbETqIcTDdWPj~8R) zgnV;zTRheR$|T6`ZqC$hRzjR>54AUTKq+K9*TXcwq@wK)yHxla%MPr#Oq)4nixG@q1_Y1t% zu+Bqiq=`lF!J>m(Ew=?XAnS@WZo)7vyvwLE;t^+!w(MZ%6sq>?x!5a!TmB*W9kHSrE2(XW@ z=4Fo`e$rcB*BA`@B2A-t2)0#pDx>*KTb1=~WPI&dVIT^_fx6q;I%4ch{i2R^2ah`Z zs_T{D2F%pViUeL&S4AM6T3+y*!%dBC!B~viV;iUiIf`v_bac3b7>CULU-o8@+C#Be za6^biudYj75l4%5QTcMQQE1MI%3q))JTn6D_Vk4YTTleDEhA(%G}+-9K6#U ziUP=yXnRlrsMnj}i*x{cqV3e&5s5XRpmkdaq`K1U_fmB=e>Pg}sHkwdNRL?ACRA4j zutJUga%Zcv;jmhdj|e{Qda6bZ0`xiL8doN!WFie!)VgZDUZ;%U#SYTDQ!Up5R(lYp zeLg2ud#l`3UGBxTB$!Udh;a@NRpT>NL?AS=0+s5#NOkqqdYrFD_^OAo>Kb>Q&*82B zLYv9qt6i0eP1O!}CCaN@wdD?1HdC#~FKE`8=&)YJ<*8s%mxoigp6ZFq>#VDHVf*kn zypB~A$dG#ONG0FllAe^WK_|*{17nVA4z{ .depend @@ -14,4 +16,4 @@ dummy: # ifeq (.depend,$(wildcard .depend)) include .depend -endif \ No newline at end of file +endif diff --git a/tools/build.c b/tools/build.c index 3ca44103480..00a550f139b 100644 --- a/tools/build.c +++ b/tools/build.c @@ -6,6 +6,13 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include #include +#ifdef linux +#define UTEXTSEL 0x23 +#endif +#ifdef __NetBSD__ +#define UTEXTSEL 0x1f +#endif + #define VARTYPE_BYTE 0 #define VARTYPE_SIGNEDWORD 0 #define VARTYPE_WORD 1 @@ -738,9 +745,12 @@ main(int argc, char **argv) { case FUNCTYPE_PASCAL: case FUNCTYPE_REG: - fprintf(fp, " { 0x23, %s_Ordinal_%d, ", UpperDLLName, i); + fprintf(fp, " { 0x%x, %s_Ordinal_%d, ", UTEXTSEL, UpperDLLName, i); fprintf(fp, "\042%s\042, ", odp->export_name); fprintf(fp, "%s, DLL_HANDLERTYPE_PASCAL, ", fdp->internal_name); +#ifdef WINESTAT + fprintf(fp, "0, "); +#endif fprintf(fp, "%d, ", fdp->n_args_32); if (fdp->n_args_32 > 0) { @@ -759,9 +769,12 @@ main(int argc, char **argv) break; case FUNCTYPE_C: - fprintf(fp, " { 0x23, %s_Ordinal_%d, ", UpperDLLName, i); + fprintf(fp, " { 0x%x, %s_Ordinal_%d, ", UTEXTSEL, UpperDLLName, i); fprintf(fp, "\042%s\042, ", odp->export_name); fprintf(fp, "%s, DLL_HANDLERTYPE_C, ", fdp->internal_name); +#ifdef WINESTAT + fprintf(fp, "0, "); +#endif fprintf(fp, "%d, ", fdp->n_args_32); if (fdp->n_args_32 > 0) { @@ -780,8 +793,8 @@ main(int argc, char **argv) break; default: - fprintf(fp, " { 0x23, %s_Ordinal_%d, \042\042, NULL },\n", - UpperDLLName, i); + fprintf(fp, " { 0x%x, %s_Ordinal_%d, \042\042, NULL },\n", + UTEXTSEL, UpperDLLName, i); break; } } diff --git a/windows/Makefile b/windows/Makefile index 0e6fe699634..2dc7616a137 100644 --- a/windows/Makefile +++ b/windows/Makefile @@ -1,7 +1,7 @@ CFLAGS=$(COPTS) $(DEBUGOPTS) -I$(INCLUDE_DIR) OBJS=class.o dc.o dce.o event.o message.o win.o timer.o graphics.o \ - clipping.o mapping.o painting.o keyboard.o + clipping.o mapping.o painting.o keyboard.o utility.o default: windows.o diff --git a/windows/class.c b/windows/class.c index 2cb42ec919d..17d36e06fae 100644 --- a/windows/class.c +++ b/windows/class.c @@ -25,7 +25,7 @@ HCLASS CLASS_FindClassByName( char * name, CLASS **ptr ) while(class) { *ptr = (CLASS *) USER_HEAP_ADDR(class); - if (!strcmp( (*ptr)->wc.lpszClassName, name )) return class; + if (!strcasecmp( (*ptr)->wc.lpszClassName, name )) return class; class = (*ptr)->hNext; } return 0; diff --git a/windows/dc.c b/windows/dc.c index 926b7cabbd0..1a65b415927 100644 --- a/windows/dc.c +++ b/windows/dc.c @@ -338,7 +338,6 @@ HDC CreateDC( LPSTR driver, LPSTR device, LPSTR output, LPSTR initData ) dc->w.planes = displayDevCaps->planes; dc->w.bitsPerPixel = displayDevCaps->bitsPixel; - XSetSubwindowMode( XT_display, dc->u.x.gc, IncludeInferiors ); DC_SetDeviceInfo( handle, dc ); return handle; diff --git a/windows/graphics.c b/windows/graphics.c index cc47f99813b..cf339b973d0 100644 --- a/windows/graphics.c +++ b/windows/graphics.c @@ -8,6 +8,9 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include #include +#ifndef PI +#define PI M_PI +#endif #include "gdi.h" diff --git a/windows/message.c b/windows/message.c index 45cca4a1013..a1288c5c54c 100644 --- a/windows/message.c +++ b/windows/message.c @@ -13,6 +13,10 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include +#ifdef __NetBSD__ +#define HZ 100 +#endif + #include "message.h" #include "win.h" diff --git a/windows/utility.c b/windows/utility.c new file mode 100644 index 00000000000..3c20d87b800 --- /dev/null +++ b/windows/utility.c @@ -0,0 +1,304 @@ +/* utility.c Utility functions for Wine + * Author: acb + * Commenced: 10-9-1993 + * + * This unit contains the implementations of + * various Windows API functions that perform + * utility tasks; i.e., that do not fit into + * any major category but perform useful tasks. + */ + +#include +#include +#include "windows.h" + +static char Copyright[] = "Copyright Andrew C. Bulhak, 1993"; + +/*#define debug_utility*/ + +/* MulDiv is a simple function that may as well have been + * implemented as a macro; however Microsoft, in their infinite + * wisdom, have implemented it as a DLL function and therefore + * so should we. + * Basically, it takes two 16-bit integers, multiplies them + * and divides by a third integer. + */ + +int MulDiv(int foo, int bar, int baz) +{ + return (long)(((int)foo*bar)/baz); +}; + +/* UTILITY_strip015() removes \015 (^M, CR) from a string; + * this is done to convert a MS-DOS-style string to a more + * UNIX-friendly format. Replacement is done in-place. + */ + +void UTILITY_strip015(char *dest) { + char *src = dest; + + while(*src) { + while(*src == '\015') src++; /* Skip \015s */ + while((*src) && (*src != '\015')) *(dest++) = *(src++); + }; + *dest = '\0'; /* Add null terminator */ +}; + +/* + * OutputDebugString strips CRs from its (string) parameter and + * calls DebugPrintString(), which was written by someone else. + * Since this is part of the standard Windows API, it needs no + * references to nonstandard DLLs. + */ + +void OutputDebugString(LPSTR foo) +{ + UTILITY_strip015(foo); + DebugPrintString(foo); +}; + +/* UTILITY_qualify(source, dest) takes the format string source and + * changes all the parameters to correspond to Linux integer sizes + * rather than Windows sizes. For example, it converts %i to %hi + * and %lx to %x. No array size checking is done at present. + */ + +static void UTILITY_qualify(const char *source, char *dest) +{ +#ifdef debug_utility + printf("UTILITY_qualify(\"%s\", \"%s\");\n", source, dest); +#endif + if(!source) return; /* Dumbass attack! */ + while(*source) { + /* Find next format code. */ + while((*source != '%') && (*source)) { + *(dest++) = *(source++); + } + /* Yeah, I know I shouldn't use gotos.... */ + if (!(*source)) goto loop_end; + /* skip the '%' */ + *(dest++) = *(source++); + /* Now insert a size qualifier, if needed. */ + switch(*source) { + case 'i': + case 'd': + case 'x': + case 'X': + case 'u': + case 'o': + /* We have a 16-bit value here. */ + *(dest++) = 'h'; + break; + }; + /* Here we go 'round the mulberry bush... */ +loop_end: + }; + *dest = '\0'; +}; + +/* UTILITY_argsize() evaluates the size of the argument list that + * accompanies a vsprintf() or wvsprintf() call. + * Arguments: + * char *format; printf-style format string. + * BOOL windows; if this is TRUE, we assume that ints are + * 16 bits in size; otherwise we deal with + * 32-bit variables. + * Returns: + * size (in bytes) of the arguments that follow the call. + */ + +size_t UTILITY_argsize(const char *format, BOOL windows) +{ + size_t size = 0; + +#define INT_SIZE (windows ? 2 : 4) + + while(*format) { + while((*format) && (*format != '%')) format++; /* skip ahead */ + if(*format) { + char modifier = ' '; +#ifdef debug_utility + printf("found:\t\"%%"); +#endif + format++; /* skip past '%' */ + /* First skip the flags, field width, etc. */ + /* First the flags */ + if ((*format == '#') || (*format == '-') || (*format == '+') + || (*format == ' ')) { +#ifdef debug_utility + printf("%c", *format); +#endif + format++; + } + /* Now the field width, etc. */ + while(isdigit(*format)) { +#ifdef debug_utility + printf("%c", *format); +#endif + format++; + } + if(*format == '.') { +#ifdef debug_utility + printf("%c", *format); +#endif + format++; + } + while(isdigit(*format)) { +#ifdef debug_utility + printf("%c", *format); +#endif + format++; + } + /* Now we handle the rest */ + if((*format == 'h') || (*format == 'l') || (*format == 'L')) { +#ifdef debug_utility + printf("%c", modifier); +#endif + modifier = *(format++); + } + /* Handle the actual type. */ +#ifdef debug_utility + printf("%c\"\n", *format); +#endif + switch(*format) { + case 'd': + case 'i': + case 'o': + case 'x': + case 'X': + case 'u': + case 'c': + size += ((modifier == 'l') ? 4 : INT_SIZE); + break; + case 's': size += sizeof(char *); break; + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': + /* It doesn't look as if Windows' wvsprintf() + supports floating-point arguments. However, + I'll leave this code here just in case. */ + size += (modifier == 'L') ? sizeof(long double) : sizeof(double); + break; + case 'p': size += sizeof(void *); break; + case 'n': size += sizeof(int *); break; + }; + }; + }; +#undef INT_SIZE +#ifdef debug_utility + printf("UTILITY_argsize: returning %i\n", size); +#endif + return size; +}; + +/* UTILITY_convertArgs() creates a 32-bit argument list from a 16-bit list. + * This is used to allow wvsprintf() arguments to be fed through + * vsprintf(). + * + * Arguments: + * char *fmt; format string + * char *winarg; Windows-style arguments + * + * Returns: + * malloc()ed pointer to new argument list. This should + * be free()d as soon as it is finished with. + */ + +char *UTILITY_convertArgs(char *format, char *winarg) +{ + char *result = (char *)malloc(UTILITY_argsize(format, 0)); + char *rptr = result; + + while(*format) { + while((*format) && (*format != '%')) format++; /* skip ahead */ + if(*format) { + char modifier = ' '; +#ifdef debug_utility + printf("found:\t\"%%"); +#endif + format++; /* skip past '%' */ + /* First skip the flags, field width, etc. */ + /* First the flags */ + if ((*format == '#') || (*format == '-') || (*format == '+') + || (*format == ' ')) format++; + /* Now the field width, etc. */ + while(isdigit(*format)) format++; + if(*format == '.') format++; + while(isdigit(*format)) format++; + /* Now we handle the rest */ + if((*format == 'h') || (*format == 'l') || (*format == 'L')) + modifier = *(format++); + /* Handle the actual type. */ +#ifdef debug_utility + printf("%c\"\n", *format); +#endif + switch(*format) { + case 'd': + case 'i': + *(((int *)rptr)++) = (modifier=='l') ? *(((int *)winarg)++) : *(((short *)winarg)++); + break; + case 'o': + case 'x': + case 'X': + case 'u': + case 'c': + *(((unsigned int *)rptr)++) = (modifier=='l') ? *(((unsigned int *)winarg)++) + : *(((unsigned short *)winarg)++); + break; + case 's': + case 'p': + case 'n': /* A pointer, is a pointer, is a pointer... */ + *(((char **)rptr)++) = *(((char **)winarg)++); + break; + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': + /* It doesn't look as if Windows' wvsprintf() + supports floating-point arguments. However, + I'll leave this code here just in case. */ + if(modifier=='L') + *(((long double *)rptr)++) = *(((long double *)winarg)++); + else *(((double *)rptr)++) = *(((double *)winarg)++); + break; + } + } + } + return result; +}; + +/* wvsprintf() is an implementation of vsprintf(). This + * implementation converts the arguments to 32-bit integers and + * calls the standard library function vsprintf(). + * + * Known shortcomings: + * wvsprintf() doesn't yet convert the arguments back after + * calling vsprintf(), so if Windows implements %n and a + * program depends on it, we're in trouble. + */ + +int wvsprintf(LPSTR buf, LPSTR format, LPSTR args) +{ + char qualified_fmt[1536]; + char *newargs; + int result; + + /* 1.5K is a safe value as wvsprintf can only handle buffers up to + 1K and in a worst case such a buffer would look like "%i%i%i..." */ + + if(!buf || !format) return 0; + + /* Change the format string so that ints are handled as short by + default */ + UTILITY_qualify(format, qualified_fmt); + + /* Convert agruments to 32-bit values */ + newargs = UTILITY_convertArgs(format, args); + + result = vsprintf(buf, qualified_fmt, newargs); + free(newargs); + return result; +}; diff --git a/windows/win.c b/windows/win.c index 615339a2ed7..6e2361eb1e3 100644 --- a/windows/win.c +++ b/windows/win.c @@ -21,6 +21,8 @@ extern Display * XT_display; static HWND firstWindow = 0; +void BUTTON_CreateButton(LPSTR className, LPSTR buttonLabel, HWND hwnd); + /*********************************************************************** * WIN_FindWndPtr @@ -99,7 +101,7 @@ HWND CreateWindow( LPSTR className, LPSTR windowName, { /* Check if parent is valid */ parentPtr = WIN_FindWndPtr( parent ); - if (!parentPtr) return 0; + if (!parent) return 0; } else if (style & WS_CHILD) return 0; /* WS_CHILD needs a parent */ @@ -160,10 +162,16 @@ HWND CreateWindow( LPSTR className, LPSTR windowName, /* Create the widgets */ - if (style & WS_CHILD) + if (!strcasecmp(className, "BUTTON")) { - wndPtr->shellWidget = 0; - wndPtr->winWidget = XtVaCreateManagedWidget(className, + BUTTON_CreateButton(className, windowName, hwnd); + } + else + { + if (style & WS_CHILD) + { + wndPtr->shellWidget = 0; + wndPtr->winWidget = XtVaCreateManagedWidget(className, coreWidgetClass, parentPtr->winWidget, XtNx, x, @@ -171,58 +179,61 @@ HWND CreateWindow( LPSTR className, LPSTR windowName, XtNwidth, width, XtNheight, height, NULL ); - } - else - { - wndPtr->shellWidget = XtVaAppCreateShell(className, + } + else + { + wndPtr->shellWidget = XtVaAppCreateShell(className, windowName, topLevelShellWidgetClass, XT_display, XtNx, x, XtNy, y, NULL ); - wndPtr->compositeWidget = XtVaCreateManagedWidget(className, + wndPtr->compositeWidget = XtVaCreateManagedWidget(className, formWidgetClass, wndPtr->shellWidget, NULL ); - if (wndPtr->wIDmenu == 0) - { - wndPtr->menuBarPtr = MENU_CreateMenuBar(wndPtr->compositeWidget, - instance, hwnd, - classPtr->wc.lpszMenuName, - width); - wndPtr->wIDmenu = - GlobalHandleFromPointer(wndPtr->menuBarPtr->firstItem); - } - else - { - wndPtr->menuBarPtr = MENU_UseMenu(wndPtr->compositeWidget, - instance, hwnd, - wndPtr->wIDmenu, width); - } + if (wndPtr->wIDmenu == 0) + { + wndPtr->menuBarPtr = + MENU_CreateMenuBar(wndPtr->compositeWidget, + instance, hwnd, + classPtr->wc.lpszMenuName, + width); + if (wndPtr->menuBarPtr) + wndPtr->wIDmenu = + GlobalHandleFromPointer(wndPtr->menuBarPtr->firstItem); + } + else + { + wndPtr->menuBarPtr = MENU_UseMenu(wndPtr->compositeWidget, + instance, hwnd, + wndPtr->wIDmenu, width); + } - if (wndPtr->menuBarPtr != NULL) - { - wndPtr->winWidget = - XtVaCreateManagedWidget(className, - compositeWidgetClass, - wndPtr->compositeWidget, - XtNwidth, width, - XtNheight, height, - XtNfromVert, - wndPtr->menuBarPtr->menuBarWidget, - XtNvertDistance, 4, - NULL ); - } - else - { - wndPtr->winWidget = - XtVaCreateManagedWidget(className, + if (wndPtr->menuBarPtr != NULL) + { + wndPtr->winWidget = + XtVaCreateManagedWidget(className, + compositeWidgetClass, + wndPtr->compositeWidget, + XtNwidth, width, + XtNheight, height, + XtNfromVert, + wndPtr->menuBarPtr->menuBarWidget, + XtNvertDistance, 4, + NULL ); + } + else + { + wndPtr->winWidget = + XtVaCreateManagedWidget(className, compositeWidgetClass, wndPtr->compositeWidget, XtNwidth, width, XtNheight, height, NULL ); + } } }