]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] Linux-0.98.4 (November 9, 1992) 0.98.4
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:06 +0000 (15:09 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:09:06 +0000 (15:09 -0500)
Rename "malloc()/free()" as "kmalloc()/kfree()" to make people more
aware of some of the limitations.

Math emulator updates to handle the case that Linux (unlike the original
djgpp target) can get preempted by user space accesses.

Make "ll_rw_blk()" take an array of blocks to read/write.

VFS "notify_change()" callback, to allow the low-level filesystem to
decide what it wants to do about metadata changes.

Deprecate old "stat()" call by printing out a warning on use.

NR_OPEN is now 256 files per process, and the old "unsigned long" bitops
needed to go away. This causes lots of syntactic changes in select().

System call tracing implemented for ptrace().

[Original announcement below]

 - the inode caching bug (resulting in bad filesystem info when
   mounting/umounting devices) should be gone for good.

 - an elusive race-condition in the fs is fixed: this may have been the
   reason some people got fsck errors once in a while.  The
   race-condition was pretty hard to find, and depends on a lot of
   things (buffer cache size, speed of the disk and computer speed).

 - fpu emulator patches (mainly for the re-entrancy problem) by me and
   W. Metzenthen.

 - various wait-queue changes - the kernel uses the waiting mechanism
   more efficiently now.

 - the NFS client support code is there: the actual nfs code is still in
   alpha (although reported to be pretty stable) and has to be gotten
   separately.

 - NR_OPEN was changed from 32 to 256 (which is what SunOS seems to use,
   so I hope it won't need any further changes).  This has lead to some
   incompatibilities (GNU emacs and the term program seem to need
   recompilation to work correctly), as the 'select()' system call has a
   slightly changed interface due to the new fd_set definition.

 - the process kernel stack is now on a separate page (needed due to the
   fact that the task_struct has now grown to almost 3kB due to the
   NR_OPEN changes).  This also means 'ps' needs patches..  My patches
   to ps-0.98 are available as 'ps-diff.Z' in the same directory as the
   kernel sources and diffs.

 - various other changes: system call tracing by Ross Biro. Changed
   ll_rw_block interface (performance reasons: it will eventually be
   changed to accept several requests at once).  Malloc() was changed
   and renamed to kmalloc() due to the new interface.  Some tcp/ip
   patches (inode counting correction and some other changes).

0.98.4 should hopefully be pretty stable: the main problem areas are
probably still tcp/ip and some of the tty code.  I'd appreciate
comments, bug-reports etc.

                Linus

108 files changed:
.version
Makefile
boot/head.S
fs/Makefile
fs/buffer.c
fs/exec.c
fs/ext/Makefile
fs/ext/file.c
fs/ext/freelists.c
fs/ext/inode.c
fs/fcntl.c
fs/filesystems.c [new file with mode: 0644]
fs/inode.c
fs/ioctl.c
fs/minix/Makefile
fs/minix/bitmap.c
fs/minix/file.c
fs/minix/inode.c
fs/minix/namei.c
fs/msdos/Makefile
fs/msdos/inode.c
fs/namei.c
fs/open.c
fs/proc/Makefile
fs/proc/inode.c
fs/select.c
fs/stat.c
fs/super.c
include/asm/dma.h
include/asm/memory.h [deleted file]
include/linux/config.h
include/linux/fs.h
include/linux/hdreg.h
include/linux/kernel.h
include/linux/limits.h
include/linux/math_emu.h
include/linux/mm.h
include/linux/ptrace.h
include/linux/sched.h
include/linux/time.h
include/linux/timer.h
include/linux/types.h
include/linux/wait.h
kernel/FPU-emu/Makefile
kernel/FPU-emu/README
kernel/FPU-emu/Reg_constant.h [new file with mode: 0644]
kernel/FPU-emu/errors.c
kernel/FPU-emu/fpu_arith.c
kernel/FPU-emu/fpu_aux.c
kernel/FPU-emu/fpu_emu.h
kernel/FPU-emu/fpu_entry.c
kernel/FPU-emu/fpu_etc.c
kernel/FPU-emu/fpu_proto.h
kernel/FPU-emu/fpu_system.h
kernel/FPU-emu/fpu_trig.c
kernel/FPU-emu/get_address.c
kernel/FPU-emu/load_store.c
kernel/FPU-emu/poly_2xm1.c
kernel/FPU-emu/poly_atan.c
kernel/FPU-emu/poly_l2.c
kernel/FPU-emu/poly_sin.c
kernel/FPU-emu/poly_tan.c
kernel/FPU-emu/reg_add_sub.c
kernel/FPU-emu/reg_compare.c
kernel/FPU-emu/reg_constant.c
kernel/FPU-emu/reg_constant.h
kernel/FPU-emu/reg_div.S
kernel/FPU-emu/reg_ld_str.c
kernel/FPU-emu/reg_mul.c
kernel/FPU-emu/reg_norm.S
kernel/FPU-emu/reg_u_add.S
kernel/FPU-emu/reg_u_div.S
kernel/FPU-emu/version.h
kernel/FPU-emu/wm_sqrt.S
kernel/Makefile
kernel/blk_drv/Makefile
kernel/blk_drv/floppy.c
kernel/blk_drv/hd.c
kernel/blk_drv/ll_rw_blk.c
kernel/blk_drv/scsi/Makefile
kernel/chr_drv/Makefile
kernel/chr_drv/keyboard.c
kernel/chr_drv/psaux.c
kernel/chr_drv/serial.c
kernel/chr_drv/tty_io.c
kernel/exit.c
kernel/fork.c
kernel/ptrace.c
kernel/sched.c
kernel/sys_call.S
lib/Makefile
lib/malloc.c
mm/Makefile
mm/memory.c
net/Makefile
net/socket.c
net/tcp/Makefile
net/tcp/arp.c
net/tcp/dev.c
net/tcp/icmp.c
net/tcp/ip.c
net/tcp/packet.c
net/tcp/raw.c
net/tcp/sock.c
net/tcp/sock.h
net/tcp/tcp.c
net/tcp/udp.c
tools/version.h

index f599e28b8ab0d8c9c57a486c89c4a5132dcbd3b2..f64f5d8d85ac0230d36724bd7e6ba351a95b4942 100644 (file)
--- a/.version
+++ b/.version
@@ -1 +1 @@
-10
+27
index 723dd23c144a1eeb56b661e05b6531a132f1f945..3eff03dba935222a148d6c4a0e3a53fc30e77db0 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -78,7 +78,7 @@ SVGA_MODE=    -DSVGA_MODE=1
 # standard CFLAGS
 #
 
-CFLAGS =-Wall -O6 -fomit-frame-pointer $(LIMIT_MEMORY)
+CFLAGS = -Wall -O6 -fomit-frame-pointer $(LIMIT_MEMORY)
 
 #
 # if you want the ram-disk device, define this to be the
@@ -99,7 +99,7 @@ CPP   =$(CC) -E $(LIMIT_MEMORY)
 AR     =ar
 
 ARCHIVES       =kernel/kernel.o mm/mm.o fs/fs.o net/net.o
-FILESYSTEMS    =fs/minix/minix.o fs/ext/ext.o fs/msdos/msdos.o fs/proc/proc.o
+FILESYSTEMS    =fs/filesystems.a
 DRIVERS                =kernel/blk_drv/blk_drv.a kernel/chr_drv/chr_drv.a \
                 kernel/blk_drv/scsi/scsi.a
 MATH           =kernel/FPU-emu/math.a
@@ -127,7 +127,7 @@ linuxsubdirs: dummy
 
 Version:
        @./makever.sh
-       @echo \#define UTS_RELEASE \"0.98.pl3-`cat .version`\" > tools/version.h
+       @echo \#define UTS_RELEASE \"0.98.pl4-`cat .version`\" > tools/version.h
        @echo \#define UTS_VERSION \"`date +%D`\" >> tools/version.h
        @echo \#define LINUX_COMPILE_TIME \"`date +%T`\" >> tools/version.h
        @echo \#define LINUX_COMPILE_BY \"`whoami`\" >> tools/version.h
@@ -218,4 +218,5 @@ init/main.o : init/main.c /usr/lib/gcc-lib/i386-linux/2.2.2d/include/stdarg.h /u
   /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h \
   /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
   /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
-  /usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/linux/unistd.h 
+  /usr/include/linux/math_emu.h /usr/include/linux/tty.h /usr/include/linux/termios.h \
+  /usr/include/linux/unistd.h /usr/include/linux/string.h 
index aef714a5167d259364bd4792edebad8e3c9cb57c..63812b234c1a60a74a68ba170a88bb742fa379b0 100644 (file)
@@ -69,7 +69,24 @@ startup_32:
        orl $0x10022,%eax       # set NE and MP
 2:     movl %eax,%cr0
        call check_x87
-       jmp after_page_tables
+       call setup_paging
+       lgdt gdt_descr
+       lidt idt_descr
+       ljmp $0x08,$1f
+1:     movl $0x10,%eax         # reload all the segment registers
+       mov %ax,%ds             # after changing gdt.
+       mov %ax,%es
+       mov %ax,%fs
+       mov %ax,%gs
+       lss _stack_start,%esp
+       pushl $0                # These are the parameters to main :-)
+       pushl $0
+       pushl $0
+       cld                     # gcc2 wants the direction flag cleared at all times
+       call _start_kernel
+L6:
+       jmp L6                  # main should never return here, but
+                               # just in case, we know what happens.
 
 /*
  * We depend on ET to be correct. This checks for 287/387.
@@ -116,6 +133,42 @@ rp_sidt:
        jne rp_sidt
        ret
 
+
+/*
+ * Setup_paging
+ *
+ * This routine sets up paging by setting the page bit
+ * in cr0. The page tables are set up, identity-mapping
+ * the first 4MB.  The rest are initialized later.
+ *
+ * (ref: added support for up to 32mb, 17Apr92)  -- Rik Faith
+ * (ref: update, 25Sept92)  -- croutons@crunchy.uucp 
+ * (ref: 92.10.11 - Linus Torvalds. Corrected 16M limit - no upper memory limit)
+ */
+.align 2
+setup_paging:
+       movl $1024*2,%ecx               /* 2 pages - swapper_pg_dir+1 page table */
+       xorl %eax,%eax
+       movl $_swapper_pg_dir,%edi      /* swapper_pg_dir is at 0x1000 */
+       cld;rep;stosl
+/* Identity-map the kernel in low 4MB memory for ease of transition */
+       movl $_pg0+7,_swapper_pg_dir            /* set present bit/user r/w */
+/* But the real place is at 0xC0000000 */
+       movl $_pg0+7,_swapper_pg_dir+3072       /* set present bit/user r/w */
+       movl $_pg0+4092,%edi
+       movl $0x03ff007,%eax            /*  4Mb - 4096 + 7 (r/w user,p) */
+       std
+1:     stosl                   /* fill the page backwards - more efficient :-) */
+       subl $0x1000,%eax
+       jge 1b
+       cld
+       movl $_swapper_pg_dir,%eax
+       movl %eax,%cr3                  /* cr3 - page directory start */
+       movl %cr0,%eax
+       orl $0x80000000,%eax
+       movl %eax,%cr0          /* set paging (PG) bit */
+       ret                     /* this also flushes the prefetch-queue */
+
 /*
  * page 0 is made non-existent, so that kernel NULL pointer references get
  * caught. Thus the swapper page directory has been moved to 0x1000
@@ -152,26 +205,6 @@ _tmp_floppy_area:
 _floppy_track_buffer:
        .fill 512*2*18,1,0
 
-after_page_tables:
-       call setup_paging
-       lgdt gdt_descr
-       lidt idt_descr
-       ljmp $0x08,$1f
-1:     movl $0x10,%eax         # reload all the segment registers
-       mov %ax,%ds             # after changing gdt.
-       mov %ax,%es
-       mov %ax,%fs
-       mov %ax,%gs
-       lss _stack_start,%esp
-       pushl $0                # These are the parameters to main :-)
-       pushl $0
-       pushl $0
-       cld                     # gcc2 wants the direction flag cleared at all times
-       call _start_kernel
-L6:
-       jmp L6                  # main should never return here, but
-                               # just in case, we know what happens.
-
 /* This is the default interrupt "handler" :-) */
 int_msg:
        .asciz "Unknown interrupt\n\r"
@@ -199,58 +232,6 @@ ignore_int:
        popl %eax
        iret
 
-
-/*
- * Setup_paging
- *
- * This routine sets up paging by setting the page bit
- * in cr0. The page tables are set up, identity-mapping
- * the first 4MB.  The rest are initialized later.
- *
- * NOTE! Although all physical memory should be identity
- * mapped by this routine, only the kernel page functions
- * use the >1Mb addresses directly. All "normal" functions
- * use just the lower 1Mb, or the local data space, which
- * will be mapped to some other place - mm keeps track of
- * that.
- *
- * For those with more memory than 16 Mb - tough luck. I've
- * not got it, why should you :-) The source is here. Change
- * it. (Seriously - it shouldn't be too difficult. Mostly
- * change some constants etc. I left it at 16Mb, as my machine
- * even cannot be extended past that (ok, but it was cheap :-)
- * I've tried to show which constants to change by having
- * some kind of marker at them (search for "16Mb"), but I
- * won't guarantee that's all :-( )
- *
- * (ref: added support for up to 32mb, 17Apr92)  -- Rik Faith
- * (ref: update, 25Sept92)  -- croutons@crunchy.uucp 
- * (ref: 92.10.11 - Linus Torvalds. Corrected 16M limit - no upper memory limit)
- */
-.align 2
-setup_paging:
-       movl $1024*2,%ecx               /* 2 pages - swapper_pg_dir+1 page table */
-       xorl %eax,%eax
-       movl $_swapper_pg_dir,%edi      /* swapper_pg_dir is at 0x1000 */
-       cld;rep;stosl
-/* Identity-map the kernel in low 4MB memory for ease of transition */
-       movl $_pg0+7,_swapper_pg_dir            /* set present bit/user r/w */
-/* But the real place is at 0xC0000000 */
-       movl $_pg0+7,_swapper_pg_dir+3072       /* set present bit/user r/w */
-       movl $_pg0+4092,%edi
-       movl $0x03ff007,%eax            /*  4Mb - 4096 + 7 (r/w user,p) */
-       std
-1:     stosl                   /* fill the page backwards - more efficient :-) */
-       subl $0x1000,%eax
-       jge 1b
-       cld
-       movl $_swapper_pg_dir,%eax
-       movl %eax,%cr3                  /* cr3 - page directory start */
-       movl %cr0,%eax
-       orl $0x80000000,%eax
-       movl %eax,%cr0          /* set paging (PG) bit */
-       ret                     /* this also flushes the prefetch-queue */
-
 /*
  * The interrupt descriptor table has room for 256 idt's
  */
index ed1b3301f24e1bba0bfc7ce9bc46dc4a7043e367..d2a59006c343d0e65152a51212cb0ad668153f8a 100644 (file)
@@ -7,7 +7,7 @@
 #
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
-SUBDIRS        =minix ext msdos proc
+SUBDIRS minix ext msdos proc
 
 .c.s:
        $(CC) $(CFLAGS) -S $<
@@ -18,26 +18,29 @@ SUBDIRS     =minix ext msdos proc
 
 OBJS=  open.o read_write.o inode.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
+       select.o fifo.o locks.o filesystems.o
 
-all: fs.o fssubdirs
+all: fs.o filesystems.a
 
 fs.o: $(OBJS)
        $(LD) -r -o fs.o $(OBJS)
 
-fssubdirs: dummy
-       @for i in $(SUBDIRS); do (cd $$i && echo $$i && $(MAKE)) || exit; done
+filesystems.a: dummy
+       rm -f filesystems.a
+       @for i in $(SUBDIRS); do [ ! -d $$i ] || \
+       (cd $$i && echo $$i && $(MAKE) && $(AR) rcs ../filesystems.a $$i.o) \
+       || exit; done
 
 clean:
        rm -f core *.o *.a tmp_make
        for i in *.c; do rm -f `basename $$i .c`.s;done
-       for i in $(SUBDIRS); do (cd $$i && $(MAKE) clean); done
+       for i in $(SUBDIRS); do ([ -d $$i ] && cd $$i && $(MAKE) clean); done
 
 depend dep:
        sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
        $(CPP) -M *.c >> tmp_make
        cp tmp_make Makefile
-       for i in $(SUBDIRS); do (cd $$i && $(MAKE) dep) || exit; done
+       for i in $(SUBDIRS); do [ ! -d $$i ] || (cd $$i && $(MAKE) dep) || exit; done
 
 dummy:
 
@@ -50,7 +53,7 @@ block_dev.o : block_dev.c /usr/include/linux/errno.h /usr/include/linux/sched.h
   /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h \
   /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
   /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
-  /usr/include/asm/segment.h /usr/include/asm/system.h 
+  /usr/include/linux/math_emu.h /usr/include/asm/segment.h /usr/include/asm/system.h 
 buffer.o : buffer.c /usr/lib/gcc-lib/i386-linux/2.2.2d/include/stdarg.h /usr/include/linux/config.h \
   /usr/include/linux/config.dist.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
@@ -59,8 +62,9 @@ buffer.o : buffer.c /usr/lib/gcc-lib/i386-linux/2.2.2d/include/stdarg.h /usr/inc
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
   /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/string.h \
-  /usr/include/asm/system.h /usr/include/asm/io.h 
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  /usr/include/linux/string.h /usr/include/linux/locks.h /usr/include/asm/system.h \
+  /usr/include/asm/io.h 
 exec.o : exec.c /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
   /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
   /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
@@ -68,9 +72,10 @@ exec.o : exec.c /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/a.out.h /usr/include/linux/errno.h \
-  /usr/include/linux/string.h /usr/include/linux/stat.h /usr/include/linux/fcntl.h \
-  /usr/include/linux/ptrace.h /usr/include/linux/user.h /usr/include/asm/segment.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/a.out.h \
+  /usr/include/linux/errno.h /usr/include/linux/string.h /usr/include/linux/stat.h \
+  /usr/include/linux/fcntl.h /usr/include/linux/ptrace.h /usr/include/linux/user.h \
+  /usr/include/asm/segment.h 
 fcntl.o : fcntl.c /usr/include/asm/segment.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
   /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
@@ -78,8 +83,9 @@ fcntl.o : fcntl.c /usr/include/asm/segment.h /usr/include/linux/sched.h /usr/inc
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
   /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/errno.h \
-  /usr/include/linux/stat.h /usr/include/linux/fcntl.h /usr/include/linux/string.h 
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  /usr/include/linux/errno.h /usr/include/linux/stat.h /usr/include/linux/fcntl.h \
+  /usr/include/linux/string.h 
 fifo.o : fifo.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
   /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
   /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
@@ -87,12 +93,20 @@ fifo.o : fifo.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/includ
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/errno.h /usr/include/linux/fcntl.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/errno.h \
+  /usr/include/linux/fcntl.h 
 file_table.o : file_table.c /usr/include/linux/fs.h /usr/include/linux/limits.h \
   /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
   /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
   /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h \
   /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/string.h 
+filesystems.o : filesystems.c /usr/include/linux/config.h /usr/include/linux/config.dist.h \
+  /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
+  /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
+  /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
+  /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
+  /usr/include/linux/msdos_fs_sb.h /usr/include/linux/minix_fs.h /usr/include/linux/proc_fs.h \
+  /usr/include/linux/ext_fs.h /usr/include/linux/msdos_fs.h 
 inode.o : inode.c /usr/include/linux/stat.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
   /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
@@ -100,8 +114,8 @@ inode.o : inode.c /usr/include/linux/stat.h /usr/include/linux/sched.h /usr/incl
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
   /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/string.h \
-  /usr/include/asm/system.h 
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  /usr/include/linux/string.h /usr/include/asm/system.h 
 ioctl.o : ioctl.c /usr/include/asm/segment.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
   /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
@@ -109,9 +123,9 @@ ioctl.o : ioctl.c /usr/include/asm/segment.h /usr/include/linux/sched.h /usr/inc
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
   /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/errno.h \
-  /usr/include/linux/string.h /usr/include/linux/stat.h /usr/include/linux/termios.h \
-  /usr/include/linux/fcntl.h 
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  /usr/include/linux/errno.h /usr/include/linux/string.h /usr/include/linux/stat.h \
+  /usr/include/linux/termios.h /usr/include/linux/fcntl.h 
 locks.o : locks.c /usr/include/asm/segment.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
   /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
@@ -119,8 +133,8 @@ locks.o : locks.c /usr/include/asm/segment.h /usr/include/linux/sched.h /usr/inc
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
   /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/errno.h \
-  /usr/include/linux/stat.h /usr/include/linux/fcntl.h 
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  /usr/include/linux/errno.h /usr/include/linux/stat.h /usr/include/linux/fcntl.h 
 namei.o : namei.c /usr/include/asm/segment.h /usr/include/linux/errno.h /usr/include/linux/sched.h \
   /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
   /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
@@ -129,7 +143,8 @@ namei.o : namei.c /usr/include/asm/segment.h /usr/include/linux/errno.h /usr/inc
   /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h \
   /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
   /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
-  /usr/include/linux/string.h /usr/include/linux/fcntl.h /usr/include/linux/stat.h 
+  /usr/include/linux/math_emu.h /usr/include/linux/string.h /usr/include/linux/fcntl.h \
+  /usr/include/linux/stat.h 
 open.o : open.c /usr/include/linux/vfs.h /usr/include/linux/types.h /usr/include/linux/utime.h \
   /usr/include/linux/errno.h /usr/include/linux/fcntl.h /usr/include/linux/stat.h \
   /usr/include/linux/string.h /usr/include/linux/sched.h /usr/include/linux/head.h \
@@ -139,8 +154,8 @@ open.o : open.c /usr/include/linux/vfs.h /usr/include/linux/types.h /usr/include
   /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h \
   /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
   /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
-  /usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/asm/system.h \
-  /usr/include/asm/segment.h 
+  /usr/include/linux/math_emu.h /usr/include/linux/tty.h /usr/include/linux/termios.h \
+  /usr/include/asm/system.h /usr/include/asm/segment.h 
 pipe.o : pipe.c /usr/include/asm/segment.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
   /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
@@ -148,8 +163,8 @@ pipe.o : pipe.c /usr/include/asm/segment.h /usr/include/linux/sched.h /usr/inclu
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
   /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/errno.h \
-  /usr/include/linux/fcntl.h /usr/include/linux/termios.h 
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  /usr/include/linux/errno.h /usr/include/linux/fcntl.h /usr/include/linux/termios.h 
 read_write.o : read_write.c /usr/include/linux/types.h /usr/include/linux/errno.h \
   /usr/include/linux/stat.h /usr/include/linux/kernel.h /usr/include/linux/sched.h \
   /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
@@ -158,7 +173,8 @@ read_write.o : read_write.c /usr/include/linux/types.h /usr/include/linux/errno.
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/minix_fs.h /usr/include/asm/segment.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/minix_fs.h \
+  /usr/include/asm/segment.h 
 select.o : select.c /usr/include/linux/types.h /usr/include/linux/time.h /usr/include/linux/fs.h \
   /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/dirent.h \
   /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
@@ -166,8 +182,9 @@ select.o : select.c /usr/include/linux/types.h /usr/include/linux/time.h /usr/in
   /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/kernel.h \
   /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/mm.h \
   /usr/include/linux/signal.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/string.h /usr/include/linux/stat.h \
-  /usr/include/linux/errno.h /usr/include/asm/segment.h /usr/include/asm/system.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/string.h \
+  /usr/include/linux/stat.h /usr/include/linux/errno.h /usr/include/asm/segment.h \
+  /usr/include/asm/system.h 
 stat.o : stat.c /usr/include/linux/errno.h /usr/include/linux/stat.h /usr/include/linux/fs.h \
   /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
   /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
@@ -176,7 +193,7 @@ stat.o : stat.c /usr/include/linux/errno.h /usr/include/linux/stat.h /usr/includ
   /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/mm.h \
   /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
   /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
-  /usr/include/asm/segment.h 
+  /usr/include/linux/math_emu.h /usr/include/asm/segment.h 
 super.o : super.c /usr/include/linux/config.h /usr/include/linux/config.dist.h \
   /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
   /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
@@ -185,6 +202,6 @@ super.o : super.c /usr/include/linux/config.h /usr/include/linux/config.dist.h \
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/minix_fs.h /usr/include/linux/proc_fs.h \
-  /usr/include/linux/ext_fs.h /usr/include/linux/msdos_fs.h /usr/include/linux/stat.h \
-  /usr/include/linux/errno.h /usr/include/asm/system.h /usr/include/asm/segment.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/stat.h \
+  /usr/include/linux/errno.h /usr/include/linux/string.h /usr/include/linux/locks.h \
+  /usr/include/asm/system.h /usr/include/asm/segment.h 
index d02e39f2d025124a58b01423de6b2084ab5e56e0..bcdf5eb36a3362b2375182ebdc0262e92aa07a41 100644 (file)
@@ -56,14 +56,16 @@ int nr_buffer_heads = 0;
  */
 void __wait_on_buffer(struct buffer_head * bh)
 {
-       add_wait_queue(&bh->b_wait,&current->wait);
+       struct wait_queue wait = { current, NULL };
+
+       add_wait_queue(&bh->b_wait, &wait);
 repeat:
        current->state = TASK_UNINTERRUPTIBLE;
        if (bh->b_lock) {
                schedule();
                goto repeat;
        }
-       remove_wait_queue(&bh->b_wait,&current->wait);
+       remove_wait_queue(&bh->b_wait, &wait);
        current->state = TASK_RUNNING;
 }
 
@@ -78,7 +80,7 @@ static void sync_buffers(dev_t dev)
                        continue;
                if (!bh->b_dirt)
                        continue;
-               ll_rw_block(WRITE,bh);
+               ll_rw_block(WRITE, 1, &bh);
        }
 }
 
@@ -325,7 +327,7 @@ repeat:
                }
 #if 0
                if (tmp->b_dirt)
-                       ll_rw_block(WRITEA,tmp);
+                       ll_rw_block(WRITEA, 1, &tmp);
 #endif
        }
 
@@ -386,7 +388,7 @@ struct buffer_head * bread(dev_t dev, int block, int size)
        }
        if (bh->b_uptodate)
                return bh;
-       ll_rw_block(READ,bh);
+       ll_rw_block(READ, 1, &bh);
        wait_on_buffer(bh);
        if (bh->b_uptodate)
                return bh;
@@ -416,7 +418,7 @@ void bread_page(unsigned long address, dev_t dev, int b[4])
                if (b[i]) {
                        if (bh[i] = getblk(dev, b[i], 1024))
                                if (!bh[i]->b_uptodate)
-                                       ll_rw_block(READ,bh[i]);
+                                       ll_rw_block(READ, 1, &bh[i]);
                } else
                        bh[i] = NULL;
        for (i=0 ; i<4 ; i++,address += BLOCK_SIZE)
@@ -444,12 +446,12 @@ struct buffer_head * breada(dev_t dev,int first, ...)
                return NULL;
        }
        if (!bh->b_uptodate)
-               ll_rw_block(READ,bh);
+               ll_rw_block(READ, 1, &bh);
        while ((first=va_arg(args,int))>=0) {
                tmp = getblk(dev, first, 1024);
                if (tmp) {
                        if (!tmp->b_uptodate)
-                               ll_rw_block(READA,tmp);
+                               ll_rw_block(READA, 1, &tmp);
                        tmp->b_count--;
                }
        }
@@ -461,9 +463,16 @@ struct buffer_head * breada(dev_t dev,int first, ...)
        return (NULL);
 }
 
+/*
+ * See fs/inode.c for the weird use of volatile..
+ */
 static void put_unused_buffer_head(struct buffer_head * bh)
 {
+       struct wait_queue * wait;
+
+       wait = ((volatile struct buffer_head *) bh)->b_wait;
        memset((void *) bh,0,sizeof(*bh));
+       ((volatile struct buffer_head *) bh)->b_wait = wait;
        bh->b_next_free = unused_list;
        unused_list = bh;
 }
@@ -620,7 +629,7 @@ int shrink_buffers(unsigned int priority)
                        else
                                wait_on_buffer(bh);
                if (bh->b_dirt) {
-                       ll_rw_block(WRITEA,bh);
+                       ll_rw_block(WRITEA, 1, &bh);
                        continue;
                }
                if (try_to_free(bh))
index 32b8356be58941007acd45e52b8287088125d67f..63976539fd20c7ce067923146f995baf7df34e64 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -77,7 +77,8 @@ int core_dump(long signr, struct pt_regs * regs)
                return 0;
        current->dumpable = 0;
 /* See if we have enough room to write the upage.  */
-       if(current->rlim[RLIMIT_CORE].rlim_cur < PAGE_SIZE/1024) return 0;
+       if (current->rlim[RLIMIT_CORE].rlim_cur < PAGE_SIZE)
+               return 0;
        __asm__("mov %%fs,%0":"=r" (fs));
        __asm__("mov %0,%%fs"::"r" ((unsigned short) 0x10));
        if (open_namei("core",O_CREAT | O_WRONLY | O_TRUNC,0600,&inode,NULL)) {
@@ -113,11 +114,11 @@ int core_dump(long signr, struct pt_regs * regs)
                dump.u_ssize = ((unsigned long) (TASK_SIZE - dump.start_stack)) >> 12;
 /* If the size of the dump file exceeds the rlimit, then see what would happen
    if we wrote the stack, but not the data area.  */
-       if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE/1024 >
+       if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
            current->rlim[RLIMIT_CORE].rlim_cur)
                dump.u_dsize = 0;
 /* Make sure we have enough room to write the stack and data areas. */
-       if ((dump.u_ssize+1) * PAGE_SIZE / 1024 >
+       if ((dump.u_ssize+1) * PAGE_SIZE >
            current->rlim[RLIMIT_CORE].rlim_cur)
                dump.u_ssize = 0;
                dump.u_comm = 0;
@@ -588,9 +589,9 @@ restart_interp:
                        current->sigaction[i].sa_handler = NULL;
        }
        for (i=0 ; i<NR_OPEN ; i++)
-               if ((current->close_on_exec>>i)&1)
+               if (FD_ISSET(i,&current->close_on_exec))
                        sys_close(i);
-       current->close_on_exec = 0;
+       FD_ZERO(&current->close_on_exec);
        clear_page_tables(current);
        if (last_task_used_math == current)
                last_task_used_math = NULL;
index 04dc41c4ca6e811950a583d4cc2c8c5d6d71d6a0..55cb096733e3197a53f371d5973231eebf231300 100644 (file)
@@ -37,9 +37,9 @@ blkdev.o : blkdev.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/in
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/ext_fs.h /usr/include/linux/tty.h \
-  /usr/include/linux/termios.h /usr/include/asm/system.h /usr/include/linux/stat.h \
-  /usr/include/linux/fcntl.h /usr/include/linux/errno.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/ext_fs.h \
+  /usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/asm/system.h \
+  /usr/include/linux/stat.h /usr/include/linux/fcntl.h /usr/include/linux/errno.h 
 chrdev.o : chrdev.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
   /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
   /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
@@ -47,9 +47,9 @@ chrdev.o : chrdev.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/in
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/ext_fs.h /usr/include/linux/tty.h \
-  /usr/include/linux/termios.h /usr/include/asm/system.h /usr/include/linux/stat.h \
-  /usr/include/linux/fcntl.h /usr/include/linux/errno.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/ext_fs.h \
+  /usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/asm/system.h \
+  /usr/include/linux/stat.h /usr/include/linux/fcntl.h /usr/include/linux/errno.h 
 dir.o : dir.c /usr/include/asm/segment.h /usr/include/linux/errno.h /usr/include/linux/kernel.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
   /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
@@ -63,7 +63,7 @@ fifo.o : fifo.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/includ
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/ext_fs.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/ext_fs.h 
 file.o : file.c /usr/include/asm/segment.h /usr/include/asm/system.h /usr/include/linux/sched.h \
   /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
   /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
@@ -72,8 +72,8 @@ file.o : file.c /usr/include/asm/segment.h /usr/include/asm/system.h /usr/includ
   /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h \
   /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
   /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
-  /usr/include/linux/ext_fs.h /usr/include/linux/errno.h /usr/include/linux/fcntl.h \
-  /usr/include/linux/stat.h 
+  /usr/include/linux/math_emu.h /usr/include/linux/ext_fs.h /usr/include/linux/errno.h \
+  /usr/include/linux/fcntl.h /usr/include/linux/stat.h /usr/include/linux/locks.h 
 freelists.o : freelists.c /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
   /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
@@ -81,8 +81,8 @@ freelists.o : freelists.c /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
   /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/ext_fs.h \
-  /usr/include/linux/string.h 
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  /usr/include/linux/ext_fs.h /usr/include/linux/string.h /usr/include/linux/locks.h 
 inode.o : inode.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
   /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
   /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
@@ -90,8 +90,9 @@ inode.o : inode.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/incl
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/ext_fs.h /usr/include/linux/string.h \
-  /usr/include/linux/stat.h /usr/include/asm/system.h /usr/include/asm/segment.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/ext_fs.h \
+  /usr/include/linux/string.h /usr/include/linux/stat.h /usr/include/linux/locks.h \
+  /usr/include/asm/system.h /usr/include/asm/segment.h 
 namei.o : namei.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
   /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
   /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
@@ -99,9 +100,9 @@ namei.o : namei.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/incl
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/ext_fs.h /usr/include/linux/string.h \
-  /usr/include/linux/stat.h /usr/include/linux/fcntl.h /usr/include/linux/errno.h \
-  /usr/include/asm/segment.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/ext_fs.h \
+  /usr/include/linux/string.h /usr/include/linux/stat.h /usr/include/linux/fcntl.h \
+  /usr/include/linux/errno.h /usr/include/asm/segment.h 
 symlink.o : symlink.c /usr/include/asm/segment.h /usr/include/linux/errno.h \
   /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
   /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
@@ -110,7 +111,8 @@ symlink.o : symlink.c /usr/include/asm/segment.h /usr/include/linux/errno.h \
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/ext_fs.h /usr/include/linux/stat.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/ext_fs.h \
+  /usr/include/linux/stat.h 
 truncate.o : truncate.c /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
   /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
@@ -118,6 +120,7 @@ truncate.o : truncate.c /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
   /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/ext_fs.h \
-  /usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/asm/system.h \
-  /usr/include/linux/stat.h /usr/include/linux/fcntl.h /usr/include/linux/errno.h 
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  /usr/include/linux/ext_fs.h /usr/include/linux/tty.h /usr/include/linux/termios.h \
+  /usr/include/asm/system.h /usr/include/linux/stat.h /usr/include/linux/fcntl.h \
+  /usr/include/linux/errno.h 
index fb7bb2b8bb0b47d95826e2658f3576ef053d13a4..ce8313cdd9d848a1e0137a1808496b0ffdac8b26 100644 (file)
@@ -100,7 +100,7 @@ static int ext_file_read(struct inode * inode, struct file * filp, char * buf, i
                        --blocks;
                        *bhb = ext_getblk(inode,block++,0);
                        if (*bhb && !(*bhb)->b_uptodate)
-                               ll_rw_block(READ,*bhb);
+                               ll_rw_block(READ, 1, bhb);
 
                        if (++bhb == &buflist[NBUF])
                                bhb = buflist;
@@ -183,7 +183,7 @@ static int ext_file_write(struct inode * inode, struct file * filp, char * buf,
                if (c > count-written)
                        c = count-written;
                if (c != BLOCK_SIZE && !bh->b_uptodate) {
-                       ll_rw_block(READ,bh);
+                       ll_rw_block(READ, 1, &bh);
                        wait_on_buffer(bh);
                        if (!bh->b_uptodate) {
                                brelse(bh);
index 81b54f1cd6c9668d59a44c02f023d6f95f181fc6..e7801c864fdf0ef0e047cc57a61b067cff0e6bb5 100644 (file)
@@ -181,10 +181,10 @@ void ext_free_inode(struct inode * inode)
        if (!inode)
                return;
        if (!inode->i_dev) {
-               memset(inode,0,sizeof(*inode));
+               printk("free_inode: inode has no device\n");
                return;
        }
-       if (inode->i_count>1) {
+       if (inode->i_count != 1) {
                printk("free_inode: inode has count=%d\n",inode->i_count);
                return;
        }
@@ -227,7 +227,7 @@ printk("ext_free_inode: inode full, skipping to %d\n", inode->i_ino);
        inode->i_sb->s_dirt = 1;
        inode->i_sb->u.ext_sb.s_firstfreeinodeblock->b_dirt = 1;
        unlock_super (inode->i_sb);
-       memset(inode,0,sizeof(*inode));
+       clear_inode(inode);
 }
 
 struct inode * ext_new_inode(struct super_block * sb)
index fe52dfb4d4ca3da98bc629f69b9b442d7557557a..383700263f963b67d78e4df47d691ee0afdc6c79 100644 (file)
@@ -45,6 +45,7 @@ void ext_put_super(struct super_block *sb)
 
 static struct super_operations ext_sops = { 
        ext_read_inode,
+       NULL,
        ext_write_inode,
        ext_put_inode,
        ext_put_super,
@@ -62,7 +63,7 @@ struct super_block *ext_read_super(struct super_block *s,void *data)
        if (!(bh = bread(dev, 1, BLOCK_SIZE))) {
                s->s_dev=0;
                unlock_super(s);
-               printk("bread failed\n");
+               printk("EXT-fs: unable to read superblock\n");
                return NULL;
        }
        es = (struct ext_super_block *) bh->b_data;
@@ -81,7 +82,7 @@ struct super_block *ext_read_super(struct super_block *s,void *data)
        if (s->s_magic != EXT_SUPER_MAGIC) {
                s->s_dev = 0;
                unlock_super(s);
-               printk("magic match failed\n");
+               printk("EXT-fs: magic match failed\n");
                return NULL;
        }
        if (!s->u.ext_sb.s_firstfreeblocknumber)
@@ -89,7 +90,7 @@ struct super_block *ext_read_super(struct super_block *s,void *data)
        else
                if (!(s->u.ext_sb.s_firstfreeblock = bread(dev,
                        s->u.ext_sb.s_firstfreeblocknumber, BLOCK_SIZE))) {
-                       printk ("ext_read_super: unable to read first free block\n");
+                       printk("ext_read_super: unable to read first free block\n");
                        s->s_dev = 0;
                        unlock_super(s);
                        return NULL;
@@ -99,7 +100,7 @@ struct super_block *ext_read_super(struct super_block *s,void *data)
        else {
                block = 2 + (s->u.ext_sb.s_firstfreeinodenumber - 1) / EXT_INODES_PER_BLOCK;
                if (!(s->u.ext_sb.s_firstfreeinodeblock = bread(dev, block, BLOCK_SIZE))) {
-                       printk ("ext_read_super: unable to read first free inode block\n");
+                       printk("ext_read_super: unable to read first free inode block\n");
                        brelse(s->u.ext_sb.s_firstfreeblock);
                        s->s_dev = 0;
                        unlock_super (s);
@@ -112,7 +113,7 @@ struct super_block *ext_read_super(struct super_block *s,void *data)
        s->s_op = &ext_sops;
        if (!(s->s_mounted = iget(s,EXT_ROOT_INO))) {
                s->s_dev=0;
-               printk("get root inode failed\n");
+               printk("EXT-fs: get root inode failed\n");
                return NULL;
        }
        return s;
@@ -253,7 +254,7 @@ static struct buffer_head * block_getblk(struct inode * inode,
        if (!bh)
                return NULL;
        if (!bh->b_uptodate) {
-               ll_rw_block(READ,bh);
+               ll_rw_block(READ, 1, &bh);
                wait_on_buffer(bh);
                if (!bh->b_uptodate) {
                        brelse(bh);
@@ -332,7 +333,7 @@ struct buffer_head * ext_bread(struct inode * inode, int block, int create)
        bh = ext_getblk(inode,block,create);
        if (!bh || bh->b_uptodate) 
                return bh;
-       ll_rw_block(READ,bh);
+       ll_rw_block(READ, 1, &bh);
        wait_on_buffer(bh);
        if (bh->b_uptodate)
                return bh;
index fa0d23bd0e79fc3d7557d4d9a5b01134ed672ee4..e9d63d0dc1cf02a576a490a091aba6d30b41f1d0 100644 (file)
@@ -30,7 +30,7 @@ static int dupfd(unsigned int fd, unsigned int arg)
                        break;
        if (arg >= NR_OPEN)
                return -EMFILE;
-       current->close_on_exec &= ~(1<<arg);
+       FD_CLR(arg, &current->close_on_exec);
        (current->filp[arg] = current->filp[fd])->f_count++;
        return arg;
 }
@@ -61,12 +61,12 @@ int sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg)
                case F_DUPFD:
                        return dupfd(fd,arg);
                case F_GETFD:
-                       return (current->close_on_exec>>fd)&1;
+                       return FD_ISSET(fd, &current->close_on_exec);
                case F_SETFD:
                        if (arg&1)
-                               current->close_on_exec |= (1<<fd);
+                               FD_SET(fd, &current->close_on_exec);
                        else
-                               current->close_on_exec &= ~(1<<fd);
+                               FD_CLR(fd, &current->close_on_exec);
                        return 0;
                case F_GETFL:
                        return filp->f_flags;
diff --git a/fs/filesystems.c b/fs/filesystems.c
new file mode 100644 (file)
index 0000000..7844781
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ *  linux/fs/filesystems.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ *  table of configured filesystems
+ */
+
+#include <linux/config.h>
+#include <linux/fs.h>
+#ifdef MINIX_FS
+#include <linux/minix_fs.h>
+#endif
+#ifdef PROC_FS
+#include <linux/proc_fs.h>
+#endif
+#ifdef EXT_FS
+#include <linux/ext_fs.h>
+#endif
+#ifdef MSDOS_FS
+#include <linux/msdos_fs.h>
+#endif
+#ifdef NFS_FS
+#include <linux/nfs_fs.h>
+#endif
+
+struct file_system_type file_systems[] = {
+#ifdef MINIX_FS
+       {minix_read_super,      "minix",        1},
+#endif
+#ifdef EXT_FS
+       {ext_read_super,        "ext",          1},
+#endif
+#ifdef MSDOS_FS
+       {msdos_read_super,      "msdos",        1},
+#endif
+#ifdef PROC_FS
+       {proc_read_super,       "proc",         0},
+#endif
+#ifdef NFS_FS
+       {nfs_read_super,        "nfs",          0},
+#endif
+       {NULL,                  NULL,           0}
+};
index 30e2e706e2f1bb0f290b7250585b227ab5880e39..78a3907d8d2266747e5f1c910cb856beea46f085 100644 (file)
 #include <asm/system.h>
 
 static struct inode inode_table[NR_INODE];
+static struct inode * last_inode = inode_table;
 
 void inode_init(void)
 {
        memset(inode_table,0,sizeof(inode_table));      
 }
 
+static void __wait_on_inode(struct inode *);
+
+static inline void wait_on_inode(struct inode * inode)
+{
+       if (inode->i_lock)
+               __wait_on_inode(inode);
+}
+
+static inline void lock_inode(struct inode * inode)
+{
+       wait_on_inode(inode);
+       inode->i_lock = 1;
+}
+
+static inline void unlock_inode(struct inode * inode)
+{
+       inode->i_lock = 0;
+       wake_up(&inode->i_wait);
+}
+
+/*
+ * Note that we don't want to disturb any wait-queues when we discard
+ * an inode.
+ *
+ * Argghh. Got bitten by a gcc problem with inlining: no way to tell
+ * the compiler that the inline asm function 'memset' changes 'inode'.
+ * I've been searching for the bug for days, and was getting desperate.
+ * Finally looked at the assembler output... Grrr.
+ *
+ * The solution is the weird use of 'volatile'. Ho humm. Have to report
+ * it to the gcc lists, and hope we can do this more cleanly some day..
+ */
+void clear_inode(struct inode * inode)
+{
+       struct wait_queue * wait;
+
+       wait_on_inode(inode);
+       wait = ((volatile struct inode *) inode)->i_wait;
+       memset(inode,0,sizeof(*inode));
+       ((volatile struct inode *) inode)->i_wait = wait;
+}
+
 int fs_may_mount(dev_t dev)
 {
        struct inode * inode;
@@ -28,7 +71,7 @@ int fs_may_mount(dev_t dev)
                        continue;
                if (inode->i_count || inode->i_dirt || inode->i_lock)
                        return 0;
-               inode->i_dev = 0;
+               clear_inode(inode);
        }
        return 1;
 }
@@ -37,61 +80,29 @@ int fs_may_umount(dev_t dev, struct inode * mount_root)
 {
        struct inode * inode;
 
-       for (inode = inode_table+0 ; inode < inode_table+NR_INODE ; inode++)
+       for (inode = inode_table+0 ; inode < inode_table+NR_INODE ; inode++) {
                if (inode->i_dev==dev && inode->i_count)
                        if (inode == mount_root && inode->i_count == 1)
                                continue;
                        else
                                return 0;
-       return 1;
-}
-
-/*
- * The "new" scheduling primitives (new as of 0.97 or so) allow this to
- * be done without disabling interrupts (other than in the actual queue
- * updating things: only a couple of 386 instructions). This should be
- * much better for interrupt latency.
- */
-static void __wait_on_inode(struct inode * inode)
-{
-       add_wait_queue(&inode->i_wait,&current->wait);
-repeat:
-       current->state = TASK_UNINTERRUPTIBLE;
-       if (inode->i_lock) {
-               schedule();
-               goto repeat;
        }
-       remove_wait_queue(&inode->i_wait,&current->wait);
-       current->state = TASK_RUNNING;
-}
-
-static inline void wait_on_inode(struct inode * inode)
-{
-       if (inode->i_lock)
-               __wait_on_inode(inode);
-}
-
-static inline void lock_inode(struct inode * inode)
-{
-       wait_on_inode(inode);
-       inode->i_lock = 1;
-}
-
-static inline void unlock_inode(struct inode * inode)
-{
-       inode->i_lock = 0;
-       wake_up(&inode->i_wait);
+       return 1;
 }
 
 static void write_inode(struct inode * inode)
 {
        if (!inode->i_dirt)
                return;
-       lock_inode(inode);
-       inode->i_dirt = 0;
-       if (inode->i_dev && inode->i_sb &&
-           inode->i_sb->s_op && inode->i_sb->s_op->write_inode)
-               inode->i_sb->s_op->write_inode(inode);
+       wait_on_inode(inode);
+       if (!inode->i_dirt)
+               return;
+       if (!inode->i_sb || !inode->i_sb->s_op || !inode->i_sb->s_op->write_inode) {
+               inode->i_dirt = 0;
+               return;
+       }
+       inode->i_lock = 1;      
+       inode->i_sb->s_op->write_inode(inode);
        unlock_inode(inode);
 }
 
@@ -103,6 +114,22 @@ static void read_inode(struct inode * inode)
        unlock_inode(inode);
 }
 
+/*
+ * notify_change is called for inode-changing operations such as
+ * chown, chmod, utime, and truncate.  It is guaranteed (unlike
+ * write_inode) to be called from the context of the user requesting
+ * the change.  It is not called for ordinary access-time updates.
+ * NFS uses this to get the authentication correct.  -- jrs
+ */
+
+int notify_change(struct inode * inode)
+{
+       if (inode->i_sb && inode->i_sb->s_op  &&
+           inode->i_sb->s_op->notify_change)
+               return inode->i_sb->s_op->notify_change(inode);
+       return 0;
+}
+
 /*
  * bmap is needed for demand-loading and paging: if this function
  * doesn't exist for a filesystem, then those things are impossible:
@@ -133,18 +160,16 @@ void invalidate_inodes(dev_t dev)
                                printk("inode in use on removed disk\n\r");
                                continue;
                        }
-                       inode->i_dev = inode->i_dirt = 0;
+                       clear_inode(inode);
                }
        }
 }
 
 void sync_inodes(dev_t dev)
 {
-       int i;
        struct inode * inode;
 
-       inode = 0+inode_table;
-       for(i=0 ; i<NR_INODE ; i++,inode++) {
+       for(inode = 0+inode_table ; inode < NR_INODE+inode_table ; inode++) {
                wait_on_inode(inode);
                if (inode->i_dirt)
                        write_inode(inode);
@@ -176,10 +201,6 @@ repeat:
                PIPE_BASE(*inode) = NULL;
                free_page(page);
        }
-       if (!inode->i_dev) {
-               inode->i_count--;
-               return;
-       }
        if (inode->i_sb && inode->i_sb->s_op && inode->i_sb->s_op->put_inode) {
                inode->i_sb->s_op->put_inode(inode);
                if (!inode->i_nlink)
@@ -197,34 +218,38 @@ repeat:
 struct inode * get_empty_inode(void)
 {
        struct inode * inode;
-       static struct inode * last_inode = inode_table;
        int i;
 
-       do {
-               inode = NULL;
-               for (i = NR_INODE; i ; i--) {
-                       if (++last_inode >= inode_table + NR_INODE)
-                               last_inode = inode_table;
-                       if (!last_inode->i_count) {
-                               inode = last_inode;
-                               if (!inode->i_dirt && !inode->i_lock)
-                                       break;
-                       }
-               }
-               if (!inode) {
-                       for (i=0 ; i<NR_INODE ; i++)
-                               printk("(%04x: %d (%o)) ",inode_table[i].i_dev,
-                                       inode_table[i].i_ino,inode_table[i].i_mode);
-                       panic("No free inodes in mem");
+repeat:
+       inode = NULL;
+       for (i = NR_INODE; i ; i--) {
+               if (++last_inode >= inode_table + NR_INODE)
+                       last_inode = inode_table;
+               if (!last_inode->i_count) {
+                       inode = last_inode;
+                       if (!inode->i_dirt && !inode->i_lock)
+                               break;
                }
+       }
+       if (!inode) {
+               for (i=0 ; i<NR_INODE ; i++)
+                       printk("(%04x: %d (%o)) ",inode_table[i].i_dev,
+                               inode_table[i].i_ino,inode_table[i].i_mode);
+               panic("No free inodes in mem");
+       }
+       if (inode->i_lock) {
                wait_on_inode(inode);
-               while (inode->i_dirt) {
-                       write_inode(inode);
-                       wait_on_inode(inode);
-               }
-       } while (inode->i_count);
-       memset(inode,0,sizeof(*inode));
+               goto repeat;
+       }
+       if (inode->i_dirt) {
+               write_inode(inode);
+               goto repeat;
+       }
+       if (inode->i_count)
+               goto repeat;
+       clear_inode(inode);
        inode->i_count = 1;
+       inode->i_nlink = 1;
        return inode;
 }
 
@@ -255,12 +280,12 @@ struct inode * iget(struct super_block * sb,int nr)
        empty = get_empty_inode();
        inode = inode_table;
        while (inode < NR_INODE+inode_table) {
-               if (inode->i_sb != sb || inode->i_ino != nr) {
+               if (inode->i_dev != sb->s_dev || inode->i_ino != nr) {
                        inode++;
                        continue;
                }
                wait_on_inode(inode);
-               if (inode->i_sb != sb || inode->i_ino != nr) {
+               if (inode->i_dev != sb->s_dev || inode->i_ino != nr) {
                        inode = inode_table;
                        continue;
                }
@@ -299,3 +324,24 @@ struct inode * iget(struct super_block * sb,int nr)
        read_inode(inode);
        return inode;
 }
+
+/*
+ * The "new" scheduling primitives (new as of 0.97 or so) allow this to
+ * be done without disabling interrupts (other than in the actual queue
+ * updating things: only a couple of 386 instructions). This should be
+ * much better for interrupt latency.
+ */
+static void __wait_on_inode(struct inode * inode)
+{
+       struct wait_queue wait = { current, NULL };
+
+       add_wait_queue(&inode->i_wait, &wait);
+repeat:
+       current->state = TASK_UNINTERRUPTIBLE;
+       if (inode->i_lock) {
+               schedule();
+               goto repeat;
+       }
+       remove_wait_queue(&inode->i_wait, &wait);
+       current->state = TASK_RUNNING;
+}
index adc3af0e71fec5f1c4b9a6d5c064255bf2b67c96..86f829d495a4a99c1c6e1b7f594c4120ac9683ad 100644 (file)
@@ -55,11 +55,11 @@ int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
                return -EBADF;
        switch (cmd) {
                case FIOCLEX:
-                       current->close_on_exec |= (1 << fd);
+                       FD_SET(fd, &current->close_on_exec);
                        return 0;
 
                case FIONCLEX:
-                       current->close_on_exec &= ~(1 << fd);
+                       FD_CLR(fd, &current->close_on_exec);
                        return 0;
 
                case FIONBIO:
index 3df9f7c4ba564a9326a2ddbe0c688a27d783d230..5f7d43a56f295971e817375df65292454f8d6444 100644 (file)
@@ -37,7 +37,8 @@ bitmap.o : bitmap.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/in
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/minix_fs.h /usr/include/linux/string.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/minix_fs.h \
+  /usr/include/linux/string.h 
 blkdev.o : blkdev.c /usr/include/linux/errno.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
   /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
@@ -45,9 +46,9 @@ blkdev.o : blkdev.c /usr/include/linux/errno.h /usr/include/linux/sched.h /usr/i
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
   /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/minix_fs.h \
-  /usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/asm/system.h \
-  /usr/include/linux/stat.h /usr/include/linux/fcntl.h 
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  /usr/include/linux/minix_fs.h /usr/include/linux/tty.h /usr/include/linux/termios.h \
+  /usr/include/asm/system.h /usr/include/linux/stat.h /usr/include/linux/fcntl.h 
 chrdev.o : chrdev.c /usr/include/linux/errno.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
   /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
@@ -55,9 +56,9 @@ chrdev.o : chrdev.c /usr/include/linux/errno.h /usr/include/linux/sched.h /usr/i
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
   /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/minix_fs.h \
-  /usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/asm/system.h \
-  /usr/include/linux/stat.h /usr/include/linux/fcntl.h 
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  /usr/include/linux/minix_fs.h /usr/include/linux/tty.h /usr/include/linux/termios.h \
+  /usr/include/asm/system.h /usr/include/linux/stat.h /usr/include/linux/fcntl.h 
 dir.o : dir.c /usr/include/asm/segment.h /usr/include/linux/errno.h /usr/include/linux/fs.h \
   /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
   /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
@@ -71,7 +72,7 @@ fifo.o : fifo.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/includ
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/minix_fs.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/minix_fs.h 
 file.o : file.c /usr/include/asm/segment.h /usr/include/asm/system.h /usr/include/linux/sched.h \
   /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
   /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
@@ -80,8 +81,8 @@ file.o : file.c /usr/include/asm/segment.h /usr/include/asm/system.h /usr/includ
   /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h \
   /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
   /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
-  /usr/include/linux/minix_fs.h /usr/include/linux/errno.h /usr/include/linux/fcntl.h \
-  /usr/include/linux/stat.h 
+  /usr/include/linux/math_emu.h /usr/include/linux/minix_fs.h /usr/include/linux/errno.h \
+  /usr/include/linux/fcntl.h /usr/include/linux/stat.h /usr/include/linux/locks.h 
 inode.o : inode.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
   /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
   /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
@@ -89,8 +90,9 @@ inode.o : inode.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/incl
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/minix_fs.h /usr/include/linux/string.h \
-  /usr/include/linux/stat.h /usr/include/asm/system.h /usr/include/asm/segment.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/minix_fs.h \
+  /usr/include/linux/string.h /usr/include/linux/stat.h /usr/include/linux/locks.h \
+  /usr/include/asm/system.h /usr/include/asm/segment.h 
 namei.o : namei.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
   /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
   /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
@@ -98,9 +100,9 @@ namei.o : namei.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/incl
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/minix_fs.h /usr/include/linux/string.h \
-  /usr/include/linux/stat.h /usr/include/linux/fcntl.h /usr/include/linux/errno.h \
-  /usr/include/asm/segment.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/minix_fs.h \
+  /usr/include/linux/string.h /usr/include/linux/stat.h /usr/include/linux/fcntl.h \
+  /usr/include/linux/errno.h /usr/include/asm/segment.h 
 symlink.o : symlink.c /usr/include/asm/segment.h /usr/include/linux/errno.h \
   /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
   /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
@@ -109,7 +111,8 @@ symlink.o : symlink.c /usr/include/asm/segment.h /usr/include/linux/errno.h \
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/minix_fs.h /usr/include/linux/stat.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/minix_fs.h \
+  /usr/include/linux/stat.h 
 truncate.o : truncate.c /usr/include/linux/errno.h /usr/include/linux/sched.h \
   /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
   /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
@@ -118,5 +121,6 @@ truncate.o : truncate.c /usr/include/linux/errno.h /usr/include/linux/sched.h \
   /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h \
   /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
   /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
-  /usr/include/linux/minix_fs.h /usr/include/linux/tty.h /usr/include/linux/termios.h \
-  /usr/include/asm/system.h /usr/include/linux/stat.h /usr/include/linux/fcntl.h 
+  /usr/include/linux/math_emu.h /usr/include/linux/minix_fs.h /usr/include/linux/tty.h \
+  /usr/include/linux/termios.h /usr/include/asm/system.h /usr/include/linux/stat.h \
+  /usr/include/linux/fcntl.h 
index c1cf6a1e093f5cff7cece896ec84a8b9a14a3e71..3a9049eb6d7a568853a43fc3b3dfd5ffaeddd5d3 100644 (file)
@@ -158,10 +158,10 @@ void minix_free_inode(struct inode * inode)
        if (!inode)
                return;
        if (!inode->i_dev) {
-               memset(inode,0,sizeof(*inode));
+               printk("free_inode: inode has no device\n");
                return;
        }
-       if (inode->i_count>1) {
+       if (inode->i_count != 1) {
                printk("free_inode: inode has count=%d\n",inode->i_count);
                return;
        }
@@ -182,9 +182,9 @@ void minix_free_inode(struct inode * inode)
                return;
        }
        if (clear_bit(inode->i_ino&8191,bh->b_data))
-               printk("free_inode: bit already cleared.\n\r");
+               printk("free_inode: bit %d already cleared.\n",inode->i_ino);
        bh->b_dirt = 1;
-       memset(inode,0,sizeof(*inode));
+       clear_inode(inode);
 }
 
 struct inode * minix_new_inode(struct super_block * sb)
index 57fb4d5f1685a31184018b4d424266382e1cdb6d..13b54f0e73b9dac997524a22b80e47ca914506e9 100644 (file)
@@ -94,7 +94,7 @@ static int minix_file_read(struct inode * inode, struct file * filp, char * buf,
                        --blocks;
                        *bhb = minix_getblk(inode,block++,0);
                        if (*bhb && !(*bhb)->b_uptodate)
-                               ll_rw_block(READ,*bhb);
+                               ll_rw_block(READ, 1, bhb);
 
                        if (++bhb == &buflist[NBUF])
                                bhb = buflist;
@@ -177,7 +177,7 @@ static int minix_file_write(struct inode * inode, struct file * filp, char * buf
                if (c > count-written)
                        c = count-written;
                if (c != BLOCK_SIZE && !bh->b_uptodate) {
-                       ll_rw_block(READ,bh);
+                       ll_rw_block(READ, 1, &bh);
                        wait_on_buffer(bh);
                        if (!bh->b_uptodate) {
                                brelse(bh);
index 651f397d375c89019bc5451e2c3ccaa9a6046a89..273187b37fd4a5deae2a3c9362232646c97809f8 100644 (file)
@@ -40,6 +40,7 @@ void minix_put_super(struct super_block *sb)
 
 static struct super_operations minix_sops = { 
        minix_read_inode,
+       NULL,
        minix_write_inode,
        minix_put_inode,
        minix_put_super,
@@ -53,11 +54,13 @@ struct super_block *minix_read_super(struct super_block *s,void *data)
        struct minix_super_block *ms;
        int i,dev=s->s_dev,block;
 
+       if (32 != sizeof (struct minix_inode))
+               panic("bad i-node size");
        lock_super(s);
        if (!(bh = bread(dev,1,BLOCK_SIZE))) {
                s->s_dev=0;
                unlock_super(s);
-               printk("bread failed\n");
+               printk("MINIX-fs: unable to read superblock\n");
                return NULL;
        }
        ms = (struct minix_super_block *) bh->b_data;
@@ -74,7 +77,7 @@ struct super_block *minix_read_super(struct super_block *s,void *data)
        if (s->s_magic != MINIX_SUPER_MAGIC) {
                s->s_dev = 0;
                unlock_super(s);
-               printk("magic match failed\n");
+               printk("MINIX-fs magic match failed\n");
                return NULL;
        }
        for (i=0;i < MINIX_I_MAP_SLOTS;i++)
@@ -99,7 +102,7 @@ struct super_block *minix_read_super(struct super_block *s,void *data)
                        brelse(s->u.minix_sb.s_zmap[i]);
                s->s_dev=0;
                unlock_super(s);
-               printk("block failed\n");
+               printk("MINIX-fs: bad superblock or unable to read bitmaps\n");
                return NULL;
        }
        s->u.minix_sb.s_imap[0]->b_data[0] |= 1;
@@ -111,7 +114,7 @@ struct super_block *minix_read_super(struct super_block *s,void *data)
        unlock_super(s);
        if (!s->s_mounted) {
                s->s_dev = 0;
-               printk("get root inode failed\n");
+               printk("MINIX-fs: get root inode failed\n");
                return NULL;
        }
        return s;
@@ -219,7 +222,7 @@ static struct buffer_head * block_getblk(struct inode * inode,
        if (!bh)
                return NULL;
        if (!bh->b_uptodate) {
-               ll_rw_block(READ,bh);
+               ll_rw_block(READ, 1, &bh);
                wait_on_buffer(bh);
                if (!bh->b_uptodate) {
                        brelse(bh);
@@ -291,7 +294,7 @@ struct buffer_head * minix_bread(struct inode * inode, int block, int create)
        bh = minix_getblk(inode,block,create);
        if (!bh || bh->b_uptodate)
                return bh;
-       ll_rw_block(READ,bh);
+       ll_rw_block(READ, 1, &bh);
        wait_on_buffer(bh);
        if (bh->b_uptodate)
                return bh;
@@ -303,14 +306,16 @@ void minix_read_inode(struct inode * inode)
 {
        struct buffer_head * bh;
        struct minix_inode * raw_inode;
-       int block;
+       int block, ino;
 
-       block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks + inode->i_sb->u.minix_sb.s_zmap_blocks +
-               (inode->i_ino-1)/MINIX_INODES_PER_BLOCK;
+       ino = inode->i_ino;
+       block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks +
+                   inode->i_sb->u.minix_sb.s_zmap_blocks +
+                   (ino-1)/MINIX_INODES_PER_BLOCK;
        if (!(bh=bread(inode->i_dev,block, BLOCK_SIZE)))
                panic("unable to read i-node block");
        raw_inode = ((struct minix_inode *) bh->b_data) +
-               (inode->i_ino-1)%MINIX_INODES_PER_BLOCK;
+                   (ino-1)%MINIX_INODES_PER_BLOCK;
        inode->i_mode = raw_inode->i_mode;
        inode->i_uid = raw_inode->i_uid;
        inode->i_gid = raw_inode->i_gid;
@@ -366,7 +371,7 @@ void minix_write_inode(struct inode * inode)
                raw_inode->i_zone[0] = inode->i_rdev;
        else for (block = 0; block < 9; block++)
                raw_inode->i_zone[block] = inode->u.minix_i.i_data[block];
-       bh->b_dirt=1;
        inode->i_dirt=0;
+       bh->b_dirt=1;
        brelse(bh);
 }
index a5e098d18f703c706d896d00f64530575d4e9c77..1093294fd000bb42260e742ac7702240d2b70530 100644 (file)
@@ -136,6 +136,9 @@ int minix_lookup(struct inode * dir,const char * name, int len,
  * NOTE!! The inode part of 'de' is left at 0 - which means you
  * may not sleep between calling this and putting something into
  * the entry, as someone else might have used it while you slept.
+ *
+ * Arggh. To avoid race-conditions, we copy the name into kernel
+ * space before actually writing it into the buffer...
  */
 static struct buffer_head * minix_add_entry(struct inode * dir,
        const char * name, int namelen, struct minix_dir_entry ** res_dir)
@@ -143,22 +146,25 @@ static struct buffer_head * minix_add_entry(struct inode * dir,
        int i;
        struct buffer_head * bh;
        struct minix_dir_entry * de;
+       char name_buffer[MINIX_NAME_LEN];
 
        *res_dir = NULL;
        if (!dir)
                return NULL;
+       if (namelen > MINIX_NAME_LEN) {
 #ifdef NO_TRUNCATE
-       if (namelen > MINIX_NAME_LEN)
                return NULL;
 #else
-       if (namelen > MINIX_NAME_LEN)
                namelen = MINIX_NAME_LEN;
 #endif
+       }
        if (!namelen)
                return NULL;
        bh =  minix_bread(dir,0,0);
        if (!bh)
                return NULL;
+       for (i = 0; i < MINIX_NAME_LEN ; i++)
+               name_buffer[i] = (i<namelen) ? get_fs_byte(name+i) : 0;
        i = 0;
        de = (struct minix_dir_entry *) bh->b_data;
        while (1) {
@@ -177,8 +183,7 @@ static struct buffer_head * minix_add_entry(struct inode * dir,
                }
                if (!de->inode) {
                        dir->i_mtime = CURRENT_TIME;
-                       for (i=0; i < MINIX_NAME_LEN ; i++)
-                               de->name[i]=(i<namelen)?get_fs_byte(name+i):0;
+                       memcpy(de->name,name_buffer,MINIX_NAME_LEN);
                        bh->b_dirt = 1;
                        *res_dir = de;
                        return bh;
@@ -441,6 +446,7 @@ int minix_unlink(struct inode * dir, const char * name, int len)
        struct buffer_head * bh;
        struct minix_dir_entry * de;
 
+repeat:
        retval = -ENOENT;
        inode = NULL;
        bh = minix_find_entry(dir,name,len,&de);
@@ -448,6 +454,13 @@ int minix_unlink(struct inode * dir, const char * name, int len)
                goto end_unlink;
        if (!(inode = iget(dir->i_sb, de->inode)))
                goto end_unlink;
+       if (de->inode != inode->i_ino) {
+               iput(inode);
+               brelse(bh);
+               current->counter = 0;
+               schedule();
+               goto repeat;
+       }
        retval = -EPERM;
        if ((dir->i_mode & S_ISVTX) && !suser() &&
            current->euid != inode->i_uid &&
@@ -462,9 +475,11 @@ int minix_unlink(struct inode * dir, const char * name, int len)
        }
        de->inode = 0;
        bh->b_dirt = 1;
+       dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+       dir->i_dirt = 1;
        inode->i_nlink--;
-       inode->i_dirt = 1;
        inode->i_ctime = CURRENT_TIME;
+       inode->i_dirt = 1;
        retval = 0;
 end_unlink:
        brelse(bh);
index c3700df40b79f87896cd0bc1498b049c0e6469f8..6fd9644f1973f81df31c16ac541b783d2d7f3232 100644 (file)
@@ -36,8 +36,8 @@ dir.o : dir.c /usr/include/asm/segment.h /usr/include/linux/sched.h /usr/include
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
   /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/msdos_fs.h \
-  /usr/include/linux/errno.h /usr/include/linux/stat.h 
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  /usr/include/linux/msdos_fs.h /usr/include/linux/errno.h /usr/include/linux/stat.h 
 fat.o : fat.c /usr/include/linux/msdos_fs.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
   /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
   /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
@@ -52,8 +52,8 @@ file.o : file.c /usr/include/asm/segment.h /usr/include/asm/system.h /usr/includ
   /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h \
   /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
   /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
-  /usr/include/linux/msdos_fs.h /usr/include/linux/errno.h /usr/include/linux/fcntl.h \
-  /usr/include/linux/stat.h 
+  /usr/include/linux/math_emu.h /usr/include/linux/msdos_fs.h /usr/include/linux/errno.h \
+  /usr/include/linux/fcntl.h /usr/include/linux/stat.h 
 inode.o : inode.c /usr/include/linux/msdos_fs.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
   /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
   /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
@@ -61,9 +61,9 @@ inode.o : inode.c /usr/include/linux/msdos_fs.h /usr/include/linux/fs.h /usr/inc
   /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/kernel.h \
   /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/mm.h \
   /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/errno.h \
-  /usr/include/linux/string.h /usr/include/linux/ctype.h /usr/include/linux/stat.h \
-  /usr/include/asm/segment.h 
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  /usr/include/linux/errno.h /usr/include/linux/string.h /usr/include/linux/ctype.h \
+  /usr/include/linux/stat.h /usr/include/linux/locks.h /usr/include/asm/segment.h 
 misc.o : misc.c /usr/include/linux/msdos_fs.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
   /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
   /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
@@ -71,8 +71,8 @@ misc.o : misc.c /usr/include/linux/msdos_fs.h /usr/include/linux/fs.h /usr/inclu
   /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/sched.h \
   /usr/include/linux/head.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
   /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/errno.h \
-  /usr/include/linux/string.h /usr/include/linux/stat.h 
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  /usr/include/linux/errno.h /usr/include/linux/string.h /usr/include/linux/stat.h 
 namei.o : namei.c /usr/include/asm/segment.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
   /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
@@ -80,5 +80,6 @@ namei.o : namei.c /usr/include/asm/segment.h /usr/include/linux/sched.h /usr/inc
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
   /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/msdos_fs.h \
-  /usr/include/linux/errno.h /usr/include/linux/string.h /usr/include/linux/stat.h 
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  /usr/include/linux/msdos_fs.h /usr/include/linux/errno.h /usr/include/linux/string.h \
+  /usr/include/linux/stat.h 
index 16e4d1e56ee47628ae10cdd19d8eb8ca3cb1048e..dfba9331b5758a59fd3948f5adddcf4783c74198 100644 (file)
@@ -24,7 +24,7 @@ void msdos_put_inode(struct inode *inode)
        inode->i_size = 0;
        msdos_truncate(inode);
        depend = MSDOS_I(inode)->i_depend;
-       memset(inode,0,sizeof(struct inode));
+       clear_inode(inode);
        if (depend) {
                if (MSDOS_I(depend)->i_old != inode) {
                        printk("Invalid link (0x%X): expected 0x%X, got "
@@ -50,6 +50,7 @@ void msdos_put_super(struct super_block *sb)
 
 static struct super_operations msdos_sops = { 
        msdos_read_inode,
+       NULL,
        msdos_write_inode,
        msdos_put_inode,
        msdos_put_super,
index 17c21859fe5ef9a668555b76886ff4d0a60d010d..930975b47bc4a99ec0d593082edae4416244c15c 100644 (file)
@@ -144,6 +144,10 @@ static int dir_namei(const char * pathname, int * namelen, const char ** name,
                if (error)
                        return error;
        }
+       if (!base->i_op || !base->i_op->lookup) {
+               iput(base);
+               return -ENOTDIR;
+       }
        *name = thisname;
        *namelen = len;
        *res_inode = base;
index 1193e17370311646325fc8182670836571741420..610316b298062c27157a0ad9fcff27adea9f6b0c 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -15,6 +15,8 @@
 #include <linux/kernel.h>
 #include <linux/signal.h>
 #include <linux/tty.h>
+#include <linux/time.h>
+
 #include <asm/segment.h>
 
 extern void fcntl_remove_locks(struct task_struct *, struct file *);
@@ -87,8 +89,9 @@ int sys_truncate(const char * path, unsigned int length)
                inode->i_op->truncate(inode);
        inode->i_atime = inode->i_mtime = CURRENT_TIME;
        inode->i_dirt = 1;
+       error = notify_change(inode);
        iput(inode);
-       return 0;
+       return error;
 }
 
 int sys_ftruncate(unsigned int fd, unsigned int length)
@@ -107,7 +110,7 @@ int sys_ftruncate(unsigned int fd, unsigned int length)
                inode->i_op->truncate(inode);
        inode->i_atime = inode->i_mtime = CURRENT_TIME;
        inode->i_dirt = 1;
-       return 0;
+       return notify_change(inode);
 }
 
 /* If times==NULL, set access and modification to current time,
@@ -144,9 +147,11 @@ int sys_utime(char * filename, struct utimbuf * times)
        }
        inode->i_atime = actime;
        inode->i_mtime = modtime;
+       inode->i_ctime = CURRENT_TIME;
        inode->i_dirt = 1;
+       error = notify_change(inode);
        iput(inode);
-       return 0;
+       return error;
 }
 
 /*
@@ -239,7 +244,7 @@ int sys_fchmod(unsigned int fd, mode_t mode)
                return -EROFS;
        inode->i_mode = (mode & 07777) | (inode->i_mode & ~07777);
        inode->i_dirt = 1;
-       return 0;
+       return notify_change(inode);
 }
 
 int sys_chmod(const char * filename, mode_t mode)
@@ -260,8 +265,9 @@ int sys_chmod(const char * filename, mode_t mode)
        }
        inode->i_mode = (mode & 07777) | (inode->i_mode & ~07777);
        inode->i_dirt = 1;
+       error = notify_change(inode);
        iput(inode);
-       return 0;
+       return error;
 }
 
 int sys_fchown(unsigned int fd, uid_t user, gid_t group)
@@ -275,13 +281,17 @@ int sys_fchown(unsigned int fd, uid_t user, gid_t group)
                return -ENOENT;
        if (IS_RDONLY(inode))
                return -EROFS;
+       if (user == (uid_t) -1)
+               user = inode->i_uid;
+       if (group == (gid_t) -1)
+               group = inode->i_gid;
        if ((current->euid == inode->i_uid && user == inode->i_uid &&
             (in_group_p(group) || group == inode->i_gid)) ||
            suser()) {
                inode->i_uid = user;
                inode->i_gid = group;
-               inode->i_dirt=1;
-               return 0;
+               inode->i_dirt = 1;
+               return notify_change(inode);
        }
        return -EPERM;
 }
@@ -298,14 +308,19 @@ int sys_chown(const char * filename, uid_t user, gid_t group)
                iput(inode);
                return -EROFS;
        }
+       if (user == (uid_t) -1)
+               user = inode->i_uid;
+       if (group == (gid_t) -1)
+               group = inode->i_gid;
        if ((current->euid == inode->i_uid && user == inode->i_uid &&
             (in_group_p(group) || group == inode->i_gid)) ||
            suser()) {
                inode->i_uid = user;
                inode->i_gid = group;
-               inode->i_dirt=1;
+               inode->i_dirt = 1;
+               error = notify_change(inode);
                iput(inode);
-               return 0;
+               return error;
        }
        iput(inode);
        return -EPERM;
@@ -336,7 +351,7 @@ int sys_open(const char * filename,int flag,int mode)
                        break;
        if (fd>=NR_OPEN)
                return -EMFILE;
-       current->close_on_exec &= ~(1<<fd);
+       FD_CLR(fd,&current->close_on_exec);
        f = get_empty_filp();
        if (!f)
                return -ENFILE;
@@ -352,11 +367,17 @@ int sys_open(const char * filename,int flag,int mode)
                f->f_count--;
                return i;
        }
-       if (flag & O_TRUNC)
-               if (inode->i_op && inode->i_op->truncate) {
-                       inode->i_size = 0;
+       if (flag & O_TRUNC) {
+               inode->i_size = 0;
+               if (inode->i_op && inode->i_op->truncate)
                        inode->i_op->truncate(inode);
+               if ((i = notify_change(inode))) {
+                       iput(inode);
+                       current->filp[fd] = NULL;
+                       f->f_count--;
+                       return i;
                }
+       }
        if (!IS_RDONLY(inode)) {
                inode->i_atime = CURRENT_TIME;
                inode->i_dirt = 1;
@@ -374,6 +395,7 @@ int sys_open(const char * filename,int flag,int mode)
                        current->filp[fd]=NULL;
                        return i;
                }
+       f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
        return (fd);
 }
 
@@ -382,7 +404,7 @@ int sys_creat(const char * pathname, int mode)
        return sys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode);
 }
 
-static int close_fp(struct file *filp)
+int close_fp(struct file *filp)
 {
        struct inode *inode;
 
@@ -411,7 +433,7 @@ int sys_close(unsigned int fd)
 
        if (fd >= NR_OPEN)
                return -EINVAL;
-       current->close_on_exec &= ~(1<<fd);
+       FD_CLR(fd, &current->close_on_exec);
        if (!(filp = current->filp[fd]))
                return -EINVAL;
        current->filp[fd] = NULL;
@@ -494,7 +516,7 @@ int sys_vhangup(void)
 
                  /* finally close the file. */
 
-                               (*process)->close_on_exec &= ~(1<<j);
+                               FD_CLR(j, &(*process)->close_on_exec);
                                close_fp (filep);
                        }
                }
index aafb266af53256beeeedd34809bc1c2b9ec9b807..fd3ad653c1e9128bf1b56c7d7600467d5c087967 100644 (file)
@@ -37,7 +37,7 @@ base.o : base.c /usr/include/asm/segment.h /usr/include/linux/errno.h /usr/inclu
   /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h \
   /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
   /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
-  /usr/include/linux/proc_fs.h /usr/include/linux/stat.h 
+  /usr/include/linux/math_emu.h /usr/include/linux/proc_fs.h /usr/include/linux/stat.h 
 fd.o : fd.c /usr/include/asm/segment.h /usr/include/linux/errno.h /usr/include/linux/sched.h \
   /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
   /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
@@ -46,7 +46,7 @@ fd.o : fd.c /usr/include/asm/segment.h /usr/include/linux/errno.h /usr/include/l
   /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h \
   /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
   /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
-  /usr/include/linux/proc_fs.h /usr/include/linux/stat.h 
+  /usr/include/linux/math_emu.h /usr/include/linux/proc_fs.h /usr/include/linux/stat.h 
 inode.o : inode.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
   /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
   /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
@@ -54,8 +54,9 @@ inode.o : inode.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/incl
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/proc_fs.h /usr/include/linux/string.h \
-  /usr/include/linux/stat.h /usr/include/asm/system.h /usr/include/asm/segment.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/proc_fs.h \
+  /usr/include/linux/string.h /usr/include/linux/stat.h /usr/include/linux/locks.h \
+  /usr/include/asm/system.h /usr/include/asm/segment.h 
 link.o : link.c /usr/include/asm/segment.h /usr/include/linux/errno.h /usr/include/linux/sched.h \
   /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
   /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
@@ -64,7 +65,7 @@ link.o : link.c /usr/include/asm/segment.h /usr/include/linux/errno.h /usr/inclu
   /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h \
   /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
   /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
-  /usr/include/linux/minix_fs.h /usr/include/linux/stat.h 
+  /usr/include/linux/math_emu.h /usr/include/linux/minix_fs.h /usr/include/linux/stat.h 
 mem.o : mem.c /usr/include/linux/types.h /usr/include/linux/errno.h /usr/include/linux/sched.h \
   /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
   /usr/include/linux/wait.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
@@ -72,8 +73,8 @@ mem.o : mem.c /usr/include/linux/types.h /usr/include/linux/errno.h /usr/include
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
   /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/asm/segment.h \
-  /usr/include/asm/io.h 
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  /usr/include/asm/segment.h /usr/include/asm/io.h 
 root.o : root.c /usr/include/asm/segment.h /usr/include/linux/errno.h /usr/include/linux/sched.h \
   /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
   /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
@@ -82,4 +83,4 @@ root.o : root.c /usr/include/asm/segment.h /usr/include/linux/errno.h /usr/inclu
   /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h \
   /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
   /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
-  /usr/include/linux/proc_fs.h /usr/include/linux/stat.h 
+  /usr/include/linux/math_emu.h /usr/include/linux/proc_fs.h /usr/include/linux/stat.h 
index e4303b41fc1e45b9081bb8c8756e882284a8cf4c..5451bdb86918d64bbfac47ac535a61a4aca7cbdf 100644 (file)
@@ -31,6 +31,7 @@ void proc_put_super(struct super_block *sb)
 
 static struct super_operations proc_sops = { 
        proc_read_inode,
+       NULL,
        proc_write_inode,
        proc_put_inode,
        proc_put_super,
index caac6990330d8424f07f4c094afb5e522ac1a22b..100e73b3d258777c12728cdfbf5a853eb8c7f1f8 100644 (file)
  * Ok, Peter made a complicated, but straightforward multiple_wait() function.
  * I have rewritten this, taking some shortcuts: This code may not be easy to
  * follow, but it should be free of race-conditions, and it's practical. If you
- * understand what I'm doing here, then you understand how the linux sleep/wakeup
- * mechanism works.
+ * understand what I'm doing here, then you understand how the linux
+ * sleep/wakeup mechanism works.
  *
  * Two very simple procedures, select_wait() and free_wait() make all the work.
- * select_wait() is a inline-function defined in <linux/fs.h>, as all select
+ * select_wait() is a inline-function defined in <linux/sched.h>, as all select
  * functions have to call it to add an entry to the select table.
  */
 
+/*
+ * I rewrote this again to make the select_table size variable, take some
+ * more shortcuts, improve responsiveness, and remove another race that
+ * Linus noticed.  -- jrs
+ */
+
 static void free_wait(select_table * p)
 {
        struct select_table_entry * entry = p->entry + p->nr;
@@ -42,89 +48,126 @@ static void free_wait(select_table * p)
 }
 
 /*
- * The check_XX functions check out a file. We know it's either
- * a pipe, a character device or a fifo
+ * The check function checks the ready status of a file using the vfs layer.
+ *
+ * If the file was not ready we were added to its wait queue.  But in
+ * case it became ready just after the check and just before it called
+ * select_wait, we call it again, knowing we are already on its
+ * wait queue this time.  The second call is not necessary if the
+ * select_table is NULL indicating an earlier file check was ready
+ * and we aren't going to sleep on the select_table.  -- jrs
  */
-static int check_in(select_table * wait, struct inode * inode, struct file * file)
-{
-       if (file->f_op && file->f_op->select)
-               return file->f_op->select(inode,file,SEL_IN,wait);
-       if (inode && S_ISREG(inode->i_mode))
-               return 1;
-       return 0;
-}
 
-static int check_out(select_table * wait, struct inode * inode, struct file * file)
+static int check(int flag, select_table * wait, struct file * file)
 {
-       if (file->f_op && file->f_op->select)
-               return file->f_op->select(inode,file,SEL_OUT,wait);
-       if (inode && S_ISREG(inode->i_mode))
-               return 1;
-       return 0;
-}
+       struct inode * inode;
+       struct file_operations *fops;
+       int (*select) (struct inode *, struct file *, int, select_table *);
 
-static int check_ex(select_table * wait, struct inode * inode, struct file * file)
-{
-       if (file->f_op && file->f_op->select)
-               return file->f_op->select(inode,file,SEL_EX,wait);
-       if (inode && S_ISREG(inode->i_mode))
+       inode = file->f_inode;
+       if ((fops = file->f_op) && (select = fops->select))
+               return select(inode, file, flag, wait)
+                   || (wait && select(inode, file, flag, NULL));
+       if (S_ISREG(inode->i_mode))
                return 1;
        return 0;
 }
 
-int do_select(fd_set in, fd_set out, fd_set ex,
-       fd_set *inp, fd_set *outp, fd_set *exp)
+int do_select(int n, fd_set *in, fd_set *out, fd_set *ex,
+       fd_set *res_in, fd_set *res_out, fd_set *res_ex)
 {
        int count;
-       select_table wait_table;
-       struct file * file;
+       select_table wait_table, *wait;
+       struct select_table_entry *entry;
        int i;
-       fd_set mask;
+       int max;
 
-       mask = in | out | ex;
-       for (i = 0 ; i < NR_OPEN ; i++,mask >>= 1) {
-               if (!(mask & 1))
+       max = -1;
+       for (i = 0 ; i < n ; i++) {
+               if (!FD_ISSET(i, in) &&
+                   !FD_ISSET(i, out) &&
+                   !FD_ISSET(i, ex))
                        continue;
                if (!current->filp[i])
                        return -EBADF;
                if (!current->filp[i]->f_inode)
                        return -EBADF;
+               max = i;
        }
+       n = max + 1;
+       entry = (struct select_table_entry *) get_free_page(GFP_KERNEL);
+       if (!entry)
+               return -ENOMEM;
+       FD_ZERO(res_in);
+       FD_ZERO(res_out);
+       FD_ZERO(res_ex);
+       count = 0;
 repeat:
        wait_table.nr = 0;
-       *inp = *outp = *exp = 0;
-       count = 0;
+       wait_table.entry = entry;
        current->state = TASK_INTERRUPTIBLE;
-       mask = 1;
-       for (i = 0 ; i < NR_OPEN ; i++, mask += mask) {
-               file = current->filp[i];
-               if (mask & in)
-                       if (check_in(&wait_table,file->f_inode,file)) {
-                               *inp |= mask;
-                               count++;
-                       }
-               if (mask & out)
-                       if (check_out(&wait_table,file->f_inode,file)) {
-                               *outp |= mask;
-                               count++;
-                       }
-               if (mask & ex)
-                       if (check_ex(&wait_table,file->f_inode,file)) {
-                               *exp |= mask;
-                               count++;
-                       }
+       wait = &wait_table;
+       for (i = 0 ; i < n ; i++) {
+               if (FD_ISSET(i,in) && check(SEL_IN,wait,current->filp[i])) {
+                       FD_SET(i, res_in);
+                       count++;
+                       wait = NULL;
+               }
+               if (FD_ISSET(i,out) && check(SEL_OUT,wait,current->filp[i])) {
+                       FD_SET(i, res_out);
+                       count++;
+                       wait = NULL;
+               }
+               if (FD_ISSET(i,ex) && check(SEL_EX,wait,current->filp[i])) {
+                       FD_SET(i, res_ex);
+                       count++;
+                       wait = NULL;
+               }
        }
-       if (!(current->signal & ~current->blocked) &&
-           current->timeout && !count) {
+       if (!count && current->timeout
+           && !(current->signal & ~current->blocked)) {
                schedule();
                free_wait(&wait_table);
                goto repeat;
        }
        free_wait(&wait_table);
+       free_page((unsigned long) entry);
        current->state = TASK_RUNNING;
        return count;
 }
 
+static void __get_fd_set(int nr, unsigned long * fs_pointer, unsigned long * fdset)
+{
+       FD_ZERO(fdset);
+       if (!fs_pointer)
+               return;
+       while (nr > 0) {
+               *fdset = get_fs_long(fs_pointer);
+               fdset++;
+               fs_pointer++;
+               nr -= 32;
+       }
+}
+
+static void __set_fd_set(int nr, unsigned long * fs_pointer, unsigned long * fdset)
+{
+       if (!fs_pointer)
+               return;
+       verify_area(fs_pointer, sizeof(fd_set));
+       while (nr > 0) {
+               put_fs_long(*fdset, fs_pointer);
+               fdset++;
+               fs_pointer++;
+               nr -= 32;
+       }
+}
+
+#define get_fd_set(nr,fsp,fdp) \
+__get_fd_set(nr, (unsigned long *) (fsp), (unsigned long *) (fdp))
+
+#define set_fd_set(nr,fsp,fdp) \
+__set_fd_set(nr, (unsigned long *) (fsp), (unsigned long *) (fdp))
+
 /*
  * We can actually return ERESTARTSYS insetad of EINTR, but I'd
  * like to be certain this leads to no problems. So I return
@@ -134,29 +177,25 @@ int sys_select( unsigned long *buffer )
 {
 /* Perform the select(nd, in, out, ex, tv) system call. */
        int i;
-       fd_set res_in, in = 0, *inp;
-       fd_set res_out, out = 0, *outp;
-       fd_set res_ex, ex = 0, *exp;
-       fd_set mask;
+       fd_set res_in, in, *inp;
+       fd_set res_out, out, *outp;
+       fd_set res_ex, ex, *exp;
+       int n;
        struct timeval *tvp;
        unsigned long timeout;
 
-       mask = get_fs_long(buffer++);
-       if (mask >= 32)
-               mask = ~0;
-       else
-               mask = ~((~0) << mask);
+       n = get_fs_long(buffer++);
+       if (n < 0)
+               return -EINVAL;
+       if (n > NR_OPEN)
+               n = NR_OPEN;
        inp = (fd_set *) get_fs_long(buffer++);
        outp = (fd_set *) get_fs_long(buffer++);
        exp = (fd_set *) get_fs_long(buffer++);
        tvp = (struct timeval *) get_fs_long(buffer);
-
-       if (inp)
-               in = mask & get_fs_long(inp);
-       if (outp)
-               out = mask & get_fs_long(outp);
-       if (exp)
-               ex = mask & get_fs_long(exp);
+       get_fd_set(n, inp, &in);
+       get_fd_set(n, outp, &out);
+       get_fd_set(n, exp, &ex);
        timeout = 0xffffffff;
        if (tvp) {
                timeout = get_fs_long((unsigned long *)&tvp->tv_usec)/(1000000/HZ);
@@ -164,7 +203,7 @@ int sys_select( unsigned long *buffer )
                timeout += jiffies;
        }
        current->timeout = timeout;
-       i = do_select(in, out, ex, &res_in, &res_out, &res_ex);
+       i = do_select(n, &in, &out, &ex, &res_in, &res_out, &res_ex);
        if (current->timeout > jiffies)
                timeout = current->timeout - jiffies;
        else
@@ -181,17 +220,8 @@ int sys_select( unsigned long *buffer )
                return i;
        if (!i && (current->signal & ~current->blocked))
                return -EINTR;
-       if (inp) {
-               verify_area(inp, 4);
-               put_fs_long(res_in,inp);
-       }
-       if (outp) {
-               verify_area(outp,4);
-               put_fs_long(res_out,outp);
-       }
-       if (exp) {
-               verify_area(exp,4);
-               put_fs_long(res_ex,exp);
-       }
+       set_fd_set(n, inp, &res_in);
+       set_fd_set(n, outp, &res_out);
+       set_fd_set(n, exp, &res_ex);
        return i;
 }
index 1a5b92cc211522f60a59db86d108c736e25965eb..79dad573d1057a4da532e5ef00fc3b25dd5d2431 100644 (file)
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -15,8 +15,7 @@ static void cp_old_stat(struct inode * inode, struct old_stat * statbuf)
 {
        struct old_stat tmp;
 
-       if (inode->i_ino & 0xffff0000)
-               printk("Warning: using old stat() call on bigfs\n");
+       printk("Warning: using old stat() call. Recompile your binary.\n");
        verify_area(statbuf,sizeof (*statbuf));
        tmp.st_dev = inode->i_dev;
        tmp.st_ino = inode->i_ino;
@@ -69,9 +68,11 @@ static void cp_new_stat(struct inode * inode, struct new_stat * statbuf)
                        blocks += indirect;
                }
                tmp.st_blocks = blocks;
-       } else
-               tmp.st_blocks = (inode->i_blocks * inode->i_blksize) / 512;
-       tmp.st_blksize = 512;
+               tmp.st_blksize = BLOCK_SIZE;
+       } else {
+               tmp.st_blocks = inode->i_blocks;
+               tmp.st_blksize = inode->i_blksize;
+       }
        memcpy_tofs(statbuf,&tmp,sizeof(tmp));
 }
 
index 1062eed8d76588d295312273469e5e9e7c191a80..4c75b07619c326f684943e77564c772d5e9ff0a3 100644 (file)
@@ -9,63 +9,54 @@
  */
 #include <linux/config.h>
 #include <linux/sched.h>
-#include <linux/minix_fs.h>
-#include <linux/proc_fs.h>
-#include <linux/ext_fs.h>
-#include <linux/msdos_fs.h>
 #include <linux/kernel.h>
 #include <linux/stat.h>
 #include <linux/errno.h>
+#include <linux/string.h>
 #include <linux/locks.h>
 
 #include <asm/system.h>
 #include <asm/segment.h>
+/*
+ * The definition of file_systems that used to be here is now in
+ * filesystems.c.  Now super.c contains no fs specific code.  -- jrs
+ */
 
-void wait_for_keypress(void);
-void fcntl_init_locks(void);
+extern struct file_system_type file_systems[];
 
-/* set_bit uses setb, as gas doesn't recognize setc */
-#define set_bit(bitnr,addr) ({ \
-register int __res __asm__("ax"); \
-__asm__("bt %2,%3;setb %%al":"=a" (__res):"a" (0),"r" (bitnr),"m" (*(addr))); \
-__res; })
+extern void wait_for_keypress(void);
+extern void fcntl_init_locks(void);
 
 struct super_block super_block[NR_SUPER];
+
 /* this is initialized in init/main.c */
 dev_t ROOT_DEV = 0;
 
-/* Move into include file later */
-
-static struct file_system_type file_systems[] = {
-       {minix_read_super,"minix"},
-       {ext_read_super,"ext"},
-       {msdos_read_super,"msdos"},
-       {proc_read_super,"proc"},
-       {NULL,NULL}
-};
-
-/* end of include file */
-
 struct file_system_type *get_fs_type(char *name)
 {
        int a;
        
+       if (!name)
+               return &file_systems[0];
        for(a = 0 ; file_systems[a].read_super ; a++)
                if (!strcmp(name,file_systems[a].name))
                        return(&file_systems[a]);
-       return(NULL);
+       return NULL;
 }
 
 void __wait_on_super(struct super_block * sb)
 {
-       add_wait_queue(&sb->s_wait,&current->wait);
+       struct wait_queue wait = { current, NULL };
+
+       add_wait_queue(&sb->s_wait, &wait);
 repeat:
        current->state = TASK_UNINTERRUPTIBLE;
        if (sb->s_lock) {
                schedule();
                goto repeat;
        }
-       remove_wait_queue(&sb->s_wait,&current->wait);
+       remove_wait_queue(&sb->s_wait, &wait);
        current->state = TASK_RUNNING;
 }
 
@@ -155,6 +146,43 @@ static struct super_block * read_super(dev_t dev,char *name,int flags,void *data
        return s;
 }
 
+/*
+ * Unnamed block devices are dummy devices used by virtual
+ * filesystems which don't use real block-devices.  -- jrs
+ */
+
+static char unnamed_dev_in_use[256];
+
+static dev_t get_unnamed_dev(void)
+{
+       static int first_use = 0;
+       int i;
+
+       if (first_use == 0) {
+               first_use = 1;
+               memset(unnamed_dev_in_use, 0, sizeof(unnamed_dev_in_use));
+               unnamed_dev_in_use[0] = 1; /* minor 0 (nodev) is special */
+       }
+       for (i = 0; i < 256; i++) {
+               if (!unnamed_dev_in_use[i]) {
+                       unnamed_dev_in_use[i] = 1;
+                       return (UNNAMED_MAJOR << 8) | i;
+               }
+       }
+       return 0;
+}
+
+static void put_unnamed_dev(dev_t dev)
+{
+       if (!dev)
+               return;
+       if (!unnamed_dev_in_use[dev]) {
+               printk("put_unnamed_dev: trying to free unused device\n");
+               return;
+       }
+       unnamed_dev_in_use[dev] = 0;
+}
+
 static int do_umount(dev_t dev)
 {
        struct super_block * sb;
@@ -173,38 +201,68 @@ static int do_umount(dev_t dev)
        iput(sb->s_mounted);
        sb->s_mounted = NULL;
        if (sb->s_op && sb->s_op->write_super && sb->s_dirt)
-               sb->s_op->write_super (sb);
+               sb->s_op->write_super(sb);
        put_super(dev);
        return 0;
 }
 
-int sys_umount(char * dev_name)
+/*
+ * Now umount can handle mount points as well as block devices.
+ * This is important for filesystems which use unnamed block devices.
+ *
+ * There is a little kludge here with the dummy_inode.  The current
+ * vfs release functions only use the r_dev field in the inode so
+ * we give them the info they need without using a real inode.
+ * If any other fields are ever needed by any block device release
+ * functions, they should be faked here.  -- jrs
+ */
+
+int sys_umount(char * name)
 {
        struct inode * inode;
-       int dev,retval;
+       dev_t dev;
+       int retval;
+       struct inode dummy_inode;
+       struct file_operations * fops;
 
        if (!suser())
                return -EPERM;
-       retval = namei(dev_name,&inode);
+       retval = namei(name,&inode);
        if (retval)
                return retval;
-       dev = inode->i_rdev;
-       if (!S_ISBLK(inode->i_mode)) {
+       if (S_ISBLK(inode->i_mode)) {
+               dev = inode->i_rdev;
+               if (IS_NODEV(inode)) {
+                       iput(inode);
+                       return -EACCES;
+               }
+       } else if (S_ISDIR(inode->i_mode)) {
+               if (!inode || !inode->i_sb || inode != inode->i_sb->s_mounted) {
+                       iput(inode);
+                       return -EINVAL;
+               }
+               dev = inode->i_sb->s_dev;
                iput(inode);
-               return -ENOTBLK;
-       }
-       if (IS_NODEV(inode)) {
+               memset(&dummy_inode, 0, sizeof(dummy_inode));
+               dummy_inode.i_rdev = dev;
+               inode = &dummy_inode;
+       } else {
                iput(inode);
-               return -EACCES;
+               return -EINVAL;
        }
        if (MAJOR(dev) >= MAX_BLKDEV) {
                iput(inode);
-               return -ENODEV;
+               return -ENXIO;
        }
-       retval = do_umount(dev);
-       if (!retval && blkdev_fops[MAJOR(dev)] && blkdev_fops[MAJOR(dev)]->release)
-               blkdev_fops[MAJOR(dev)]->release(inode,NULL);
-       iput(inode);
+       if (!(retval = do_umount(dev))) {
+               fops = blkdev_fops[MAJOR(dev)];
+               if (fops && fops->release)
+                       fops->release(inode,NULL);
+               if (MAJOR(dev) == UNNAMED_MAJOR)
+                       put_unnamed_dev(dev);
+       }
+       if (inode != &dummy_inode)
+               iput(inode);
        if (retval)
                return retval;
        sync_dev(dev);
@@ -265,33 +323,51 @@ static int do_mount(dev_t dev, const char * dir, char * type, int flags, void *
  * are talking to an older version that didn't understand them.
  */
 int sys_mount(char * dev_name, char * dir_name, char * type,
-       unsigned long new_flags, void *data)
+       unsigned long new_flags, void * data)
 {
+       struct file_system_type * fstype;
        struct inode * inode;
        struct file_operations * fops;
-       int dev;
+       dev_t dev;
        int retval;
-       char tmp[100],*t;
+       char tmp[100], * t;
        int i;
        unsigned long flags = 0;
        unsigned long page = 0;
 
        if (!suser())
                return -EPERM;
-       if (retval = namei(dev_name,&inode))
-               return retval;
-       dev = inode->i_rdev;
-       if (!S_ISBLK(inode->i_mode)) {
-               iput(inode);
-               return -ENOTBLK;
-       }
-       if (IS_NODEV(inode)) {
-               iput(inode);
-               return -EACCES;
-       }
-       if (MAJOR(dev) >= MAX_BLKDEV) {
-               iput(inode);
+       if (type) {
+               for (i = 0 ; i < 100 ; i++)
+                       if (!(tmp[i] = get_fs_byte(type++)))
+                               break;
+               t = tmp;
+       } else
+               t = NULL;
+       if (!(fstype = get_fs_type(t)))
                return -ENODEV;
+       t = fstype->name;
+       if (fstype->requires_dev) {
+               if (retval = namei(dev_name,&inode))
+                       return retval;
+               if (!S_ISBLK(inode->i_mode)) {
+                       iput(inode);
+                       return -ENOTBLK;
+               }
+               if (IS_NODEV(inode)) {
+                       iput(inode);
+                       return -EACCES;
+               }
+               dev = inode->i_rdev;
+               if (MAJOR(dev) >= MAX_BLKDEV) {
+                       iput(inode);
+                       return -ENXIO;
+               }
+       }
+       else {
+               if (!(dev = get_unnamed_dev()))
+                       return -EMFILE;
+               inode = NULL;
        }
        fops = blkdev_fops[MAJOR(dev)];
        if (fops && fops->open) {
@@ -302,22 +378,18 @@ int sys_mount(char * dev_name, char * dir_name, char * type,
        }
        if ((new_flags & 0xffff0000) == 0xC0ED0000) {
                flags = new_flags & 0xffff;
-               if (data && (unsigned long) data < TASK_SIZE)
+               if (data) {
+                       if ((unsigned long) data >= TASK_SIZE) {
+                               iput(inode);
+                               return -EFAULT;
+                       }
                        page = get_free_page(GFP_KERNEL);
+                       i = TASK_SIZE - (unsigned long) data;
+                       if (i < 0 || i > 4095)
+                               i = 4095;
+                       memcpy_fromfs((void *) page,data,i);
+               }
        }
-       if (page) {
-               i = TASK_SIZE - (unsigned long) data;
-               if (i < 0 || i > 4095)
-                       i = 4095;
-               memcpy_fromfs((void *) page,data,i);
-       }
-       if (type) {
-               for (i = 0 ; i < 100 ; i++)
-                       if (!(tmp[i] = get_fs_byte(type++)))
-                               break;
-               t = tmp;
-       } else
-               t = "minix";
        retval = do_mount(dev,dir_name,t,flags,(void *) page);
        free_page(page);
        if (retval && fops && fops->release)
@@ -328,39 +400,30 @@ int sys_mount(char * dev_name, char * dir_name, char * type,
 
 void mount_root(void)
 {
-       int i;
-       struct file_system_type * fs_type = file_systems;
-       struct super_block * p;
-       struct inode * mi;
-
-       if (32 != sizeof (struct minix_inode))
-               panic("bad i-node size");
-       for(i=0;i<NR_FILE;i++)
-               file_table[i].f_count=0;
+       struct file_system_type * fs_type;
+       struct super_block * sb;
+       struct inode * inode;
+
+       memset(file_table, 0, sizeof(file_table));
+       memset(super_block, 0, sizeof(super_block));
        fcntl_init_locks();
        if (MAJOR(ROOT_DEV) == 2) {
                printk("Insert root floppy and press ENTER");
                wait_for_keypress();
        }
-       for(p = &super_block[0] ; p < &super_block[NR_SUPER] ; p++) {
-               p->s_dev = 0;
-               p->s_blocksize = 0;
-               p->s_lock = 0;
-               p->s_wait = NULL;
-               p->s_mounted = p->s_covered = NULL;
-       }
-       while (fs_type->read_super && fs_type->name) {
-               p = read_super(ROOT_DEV,fs_type->name,0,NULL);
-               if (p) {
-                       mi = p->s_mounted;
-                       mi->i_count += 3 ;      /* NOTE! it is logically used 4 times, not 1 */
-                       p->s_covered = mi;
-                       p->s_flags = 0;
-                       current->pwd = mi;
-                       current->root = mi;
+       for (fs_type = file_systems; fs_type->read_super; fs_type++) {
+               if (!fs_type->requires_dev)
+                       continue;
+               sb = read_super(ROOT_DEV,fs_type->name,0,NULL);
+               if (sb) {
+                       inode = sb->s_mounted;
+                       inode->i_count += 3 ;   /* NOTE! it is logically used 4 times, not 1 */
+                       sb->s_covered = inode;
+                       sb->s_flags = 0;
+                       current->pwd = inode;
+                       current->root = inode;
                        return;
                }
-               fs_type++;
        }
        panic("Unable to mount root");
 }
index 9ba767f24451071e4fed1e37aa5e75b8c0bbf1b6..e04f196ad7d75130810410b177083a9af200eb27 100644 (file)
@@ -1,21 +1,20 @@
 /* $Header: /sys/linux-0.97/include/asm/RCS/dma.h,v 1.4 1992/09/21 03:15:46 root Exp root $
  * linux/include/asm/dma.h: Defines for using and allocating dma channels.
  * Written by Hennus Bergman, 1992.
+ *
+ * High DMA channel support by Hannu Savolainen
  */
 
 #ifndef _ASM_DMA_H
 #define _ASM_DMA_H
 
 #include <asm/io.h>            /* need byte IO */
-#include <linux/kernel.h>      /* need panic() [FIXME] */
 
 
 #ifdef HAVE_REALLY_SLOW_DMA_CONTROLLER
 #define outb   outb_p
 #endif
 
-/* FIXME: better fix this code for dma channels>3!!!!!!! */
-
 /*
  * The routines below should in most cases (with optimizing on) result
  * in equal or better code than similar code using macros.
  * that cross a 64k boundary. When the address reaches 0xNffff, it will wrap
  * around to 0xN0000, rather than increment to 0x(N+1)0000 !
  * Make sure you align your buffers properly! Runtime check recommended.
+
+ ****** Correction!!!!!
+ *     Channels 4-7 16 bit channels and capable to cross 64k boundaries
+ *     but not 128k boundaries. Transfer count must be given as words.
+ *     Maximum transfer size is 65k words = 128kb.
  *
  * NOTE2: DMA1..3 can only use the lower 1MB of physical memory. DMA4..7
  * can access the lower 16MB. There are people with >16MB, so beware!
+ * **** Not correct!!! All channels are able to access the first 16MB *******
  */
 
 
@@ -38,6 +44,7 @@
  * The first DMA controller uses bytes, the second words.
  *
  * Where are the page regs for the second DMA controller?????
+ * (ch 5=0x8b, 6=0x89, 7=0x8a)
  */
 
 
 #define DMA1_MODE_REG          0x0B    /* set modes for individual channels */
 #define DMA1_CLEAR_FF_REG      0x0C    /* Write 0 for LSB, 1 for MSB */
 #define DMA1_RESET_REG         0x0D    /* Write here to reset DMA controller */
-/* don't have much info on the second DMA controller... */
+
+#define DMA2_CMD_REG           0xD0    /* DMA command register */
+#define DMA2_STAT_REG          0xD0    /* DMA status register */
 #define DMA2_MASK_REG          0xD4
 #define DMA2_MODE_REG          0xD6
-/* #define DMA2_CLEAR_FF_REG 0xD8 -- pure guessing.... */
-
-/************* #error This needs more work!!!!!!!*************/
+#define DMA2_CLEAR_FF_REG      0xD8
+#define DMA2_RESET_REG         0xDA    /* Write here to reset DMA controller */
 
 #define DMA_MODE_READ  0x44    /* I/O to memory, no autoinit, increment, single mode */
 #define DMA_MODE_WRITE 0x48    /* memory to I/O, no autoinit, increment, single mode */
-#define DMA_MODE_CASCADE       0xC0    /* cascade mode (for DMA2 controller only) */
+/* cascade mode (for DMA2 controller only) */
+#define DMA_MODE_CASCADE       0x40    /* 0xC0 */
 
 
 /* enable/disable a specific DMA channel */
@@ -93,11 +102,7 @@ static __inline__ void clear_dma_ff(unsigned int dmanr)
        if (dmanr<=3)
                outb(0,  DMA1_CLEAR_FF_REG);
        else
-#ifdef DMA2_CLEAR_FF_REG
                outb(0,  DMA2_CLEAR_FF_REG);
-#else
-               panic("dma.h: Don't have CLEAR_FF for high dma channels!\n");
-#endif
 }
 
 /* set mode (above) for a specific DMA channel */
@@ -130,10 +135,16 @@ static __inline__ void set_dma_page(unsigned int dmanr, char pagenr)
                        outb(pagenr, 0x82);
                        break;
                case 4:
+                       outb(pagenr, 0x8f);
+                       break;
                case 5:
+                       outb(pagenr, 0x8b);
+                       break;
                case 6:
+                       outb(pagenr, 0x89);
+                       break;
                case 7:
-                       panic("dma.h: don't know how to set DMA page regs for channels>3");
+                       outb(pagenr, 0x8a);
                        break;
        }
 }
@@ -141,12 +152,20 @@ static __inline__ void set_dma_page(unsigned int dmanr, char pagenr)
 
 /* Set transfer address & page bits for specific DMA channel.
  * Assumes dma flipflop is clear.
+ *
+ * NOTE! A word address is assumed for the channels 4 to 7.
  */
 static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
 {
        unsigned int io_base = (dmanr<=3)? IO_DMA1_BASE : IO_DMA2_BASE;
+       unsigned int page = a>>16;
+
+       if (dmanr>3) page &= 0xfe;      /* The last bit is never used */
+
+       set_dma_page(dmanr, page);
+
+       if (dmanr>3) a >>= 1;
 
-       set_dma_page(dmanr, a>>16);
        outb(a & 0xff, ((dmanr&3)<<1) + io_base);
        outb((a>>8) & 0xff, ((dmanr&3)<<1) + io_base);
 }
@@ -160,9 +179,12 @@ static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
  */
 static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
 {
-       unsigned int dc = count - 1;
+       unsigned int dc;
        unsigned int io_base = (dmanr<=3)? IO_DMA1_BASE : IO_DMA2_BASE;
 
+        if (dmanr>3) count >>=1;
+       dc = count - 1;
+
        outb(dc & 0xff, ((dmanr&3)<<1) + 1 + io_base);
        outb((dc>>8) & 0xff, ((dmanr&3)<<1) + 1 + io_base);
 }
diff --git a/include/asm/memory.h b/include/asm/memory.h
deleted file mode 100644 (file)
index efef4f1..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- *  NOTE!!! memcpy(dest,src,n) assumes ds=es=normal data segment. This
- *  goes for all kernel functions (ds=es=kernel space, fs=local data,
- *  gs=null), as well as for all well-behaving user programs (ds=es=
- *  user data space). This is NOT a bug, as any user program that changes
- *  es deserves to die if it isn't careful.
- */
-#if 0
-#define memcpy(dest,src,n) ({ \
-void * _res = dest; \
-__asm__ __volatile__ ("cld;rep;movsb" \
-       ::"D" ((long)(_res)),"S" ((long)(src)),"c" ((long) (n)) \
-       :"di","si","cx"); \
-_res; \
-})
-#else
-
-/* this is basically memcpy_tofs.  It should be faster.
-   I've reorder it.  This should be a little faster. -RAB */
-
-#define memcpy(dest, src, n) f_memcpy(dest, src, n)
-extern inline void * f_memcpy(void * to, void * from, unsigned long n)
-{
-__asm__("cld\n\t"
-       "movl %%edx, %%ecx\n\t"
-       "shrl $2,%%ecx\n\t"
-       "rep ; movsl\n\t"
-       "testb $1,%%dl\n\t"
-       "je 1f\n\t"
-       "movsb\n"
-       "1:\ttestb $2,%%dl\n\t"
-       "je 2f\n\t"
-       "movsw\n"
-       "2:\n"
-       ::"d" (n),"D" ((long) to),"S" ((long) from)
-       : "cx","di","si");
-return (to);
-}
-#endif
index 4fe72bc8cbd16fb31b976064539d7bd15dbfdfec..c08f507faa9f70f013127f7354f23a97c1cf168d 100644 (file)
@@ -99,6 +99,16 @@ defined(CONFIG_CHR_DEV_ST)
 #endif
 #endif
 
+/*
+ *  Choose filesystems here.
+ */
+
+#define MINIX_FS
+#define EXT_FS
+#define MSDOS_FS
+#define PROC_FS
+#undef  NFS_FS
+
 #ifdef CONFIG_DISTRIBUTION
 #include <linux/config.dist.h>
 #else
index 87b76d704992aab18b39b01217b5661336c58326..cf725b907300347784b9e4aedaa84b117d973cb0 100644 (file)
@@ -15,7 +15,7 @@
 /* devices are as follows: (same as minix, so we can use the minix
  * file system. These are major numbers.)
  *
- *  0 - unused (nodev)
+ *  0 - unnamed (minor 0 = true nodev)
  *  1 - /dev/mem
  *  2 - /dev/fd
  *  3 - /dev/hd
  *  9 - /dev/st
  * 10 - mice
  * 11 - scsi cdrom
+ * 12 -
+ * 13 -
+ * 14 - sound card (?)
+ * 15 -
  */
 
+#define UNNAMED_MAJOR 0
+
 #define MAY_EXEC 1
 #define MAY_WRITE 2
 #define MAY_READ 4
@@ -129,6 +135,9 @@ struct inode {
        struct wait_queue * i_wait;
        struct file_lock * i_flock;
        struct vm_area_struct * i_mmap;
+       struct inode * i_next, * i_prev;
+       struct inode * i_hash_next, * i_hash_prev;
+       struct inode * i_bound_to, * i_bound_by;
        unsigned short i_count;
        unsigned short i_flags;
        unsigned char i_lock;
@@ -194,7 +203,7 @@ struct file_operations {
        int (*lseek) (struct inode *, struct file *, off_t, int);
        int (*read) (struct inode *, struct file *, char *, int);
        int (*write) (struct inode *, struct file *, char *, int);
-       int (*readdir) (struct inode *, struct file *, struct dirent *, int count);
+       int (*readdir) (struct inode *, struct file *, struct dirent *, int);
        int (*select) (struct inode *, struct file *, int, select_table *);
        int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned int);
        int (*mmap) (void);
@@ -214,23 +223,25 @@ struct inode_operations {
        int (*mknod) (struct inode *,const char *,int,int,int);
        int (*rename) (struct inode *,const char *,int,struct inode *,const char *,int);
        int (*readlink) (struct inode *,char *,int);
-       int (*follow_link) (struct inode *, struct inode *, int flag, int mode, struct inode ** res_inode);
+       int (*follow_link) (struct inode *,struct inode *,int,int,struct inode **);
        int (*bmap) (struct inode *,int);
        void (*truncate) (struct inode *);
 };
 
 struct super_operations {
-       void (*read_inode)(struct inode *inode);
-       void (*write_inode) (struct inode *inode);
-       void (*put_inode) (struct inode *inode);
-       void (*put_super)(struct super_block *sb);
-       void (*write_super) (struct super_block *sb);
-       void (*statfs) (struct super_block *sb, struct statfs *buf);
+       void (*read_inode) (struct inode *);
+       int (*notify_change) (struct inode *);
+       void (*write_inode) (struct inode *);
+       void (*put_inode) (struct inode *);
+       void (*put_super) (struct super_block *);
+       void (*write_super) (struct super_block *);
+       void (*statfs) (struct super_block *, struct statfs *);
 };
 
 struct file_system_type {
-       struct super_block *(*read_super)(struct super_block *sb,void *mode);
+       struct super_block *(*read_super) (struct super_block *, void *);
        char *name;
+       int requires_dev;
 };
 
 extern struct file_operations * chrdev_fops[MAX_CHRDEV];
@@ -261,6 +272,7 @@ extern void sync_inodes(dev_t dev);
 extern void sync_dev(dev_t dev);
 extern void sync_supers(dev_t dev);
 extern int bmap(struct inode * inode,int block);
+extern int notify_change(struct inode * inode);
 extern int namei(const char * pathname, struct inode ** res_inode);
 extern int lnamei(const char * pathname, struct inode ** res_inode);
 extern int permission(struct inode * inode,int mask);
@@ -270,11 +282,12 @@ extern int do_mknod(const char * filename, int mode, dev_t dev);
 extern void iput(struct inode * inode);
 extern struct inode * iget(struct super_block * sb,int nr);
 extern struct inode * get_empty_inode(void);
+extern void clear_inode(struct inode *);
 extern struct inode * get_pipe_inode(void);
 extern struct file * get_empty_filp(void);
 extern struct buffer_head * get_hash_table(dev_t dev, int block, int size);
 extern struct buffer_head * getblk(dev_t dev, int block, int size);
-extern void ll_rw_block(int rw, struct buffer_head * bh);
+extern void ll_rw_block(int rw, int nr, struct buffer_head * bh[]);
 extern void ll_rw_page(int rw, int dev, int nr, char * buffer);
 extern void ll_rw_swap_file(int rw, int dev, unsigned int *b, int nb, char *buffer);
 extern void brelse(struct buffer_head * buf);
index 28e30541895dc103fe53702920e356773b68b529..46b42451b6e5ed05c7550f250f64df938f64c035 100644 (file)
 #define        BBD_ERR         0x80    /* ? */
 
 
+/* HDIO_GETGEO is the preferred choice - HDIO_REQ will be removed at some
+   later date */
 #define HDIO_REQ 0x301
+#define HDIO_GETGEO 0x301
 struct hd_geometry {
       unsigned char heads;
       unsigned char sectors;
index a4ac54fe15b30d60a04bd94874b67145802c0ada..e80507fe412454fdc6b56a4759d2c8f464d8b01d 100644 (file)
@@ -10,10 +10,11 @@ volatile void panic(const char * str);
 volatile void do_exit(long error_code);
 unsigned long simple_strtoul(const char *,char **,unsigned int);
 int printk(const char * fmt, ...);
-void * malloc(unsigned int size);
-void free_s(void * obj, int size);
 
-#define free(x) free_s((x), 0)
+void * kmalloc(unsigned int size, int priority);
+void kfree_s(void * obj, int size);
+
+#define kfree(x) kfree_s((x), 0)
 
 /*
  * This is defined as a macro, but at some point this might become a
index f3912fa3d32a8d2c5198374806402b9748dcd1d2..adfdf8fa29b890d44119822b2606c51683ca329e 100644 (file)
@@ -3,21 +3,29 @@
 
 #define NAME_MAX 255
 
-#define NR_OPEN 32
+/*
+ * It's silly to have NR_OPEN bigger than NR_FILE, but I'll fix
+ * that later. Anyway, now the file code is no longer dependent
+ * on bitmaps in unsigned longs, but uses the new fd_set structure..
+ *
+ * Some programs (notably those using select()) may have to be 
+ * recompiled to take full advantage of the new limits..
+ */
+#define NR_OPEN 256
 #define NR_INODE 128
 #define NR_FILE 128
-#define NR_SUPER 8
+#define NR_SUPER 16
 #define NR_HASH 997
 #define NR_FILE_LOCKS 32
 #define BLOCK_SIZE 1024
 #define BLOCK_SIZE_BITS 10
-#define MAX_CHRDEV 16
-#define MAX_BLKDEV 16
+#define MAX_CHRDEV 32
+#define MAX_BLKDEV 32
 
 #define NGROUPS_MAX       32   /* supplemental group IDs are available */
 #define ARG_MAX       131072   /* # bytes of args + environ for exec() */
 #define CHILD_MAX        999    /* no limit :-) */
-#define OPEN_MAX          32   /* # open files a process may have */
+#define OPEN_MAX         256   /* # open files a process may have */
 #define LINK_MAX         127   /* # links a file may have */
 #define MAX_CANON        255   /* size of the canonical input queue */
 #define MAX_INPUT        255   /* size of the type-ahead buffer */
index 827e9c9953a2ec707ffa3095273aabd385a6cc5c..ec8d6ba0e4594d5ec29e35e7b323cd1b404a328c 100644 (file)
@@ -1,7 +1,13 @@
 #ifndef _LINUX_MATH_EMU_H
 #define _LINUX_MATH_EMU_H
 
-#include <linux/sched.h>
+struct fpu_reg {
+       char sign;
+       char tag;
+       long exp;
+       unsigned sigl;
+       unsigned sigh;
+};
 
 struct info {
        long ___orig_eip;
@@ -25,6 +31,7 @@ struct info {
        long ___ss;
 };
 
+#if 0
 #define EAX (info->___eax)
 #define EBX (info->___ebx)
 #define ECX (info->___ecx)
@@ -41,145 +48,11 @@ struct info {
 #define FS (*(unsigned short *) &(info->___fs))
 #define CS (*(unsigned short *) &(info->___cs))
 #define SS (*(unsigned short *) &(info->___ss))
+#endif
 
 void __math_abort(struct info *, unsigned int);
 
 #define math_abort(x,y) \
 (((volatile void (*)(struct info *,unsigned int)) __math_abort)((x),(y)))
 
-/*
- * Gcc forces this stupid alignment problem: I want to use only two longs
- * for the temporary real 64-bit mantissa, but then gcc aligns out the
- * structure to 12 bytes which breaks things in math_emulate.c. Shit. I
- * want some kind of "no-alignt" pragma or something.
- */
-
-typedef struct {
-       long a,b;
-       short exponent;
-} temp_real;
-
-typedef struct {
-       short m0,m1,m2,m3;
-       short exponent;
-} temp_real_unaligned;
-
-#define real_to_real(a,b) \
-((*(long long *) (b) = *(long long *) (a)),((b)->exponent = (a)->exponent))
-
-typedef struct {
-       long a,b;
-} long_real;
-
-typedef long short_real;
-
-typedef struct {
-       long a,b;
-       short sign;
-} temp_int;
-
-struct swd {
-       int ie:1;
-       int de:1;
-       int ze:1;
-       int oe:1;
-       int ue:1;
-       int pe:1;
-       int sf:1;
-       int ir:1;
-       int c0:1;
-       int c1:1;
-       int c2:1;
-       int top:3;
-       int c3:1;
-       int b:1;
-};
-
-#define I387 (current->tss.i387)
-#define SWD (*(struct swd *) &I387.swd)
-#define ROUNDING ((I387.cwd >> 10) & 3)
-#define PRECISION ((I387.cwd >> 8) & 3)
-
-#define BITS24 0
-#define BITS53 2
-#define BITS64 3
-
-#define ROUND_NEAREST  0
-#define ROUND_DOWN     1
-#define ROUND_UP       2
-#define ROUND_0                3
-
-#define CONSTZ   (temp_real_unaligned) {0x0000,0x0000,0x0000,0x0000,0x0000}
-#define CONST1   (temp_real_unaligned) {0x0000,0x0000,0x0000,0x8000,0x3FFF}
-#define CONSTPI  (temp_real_unaligned) {0xC235,0x2168,0xDAA2,0xC90F,0x4000}
-#define CONSTLN2 (temp_real_unaligned) {0x79AC,0xD1CF,0x17F7,0xB172,0x3FFE}
-#define CONSTLG2 (temp_real_unaligned) {0xF799,0xFBCF,0x9A84,0x9A20,0x3FFD}
-#define CONSTL2E (temp_real_unaligned) {0xF0BC,0x5C17,0x3B29,0xB8AA,0x3FFF}
-#define CONSTL2T (temp_real_unaligned) {0x8AFE,0xCD1B,0x784B,0xD49A,0x4000}
-
-#define set_IE() (I387.swd |= 1)
-#define set_DE() (I387.swd |= 2)
-#define set_ZE() (I387.swd |= 4)
-#define set_OE() (I387.swd |= 8)
-#define set_UE() (I387.swd |= 16)
-#define set_PE() (I387.swd |= 32)
-
-#define set_C0() (I387.swd |= 0x0100)
-#define set_C1() (I387.swd |= 0x0200)
-#define set_C2() (I387.swd |= 0x0400)
-#define set_C3() (I387.swd |= 0x4000)
-
-/* ea.c */
-
-char * ea(struct info * __info, unsigned short __code);
-
-/* convert.c */
-
-void frndint(const temp_real * __a, temp_real * __b);
-void short_to_temp(const short_real * __a, temp_real * __b);
-void long_to_temp(const long_real * __a, temp_real * __b);
-void temp_to_short(const temp_real * __a, short_real * __b);
-void temp_to_long(const temp_real * __a, long_real * __b);
-void real_to_int(const temp_real * __a, temp_int * __b);
-void int_to_real(const temp_int * __a, temp_real * __b);
-
-/* get_put.c */
-
-void get_short_real(temp_real *, struct info *, unsigned short);
-void get_long_real(temp_real *, struct info *, unsigned short);
-void get_temp_real(temp_real *, struct info *, unsigned short);
-void get_short_int(temp_real *, struct info *, unsigned short);
-void get_long_int(temp_real *, struct info *, unsigned short);
-void get_longlong_int(temp_real *, struct info *, unsigned short);
-void get_BCD(temp_real *, struct info *, unsigned short);
-void put_short_real(const temp_real *, struct info *, unsigned short);
-void put_long_real(const temp_real *, struct info *, unsigned short);
-void put_temp_real(const temp_real *, struct info *, unsigned short);
-void put_short_int(const temp_real *, struct info *, unsigned short);
-void put_long_int(const temp_real *, struct info *, unsigned short);
-void put_longlong_int(const temp_real *, struct info *, unsigned short);
-void put_BCD(const temp_real *, struct info *, unsigned short);
-
-/* add.c */
-
-void fadd(const temp_real *, const temp_real *, temp_real *);
-
-/* mul.c */
-
-void fmul(const temp_real *, const temp_real *, temp_real *);
-
-/* div.c */
-
-void fdiv(const temp_real *, const temp_real *, temp_real *);
-
-/* sqrt.c */
-
-void fsqrt(const temp_real *, temp_real *);
-
-/* compare.c */
-
-void fcom(const temp_real *, const temp_real *);
-void fucom(const temp_real *, const temp_real *);
-void ftst(const temp_real *);
-
 #endif
index 4779b257c49a11e15bcb8e1be08cacf7fff5fda6..e250898eceb9c98acb173f2aa45eb5a287732c3b 100644 (file)
@@ -47,41 +47,11 @@ struct vm_operations_struct {
        int (*share)(struct vm_area_struct * old, struct vm_area_struct * new, unsigned long address);
 };
 
-/*
- * BAD_PAGE is the page that is used for page faults when linux
- * is out-of-memory. Older versions of linux just did a
- * do_exit(), but using this instead means there is less risk
- * for a process dying in kernel mode, possibly leaving a inode
- * unused etc..
- *
- * BAD_PAGETABLE is the accompanying page-table: it is initialized
- * to point to BAD_PAGE entries.
- */
-extern unsigned long inline __bad_page(void)
-{
-       extern char empty_bad_page[PAGE_SIZE];
-
-       __asm__ __volatile__("cld ; rep ; stosl"
-               ::"a" (0),
-                 "D" ((long) empty_bad_page),
-                 "c" (1024)
-               :"di","cx");
-       return (unsigned long) empty_bad_page;
-}
-#define BAD_PAGE __bad_page()
+extern unsigned long __bad_page(void);
+extern unsigned long __bad_pagetable(void);
 
-extern unsigned long inline __bad_pagetable(void)
-{
-       extern char empty_bad_page_table[PAGE_SIZE];
-
-       __asm__ __volatile__("cld ; rep ; stosl"
-               ::"a" (7+BAD_PAGE),
-                 "D" ((long) empty_bad_page_table),
-                 "c" (1024)
-               :"di","cx");
-       return (unsigned long) empty_bad_page_table;
-}
 #define BAD_PAGETABLE __bad_pagetable()
+#define BAD_PAGE __bad_page()
 
 extern volatile short free_page_ptr; /* used by malloc and tcp/ip. */
 
index ad26e03428f04866e345a226774a8db5c10c6f42..dc4fb38066c7a7f3f0b52241acacb929854a128b 100644 (file)
@@ -19,6 +19,8 @@
 #define PTRACE_ATTACH          0x10
 #define PTRACE_DETACH          0x11
 
+#define PTRACE_SYSCALL           24
+
 /* use ptrace (3 or 6, pid, PT_EXCL, data); to read or write
    the processes registers. */
 
index 5058896e71e52d7464090beae05c01527d04f0b1..87e5c5b244e7b159fe60d612d84ea9066f80c314 100644 (file)
@@ -1,6 +1,15 @@
 #ifndef _LINUX_SCHED_H
 #define _LINUX_SCHED_H
 
+/*
+ * define DEBUG if you want the wait-queues to have some extra
+ * debugging code. It's not normally used, but might catch some
+ * wait-queue coding errors.
+ *
+ *  #define DEBUG
+ */
+
+
 #define HZ 100
 
 /*
 #include <linux/param.h>
 #include <linux/resource.h>
 #include <linux/vm86.h>
-
-#if (NR_OPEN > 32)
-#error "Currently the close-on-exec-flags and select masks are in one long, max 32 files/proc"
-#endif
+#include <linux/math_emu.h>
 
 #define TASK_RUNNING           0
 #define TASK_INTERRUPTIBLE     1
@@ -100,7 +106,10 @@ union i387_union {
                long    foo;
                long    fos;
                long    top;
-               long    regs_space[32]; /* 8*16 bytes for each FP-reg = 112 bytes */
+               struct fpu_reg  regs[8];        /* 8*16 bytes for each FP-reg = 112 bytes */
+               unsigned char   lookahead;
+               struct info     *info;
+               unsigned long   entry_eip;
        } soft;
 };
 
@@ -141,6 +150,8 @@ struct task_struct {
        struct sigaction sigaction[32];
        long blocked;   /* bitmap of masked signals */
        unsigned long saved_kernel_stack;
+       unsigned long kernel_stack_page;
+       unsigned int flags;     /* per process flags, defined below */
 /* various fields */
        int exit_code;
        int dumpable:1;
@@ -158,7 +169,6 @@ struct task_struct {
         * For ease of programming... Normal sleeps don't need to
         * keep track of a wait-queue: every task has an entry of it's own
         */
-       struct wait_queue wait;
        unsigned short uid,euid,suid;
        unsigned short gid,egid,sgid;
        unsigned long timeout;
@@ -168,7 +178,6 @@ struct task_struct {
        unsigned long min_flt, maj_flt;
        unsigned long cmin_flt, cmaj_flt;
        struct rlimit rlim[RLIM_NLIMITS]; 
-       unsigned int flags;     /* per process flags, defined below */
        unsigned short used_math;
        unsigned short rss;     /* number of resident pages */
        char comm[8];
@@ -190,9 +199,9 @@ struct task_struct {
        } libraries[MAX_SHARED_LIBS];
        int numlibraries;
        struct file * filp[NR_OPEN];
-       unsigned long close_on_exec;
-/* ldt for this task 0 - zero 1 - cs 2 - ds&ss */
-       struct desc_struct ldt[3];
+       fd_set close_on_exec;
+/* ldt for this task 0 - zero 1 - cs 2 - ds&ss, rest unused */
+       struct desc_struct ldt[32];
 /* tss for this task */
        struct tss_struct tss;
 };
@@ -203,6 +212,7 @@ struct task_struct {
 #define PF_ALIGNWARN   0x00000001      /* Print alignment warning msgs */
                                        /* Not implemented yet, only for 486*/
 #define PF_PTRACED     0x00000010      /* set if ptrace (0) has been called. */
+#define PF_TRACESYS    0x00000020      /* tracing system calls */
 
 /*
  *  INIT_TASK is used to set up the first task table, touch at
@@ -210,32 +220,33 @@ struct task_struct {
  */
 #define INIT_TASK \
 /* state etc */        { 0,15,15, \
-/* signals */  0,{{},},0,0, \
+/* signals */  0,{{},},0,0,0, \
+/* flags */    0, \
 /* ec,brk... */        0,0,0,0,0,0,0,0, \
 /* pid etc.. */        0,0,0,0, \
 /* suppl grps*/ {NOGROUP,}, \
-/* proc links*/ &init_task.task,&init_task.task,NULL,NULL,NULL, \
-/* wait queue*/ {&init_task.task,NULL}, \
+/* proc links*/ &init_task,&init_task,NULL,NULL,NULL, \
 /* uid etc */  0,0,0,0,0,0, \
 /* timeout */  0,0,0,0,0,0,0,0,0,0,0,0, \
 /* min_flt */  0,0,0,0, \
 /* rlimits */   { {0x7fffffff, 0x7fffffff}, {0x7fffffff, 0x7fffffff},  \
                  {0x7fffffff, 0x7fffffff}, {0x7fffffff, 0x7fffffff}, \
                  {0x7fffffff, 0x7fffffff}, {0x7fffffff, 0x7fffffff}}, \
-/* flags */    0, \
 /* math */     0, \
 /* rss */      2, \
 /* comm */     "swapper", \
 /* vm86_info */        NULL, 0, \
 /* fs info */  0,-1,0022,NULL,NULL,NULL,NULL, \
 /* libraries */        { { NULL, 0, 0}, }, 0, \
-/* filp */     {NULL,}, 0, \
+/* filp */     {NULL,}, \
+/* cloe */     {0,}, \
                { \
                        {0,0}, \
 /* ldt */              {0x9f,0xc0c0fa00}, \
-                       {0x9f,0xc0c0f200} \
+                       {0x9f,0xc0c0f200}, \
                }, \
-/*tss*/        {0,PAGE_SIZE+(long)&init_task,0x10,0,0,0,0,(long)&swapper_pg_dir,\
+/*tss*/        {0,sizeof(init_kernel_stack) + (long) &init_kernel_stack, \
+        0x10,0,0,0,0,(long) &swapper_pg_dir,\
         0,0,0,0,0,0,0,0, \
         0,0,0x17,0x17,0x17,0x17,0x17,0x17, \
         _LDT(0),0x80000000,{0xffffffff}, \
@@ -368,26 +379,49 @@ extern inline void remove_wait_queue(struct wait_queue ** p, struct wait_queue *
 {
        unsigned long flags;
        struct wait_queue * tmp;
+#ifdef DEBUG
+       unsigned long ok = 0;
+#endif
 
        __asm__ __volatile__("pushfl ; popl %0 ; cli":"=r" (flags));
-       if ((*p == wait) && ((*p = wait->next) == wait)) {
+       if ((*p == wait) &&
+#ifdef DEBUG
+           (ok = 1) &&
+#endif
+           ((*p = wait->next) == wait)) {
                *p = NULL;
        } else {
                tmp = wait;
-               while (tmp->next != wait)
+               while (tmp->next != wait) {
                        tmp = tmp->next;
+#ifdef DEBUG
+                       if (tmp == *p)
+                               ok = 1;
+#endif
+               }
                tmp->next = wait->next;
        }
        wait->next = NULL;
        __asm__ __volatile__("pushl %0 ; popfl"::"r" (flags));
+#ifdef DEBUG
+       if (!ok) {
+               printk("removed wait_queue not on list.\n");
+               printk("list = %08x, queue = %08x\n",p,wait);
+               __asm__("call 1f\n1:\tpopl %0":"=r" (ok));
+               printk("eip = %08x\n",ok);
+       }
+#endif
 }
 
 extern inline void select_wait(struct wait_queue ** wait_address, select_table * p)
 {
-       struct select_table_entry * entry = p->entry + p->nr;
+       struct select_table_entry * entry;
 
-       if (!wait_address)
+       if (!p || !wait_address)
+               return;
+       if (p->nr >= __MAX_SELECT_TABLE_ENTRIES)
                return;
+       entry = p->entry + p->nr;
        entry->wait_address = wait_address;
        entry->wait.task = current;
        entry->wait.next = NULL;
index f154e5d90053d6f1dcd072f0ccaf8b099c59d0b5..f87412a3a502b6b401d0af3624f56cc3a950306a 100644 (file)
@@ -11,11 +11,11 @@ struct timezone {
        int     tz_dsttime;     /* type of dst correction */
 };
 
-#define FD_SETSIZE             (8*sizeof(fd_set))
-#define FD_SET(fd,fdsetp)      (*(fdsetp) |= (1 << (fd)))
-#define FD_CLR(fd,fdsetp)      (*(fdsetp) &= ~(1 << (fd)))
-#define FD_ISSET(fd,fdsetp)    ((*(fdsetp) >> fd) & 1)
-#define FD_ZERO(fdsetp)                (*(fdsetp) = 0)
+#define FD_SETSIZE             __FD_SETSIZE
+#define FD_SET(fd,fdsetp)      __FD_SET(fd,fdsetp)
+#define FD_CLR(fd,fdsetp)      __FD_CLR(fd,fdsetp)
+#define FD_ISSET(fd,fdsetp)    __FD_ISSET(fd,fdsetp)
+#define FD_ZERO(fdsetp)                __FD_ZERO(fdsetp)
 
 /*
  * Names of the interval timers, and structure
index d131adb42b44116baa8faa33704a95c07da0aeb9..03ee1d3e41d2d7097708c26f2b17133e39ea46f5 100644 (file)
@@ -32,6 +32,7 @@
 #define FLOPPY_TIMER   17
 #define SCSI_TIMER     18
 #define NET_TIMER      19
+#define SOUND_TIMER    20
 
 struct timer_struct {
        unsigned long expires;
index a8c992a1b388b1857609c529a2387d1fdf9abf58..eb17a3616dd8e99138124de21ec51ffc1ea91f28 100644 (file)
@@ -63,7 +63,41 @@ typedef unsigned char cc_t;
 typedef unsigned int speed_t;
 typedef unsigned long tcflag_t;
 
-typedef unsigned long fd_set;
+/*
+ * This allows for 256 file descriptors: if NR_OPEN is ever grown beyond that
+ * you'll have to change this too. But 256 fd's seem to be enough even for such
+ * "real" unices like SunOS, so hopefully this is one limit that doesn't have
+ * to be changed.
+ *
+ * Note that POSIX wants the FD_CLEAR(fd,fdsetp) defines to be in <sys/time.h>
+ * (and thus <linux/time.h>) - but this is a more logical place for them. Solved
+ * by having dummy defines in <sys/time.h>.
+ */
+#define __FDSET_LONGS 8
+typedef struct fd_set {
+       unsigned long fd_mask[__FDSET_LONGS];
+} fd_set;
+
+#define __FD_SETSIZE (__FDSET_LONGS*32)
+
+#define __FD_SET(fd,fdsetp) \
+__asm__ __volatile__("btsl %1,%0":"=m" (*(struct fd_set *)fdsetp):"r" ((int) fd))
+
+#define __FD_CLR(fd,fdsetp) \
+__asm__ __volatile__("btrl %1,%0":"=m" (*(struct fd_set *)fdsetp):"r" ((int) fd))
+
+#define __FD_ISSET(fd,fdsetp) \
+({ char __result; \
+__asm__ __volatile__("btl %1,%2 ; setb %0" \
+       :"=q" (__result) \
+       :"r" ((int) fd),"m" (*(struct fd_set *) fdsetp)); \
+__result; })
+
+#define __FD_ZERO(fdsetp) \
+__asm__ __volatile__("cld ; rep ; stosl" \
+       :"=m" (*(struct fd_set *) fdsetp) \
+       :"a" (0), "c" (__FDSET_LONGS), "D" ((struct fd_set *) fdsetp) \
+       :"cx","di")
 
 struct ustat {
        daddr_t f_tfree;
index 0c13811aa0f41deb12a13efb6f817a4598eed5a5..58dd08834f75022a554f22cfcc1fe0739ccd6207 100644 (file)
@@ -1,8 +1,6 @@
 #ifndef _LINUX_WAIT_H
 #define _LINUX_WAIT_H
 
-#include <linux/limits.h>
-
 #define WNOHANG                1
 #define WUNTRACED      2
 
@@ -16,7 +14,9 @@ typedef struct select_table_struct {
        struct select_table_entry {
                struct wait_queue wait;
                struct wait_queue ** wait_address;
-       } entry[NR_OPEN*3];
+       } * entry;
 } select_table;
 
+#define __MAX_SELECT_TABLE_ENTRIES (4096 / sizeof (struct select_table_entry))
+
 #endif
index d288ef798545c4782cc033809768f8afdb629419..d7db872828131ec38e1e30347f2976222003575f 100644 (file)
@@ -50,32 +50,32 @@ dummy:
 
 ### Dependencies:
 errors.o : errors.c /usr/include/linux/signal.h /usr/include/asm/segment.h fpu_system.h \
-  /usr/include/linux/math_emu.h /usr/include/linux/sched.h /usr/include/linux/head.h \
+  /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
+  /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
+  /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
+  /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
+  /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
+  /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/time.h \
+  /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
+  /usr/include/linux/math_emu.h exception.h fpu_emu.h fpu_proto.h status_w.h control_w.h \
+  reg_constant.h version.h 
+fpu_arith.o : fpu_arith.c fpu_system.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
   /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
   /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
-  /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h exception.h fpu_emu.h fpu_proto.h status_w.h control_w.h \
-  reg_constant.h version.h 
-fpu_arith.o : fpu_arith.c fpu_system.h /usr/include/linux/math_emu.h /usr/include/linux/sched.h \
-  /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
-  /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
-  /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
-  /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h \
-  /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h \
-  /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
-  /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
+  /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
   fpu_emu.h fpu_proto.h 
-fpu_aux.o : fpu_aux.c fpu_system.h /usr/include/linux/math_emu.h /usr/include/linux/sched.h \
-  /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
-  /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
-  /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
-  /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h \
-  /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h \
-  /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
-  /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
+fpu_aux.o : fpu_aux.c fpu_system.h /usr/include/linux/sched.h /usr/include/linux/head.h \
+  /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
+  /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
+  /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
+  /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
+  /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
+  /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
   exception.h fpu_emu.h fpu_proto.h status_w.h 
 fpu_entry.o : fpu_entry.c /usr/include/linux/signal.h /usr/include/linux/sched.h \
   /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
@@ -84,51 +84,36 @@ fpu_entry.o : fpu_entry.c /usr/include/linux/signal.h /usr/include/linux/sched.h
   /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h \
   /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h \
   /usr/include/linux/kernel.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h 
-fpu_etc.o : fpu_etc.c fpu_system.h /usr/include/linux/math_emu.h /usr/include/linux/sched.h \
-  /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
-  /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
-  /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
-  /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h \
-  /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h \
-  /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
-  /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h 
+fpu_etc.o : fpu_etc.c fpu_system.h /usr/include/linux/sched.h /usr/include/linux/head.h \
+  /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
+  /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
+  /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
+  /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
+  /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
+  /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
   exception.h fpu_emu.h fpu_proto.h status_w.h reg_constant.h 
-fpu_trig.o : fpu_trig.c fpu_system.h /usr/include/linux/math_emu.h /usr/include/linux/sched.h \
-  /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
-  /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
-  /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
-  /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h \
-  /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h \
-  /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
-  /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
+fpu_trig.o : fpu_trig.c fpu_system.h /usr/include/linux/sched.h /usr/include/linux/head.h \
+  /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
+  /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
+  /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
+  /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
+  /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
+  /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
   exception.h fpu_emu.h fpu_proto.h status_w.h control_w.h reg_constant.h 
-get_address.o : get_address.c /usr/include/linux/stddef.h /usr/include/linux/math_emu.h \
-  /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
-  /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
-  /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
-  /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
-  /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
-  /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
-  /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/asm/segment.h fpu_system.h exception.h \
-  fpu_emu.h fpu_proto.h 
-load_store.o : load_store.c /usr/include/asm/segment.h fpu_system.h /usr/include/linux/math_emu.h \
-  /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
+get_address.o : get_address.c /usr/include/linux/stddef.h /usr/include/asm/segment.h \
+  fpu_system.h /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
   /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
   /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
   /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h exception.h fpu_emu.h fpu_proto.h status_w.h 
-poly_2xm1.o : poly_2xm1.c exception.h fpu_emu.h fpu_proto.h reg_constant.h 
-poly_atan.o : poly_atan.c exception.h fpu_emu.h fpu_proto.h reg_constant.h 
-poly_l2.o : poly_l2.c exception.h fpu_emu.h fpu_proto.h reg_constant.h 
-poly_sin.o : poly_sin.c exception.h fpu_emu.h fpu_proto.h reg_constant.h 
-poly_tan.o : poly_tan.c exception.h fpu_emu.h fpu_proto.h reg_constant.h 
-reg_add_sub.o : reg_add_sub.c exception.h fpu_emu.h fpu_proto.h reg_constant.h 
-reg_compare.o : reg_compare.c fpu_system.h /usr/include/linux/math_emu.h /usr/include/linux/sched.h \
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h exception.h fpu_emu.h \
+  fpu_proto.h 
+load_store.o : load_store.c /usr/include/asm/segment.h fpu_system.h /usr/include/linux/sched.h \
   /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
   /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
   /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
@@ -136,8 +121,38 @@ reg_compare.o : reg_compare.c fpu_system.h /usr/include/linux/math_emu.h /usr/in
   /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h \
   /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
   /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
+  /usr/include/linux/math_emu.h exception.h fpu_emu.h fpu_proto.h status_w.h 
+poly_2xm1.o : poly_2xm1.c exception.h fpu_emu.h /usr/include/linux/math_emu.h \
+  fpu_proto.h reg_constant.h 
+poly_atan.o : poly_atan.c exception.h fpu_emu.h /usr/include/linux/math_emu.h \
+  fpu_proto.h reg_constant.h 
+poly_l2.o : poly_l2.c exception.h fpu_emu.h /usr/include/linux/math_emu.h fpu_proto.h \
+  reg_constant.h 
+poly_sin.o : poly_sin.c exception.h fpu_emu.h /usr/include/linux/math_emu.h \
+  fpu_proto.h reg_constant.h 
+poly_tan.o : poly_tan.c exception.h fpu_emu.h /usr/include/linux/math_emu.h \
+  fpu_proto.h reg_constant.h 
+reg_add_sub.o : reg_add_sub.c exception.h fpu_emu.h /usr/include/linux/math_emu.h \
+  fpu_proto.h reg_constant.h 
+reg_compare.o : reg_compare.c fpu_system.h /usr/include/linux/sched.h /usr/include/linux/head.h \
+  /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
+  /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
+  /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
+  /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
+  /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
+  /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
   exception.h fpu_emu.h fpu_proto.h status_w.h 
-reg_constant.o : reg_constant.c fpu_system.h /usr/include/linux/math_emu.h /usr/include/linux/sched.h \
+reg_constant.o : reg_constant.c fpu_system.h /usr/include/linux/sched.h /usr/include/linux/head.h \
+  /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
+  /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
+  /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
+  /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
+  /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
+  /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  fpu_emu.h fpu_proto.h status_w.h reg_constant.h 
+reg_ld_str.o : reg_ld_str.c /usr/include/asm/segment.h fpu_system.h /usr/include/linux/sched.h \
   /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
   /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
   /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
@@ -145,17 +160,10 @@ reg_constant.o : reg_constant.c fpu_system.h /usr/include/linux/math_emu.h /usr/
   /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h \
   /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
   /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
-  fpu_emu.h fpu_proto.h status_w.h reg_constant.h 
-reg_ld_str.o : reg_ld_str.c /usr/include/asm/segment.h fpu_system.h /usr/include/linux/math_emu.h \
-  /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
-  /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
-  /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
-  /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
-  /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
-  /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
-  /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h exception.h fpu_emu.h fpu_proto.h reg_constant.h control_w.h 
-reg_mul.o : reg_mul.c exception.h fpu_emu.h fpu_proto.h reg_constant.h 
+  /usr/include/linux/math_emu.h exception.h fpu_emu.h fpu_proto.h reg_constant.h \
+  control_w.h 
+reg_mul.o : reg_mul.c exception.h fpu_emu.h /usr/include/linux/math_emu.h fpu_proto.h \
+  reg_constant.h 
 div_small.o : div_small.S fpu_asm.h fpu_emu.h 
 poly_div.o : poly_div.S fpu_asm.h fpu_emu.h 
 poly_mul64.o : poly_mul64.S fpu_asm.h fpu_emu.h 
index 07a0ccdbcd8f1d13a857742d06dda37d61a863a5..53cbea21778a286f1bad274512a37a5860558ed2 100644 (file)
@@ -28,7 +28,7 @@ wm-FPU-emu is an FPU emulator for Linux. It is derived from wm-emu387
 which is my 80387 emulator for djgpp (gcc under msdos); wm-emu387 was
 in turn based upon emu387 which was written by DJ Delorie for djgpp.
 The interface to the Linux kernel is based upon the original Linux
-math emulator.
+math emulator by Linus Torvalds.
 
 My target FPU for wm-FPU-emu is that described in the Intel486
 Programmer's Reference Manual (1992 edition). Numerous facets of the
@@ -66,13 +66,25 @@ Numeric algorithms:
     "optimal" polynomial approximations. My definition of "optimal" was
     based upon getting good accuracy with reasonable speed.
 
-
---Bill Metzenthen
+The code of the emulator is complicated slightly by the need to
+account for a limited form of re-entrancy. Normally, the emulator will
+emulate each FPU instruction to completion without interruption.
+However, it may happen that when the emulator is accessing the user
+memory space, swapping may be needed. In this case the emulator may be
+temporarily suspended while disk i/o takes place. During this time
+another process may use the emulator, thereby changing some static
+variables (eg FPU_st0_ptr, etc). The code which accesses user memory
+is confined to five files:
+    fpu_entry.c
+    reg_ld_str.c
+    load_store.c
+    get_address.c
+    errors.c
 
 ----------------------- Limitations of wm-FPU-emu -----------------------
 
 There are a number of differences between the current wm-FPU-emu
-(version ALPHA 0.5) and the 80486 FPU (apart from bugs). Some of the
+(version ALPHA 0.7) and the 80486 FPU (apart from bugs). Some of the
 more important differences are listed below:
 
 Internal computations do not use de-normal numbers (but External
@@ -93,10 +105,6 @@ The functions which load/store the FPU state are partially implemented,
 but the implementation should be sufficient for handling FPU errors etc
 in 32 bit protected mode.
 
-
---Bill Metzenthen
-  October 1992
-
 ----------------------- Performance of wm-FPU-emu -----------------------
 
 Speed.
@@ -132,9 +140,9 @@ function      Turbo C        djgpp 1.06        WM-emu387     wm-FPU-emu
  exp()        479.1          6619.2            469.1          850.8
 
 
-The performance under Linux can be improved if look-ahead code is used.
-WM-emu387 uses such code. The following results show the improvement
-which can be obtained under Linux. Also given are the times for the
+The performance under Linux is improved by the use of look-ahead code.
+The following results show the improvement which is obtained under
+Linux due to the look-ahead code. Also given are the times for the
 original Linux emulator with the 4.1 'soft' lib.
 
  [ Linus' note: I changed look-ahead to be the default under linux, as
diff --git a/kernel/FPU-emu/Reg_constant.h b/kernel/FPU-emu/Reg_constant.h
new file mode 100644 (file)
index 0000000..b6ee963
--- /dev/null
@@ -0,0 +1,31 @@
+/*---------------------------------------------------------------------------+
+ |  reg_constant.h                                                           |
+ |                                                                           |
+ | Copyright (C) 1992    W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
+ |                       Australia.  E-mail apm233m@vaxc.cc.monash.edu.au    |
+ |                                                                           |
+ +---------------------------------------------------------------------------*/
+
+#ifndef _REG_CONSTANT_H_
+#define _REG_CONSTANT_H_
+
+#include "fpu_emu.h"
+
+extern FPU_REG CONST_1;
+extern FPU_REG CONST_2;
+extern FPU_REG CONST_HALF;
+extern FPU_REG CONST_L2T;
+extern FPU_REG CONST_L2E;
+extern FPU_REG CONST_PI;
+extern FPU_REG CONST_PI2;
+extern FPU_REG CONST_PI4;
+extern FPU_REG CONST_LG2;
+extern FPU_REG CONST_LN2;
+extern FPU_REG CONST_Z;
+extern FPU_REG CONST_PINF;
+extern FPU_REG CONST_INF;
+extern FPU_REG CONST_MINF;
+extern FPU_REG CONST_QNaN;
+
+#endif _REG_CONSTANT_H_
+
index 078e860a47ed14f026f02e0b2af43f5f02193056..3ab52875310a5d894a9ca3c4e0029c9604395e4a 100644 (file)
@@ -9,6 +9,13 @@
  |                                                                           |
  +---------------------------------------------------------------------------*/
 
+/*---------------------------------------------------------------------------+
+ | Note:                                                                     |
+ |    The file contains code which accesses user memory.                     |
+ |    Emulator static data may change when user memory is accessed, due to   |
+ |    other processes using the emulator while swapping is in progress.      |
+ +---------------------------------------------------------------------------*/
+
 #include <linux/signal.h>
 
 #include <asm/segment.h>
 #include "reg_constant.h"
 #include "version.h"
 
-
-extern unsigned char  FPU_lookahead;
-
 /* */
 #undef PRINT_MESSAGES
 /* */
 
-
 void Un_impl(void)
 {
-  unsigned char byte1 = get_fs_byte((unsigned char *) FPU_ORIG_EIP);
+  unsigned char byte1, FPU_modrm;
+
+  RE_ENTRANT_CHECK_OFF
+  byte1 = get_fs_byte((unsigned char *) FPU_ORIG_EIP);
+  FPU_modrm = get_fs_byte(1 + (unsigned char *) FPU_ORIG_EIP);
 
   printk("Unimplemented FPU Opcode at eip=%p : %02x ",
         FPU_ORIG_EIP, byte1);
@@ -40,6 +47,7 @@ void Un_impl(void)
     printk("%02x (%02x+%d)\n", FPU_modrm, FPU_modrm & 0xf8, FPU_modrm & 7);
   else
     printk("/%d\n", (FPU_modrm >> 3) & 7);
+  RE_ENTRANT_CHECK_ON
 
   EXCEPTION(EX_Invalid);
 
@@ -53,7 +61,11 @@ void emu_printall()
   int i;
   static char *tag_desc[] = { "Valid", "Zero", "ERROR", "ERROR",
                               "DeNorm", "Inf", "NaN", "Empty" };
-  unsigned char byte1 = get_fs_byte((unsigned char *) FPU_ORIG_EIP);
+  unsigned char byte1, FPU_modrm;
+
+  RE_ENTRANT_CHECK_OFF
+  byte1 = get_fs_byte((unsigned char *) FPU_ORIG_EIP);
+  FPU_modrm = get_fs_byte(1 + (unsigned char *) FPU_ORIG_EIP);
 
 #ifdef DEBUGGING
 if ( status_word & SW_B ) printk("SW: backward compatibility (=ES)\n");
@@ -103,7 +115,7 @@ printk(" CW: ic=%d rc=%d%d pc=%d%d iem=%d     ef=%d%d%d%d%d%d\n",
 
   for ( i = 0; i < 8; i++ )
     {
-      struct reg *r = &st(i);
+      FPU_REG *r = &st(i);
       switch (r->tag)
        {
        case TW_Empty:
@@ -140,6 +152,7 @@ printk(" CW: ic=%d rc=%d%d pc=%d%d iem=%d     ef=%d%d%d%d%d%d\n",
         (long)(FPU_loaded_data.sigl & 0xFFFF),
         FPU_loaded_data.exp - EXP_BIAS + 1);
   printk("%s\n", tag_desc[(int) (unsigned) FPU_loaded_data.tag]);
+  RE_ENTRANT_CHECK_ON
 
 }
 
@@ -224,6 +237,7 @@ void exception(int n)
        status_word &= ~SW_C1;
     }
 
+  RE_ENTRANT_CHECK_OFF
   if ( (~control_word & n & CW_EXM) || (n == EX_INTERNAL) )
     {
 #ifdef PRINT_MESSAGES
@@ -257,6 +271,7 @@ void exception(int n)
 
       send_sig(SIGFPE, current, 1);
     }
+  RE_ENTRANT_CHECK_ON
 
 #ifdef __DEBUG__
   math_abort(FPU_info,SIGFPE);
@@ -268,9 +283,9 @@ void exception(int n)
 
 
 /* Real operation attempted on two operands, one a NaN */
-void real_2op_NaN(REG *a, REG *b, REG *dest)
+void real_2op_NaN(FPU_REG *a, FPU_REG *b, FPU_REG *dest)
 {
-  REG *x;
+  FPU_REG *x;
   
   x = a;
   if (a->tag == TW_NaN)
@@ -309,7 +324,7 @@ void real_2op_NaN(REG *a, REG *b, REG *dest)
 }
 
 /* Invalid arith operation on valid registers */
-void arith_invalid(REG *dest)
+void arith_invalid(FPU_REG *dest)
 {
   
   if ( control_word & EX_Invalid )
@@ -326,7 +341,7 @@ void arith_invalid(REG *dest)
 
 
 /* Divide a finite number by zero */
-void divide_by_zero(int sign, REG *dest)
+void divide_by_zero(int sign, FPU_REG *dest)
 {
 
   if ( control_word & EX_ZeroDiv )
@@ -343,7 +358,7 @@ void divide_by_zero(int sign, REG *dest)
 }
 
 
-void arith_overflow(REG *dest)
+void arith_overflow(FPU_REG *dest)
 {
 
   if ( control_word & EX_Overflow )
@@ -367,7 +382,7 @@ void arith_overflow(REG *dest)
 }
 
 
-void arith_underflow(REG *dest)
+void arith_underflow(FPU_REG *dest)
 {
 
   if ( control_word & EX_Underflow )
@@ -395,7 +410,7 @@ void stack_overflow(void)
     {
       /* The masked response */
       top--;
-      reg_move(&CONST_QNaN, st0_ptr = &st(0));
+      reg_move(&CONST_QNaN, FPU_st0_ptr = &st(0));
     }
 
   EXCEPTION(EX_StackOver);
@@ -411,7 +426,7 @@ void stack_underflow(void)
  if ( control_word & EX_Invalid )
     {
       /* The masked response */
-      reg_move(&CONST_QNaN, st0_ptr);
+      reg_move(&CONST_QNaN, FPU_st0_ptr);
     }
 
   EXCEPTION(EX_StackUnder);
index a1c73f731f848c3f6f78e8d05496f84669612c05..fb86989b8c7bf13ed54ec394c8f02268de529aa1 100644 (file)
 void fadd__()
 {
   /* fadd st,st(i) */
-  reg_add(st0_ptr, &st(FPU_rm), st0_ptr);
+  reg_add(FPU_st0_ptr, &st(FPU_rm), FPU_st0_ptr);
 }
 
 
 void fmul__()
 {
   /* fmul st,st(i) */
-  reg_mul(st0_ptr, &st(FPU_rm), st0_ptr);
+  reg_mul(FPU_st0_ptr, &st(FPU_rm), FPU_st0_ptr);
 }
 
 
@@ -31,28 +31,28 @@ void fmul__()
 void fsub__()
 {
   /* fsub st,st(i) */
-  reg_sub(st0_ptr, &st(FPU_rm), st0_ptr);
+  reg_sub(FPU_st0_ptr, &st(FPU_rm), FPU_st0_ptr);
 }
 
 
 void fsubr_()
 {
   /* fsubr st,st(i) */
-  reg_sub(&st(FPU_rm), st0_ptr, st0_ptr);
+  reg_sub(&st(FPU_rm), FPU_st0_ptr, FPU_st0_ptr);
 }
 
 
 void fdiv__()
 {
   /* fdiv st,st(i) */
-  reg_div(st0_ptr, &st(FPU_rm), st0_ptr);
+  reg_div(FPU_st0_ptr, &st(FPU_rm), FPU_st0_ptr);
 }
 
 
 void fdivr_()
 {
   /* fdivr st,st(i) */
-  reg_div(&st(FPU_rm), st0_ptr, st0_ptr);
+  reg_div(&st(FPU_rm), FPU_st0_ptr, FPU_st0_ptr);
 }
 
 
@@ -60,14 +60,14 @@ void fdivr_()
 void fadd_i()
 {
   /* fadd st(i),st */
-  reg_add(st0_ptr, &st(FPU_rm), &st(FPU_rm));
+  reg_add(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm));
 }
 
 
 void fmul_i()
 {
   /* fmul st(i),st */
-  reg_mul(&st(FPU_rm), st0_ptr, &st(FPU_rm));
+  reg_mul(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm));
 }
 
 
@@ -75,8 +75,8 @@ void fsubri()
 {
   /* fsubr st(i),st */
   /* This is the sense of the 80486 manual
-     reg_sub(&st(FPU_rm), st0_ptr, &st(FPU_rm)); */
-  reg_sub(st0_ptr, &st(FPU_rm), &st(FPU_rm));
+     reg_sub(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm)); */
+  reg_sub(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm));
 }
 
 
@@ -84,22 +84,22 @@ void fsub_i()
 {
   /* fsub st(i),st */
   /* This is the sense of the 80486 manual
-     reg_sub(st0_ptr, &st(FPU_rm), &st(FPU_rm)); */
-  reg_sub(&st(FPU_rm), st0_ptr, &st(FPU_rm));
+     reg_sub(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm)); */
+  reg_sub(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm));
 }
 
 
 void fdivri()
 {
   /* fdivr st(i),st */
-  reg_div(st0_ptr, &st(FPU_rm), &st(FPU_rm));
+  reg_div(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm));
 }
 
 
 void fdiv_i()
 {
   /* fdiv st(i),st */
-  reg_div(&st(FPU_rm), st0_ptr, &st(FPU_rm));
+  reg_div(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm));
 }
 
 
@@ -107,7 +107,7 @@ void fdiv_i()
 void faddp_()
 {
   /* faddp st(i),st */
-  reg_add(st0_ptr, &st(FPU_rm), &st(FPU_rm));
+  reg_add(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm));
   pop();
 }
 
@@ -115,7 +115,7 @@ void faddp_()
 void fmulp_()
 {
   /* fmulp st(i),st */
-  reg_mul(&st(FPU_rm), st0_ptr, &st(FPU_rm));
+  reg_mul(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm));
   pop();
 }
 
@@ -125,8 +125,8 @@ void fsubrp()
 {
   /* fsubrp st(i),st */
   /* This is the sense of the 80486 manual
-     reg_sub(&st(FPU_rm), st0_ptr, &st(FPU_rm)); */
-  reg_sub(st0_ptr, &st(FPU_rm), &st(FPU_rm));
+     reg_sub(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm)); */
+  reg_sub(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm));
   pop();
 }
 
@@ -135,8 +135,8 @@ void fsubp_()
 {
   /* fsubp st(i),st */
   /* This is the sense of the 80486 manual
-     reg_sub(st0_ptr, &st(FPU_rm), &st(FPU_rm)); */
-  reg_sub(&st(FPU_rm), st0_ptr, &st(FPU_rm));
+     reg_sub(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm)); */
+  reg_sub(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm));
   pop();
 }
 
@@ -144,7 +144,7 @@ void fsubp_()
 void fdivrp()
 {
   /* fdivrp st(i),st */
-  reg_div(st0_ptr, &st(FPU_rm), &st(FPU_rm));
+  reg_div(FPU_st0_ptr, &st(FPU_rm), &st(FPU_rm));
   pop();
 }
 
@@ -152,7 +152,7 @@ void fdivrp()
 void fdivp_()
 {
   /* fdivp st(i),st */
-  reg_div(&st(FPU_rm), st0_ptr, &st(FPU_rm));
+  reg_div(&st(FPU_rm), FPU_st0_ptr, &st(FPU_rm));
   pop();
 }
 
index 50d51d0c92c370c6d35e7b7be904e5879c57ca9e..83b52e690f82edfb9e4b381c1b7b9db5c604f02c 100644 (file)
 #include "fpu_emu.h"
 #include "status_w.h"
 
-extern struct info *FPU_info;
-
-#define EAX_REG ((long)(FPU_info->___eax))
-
 
 
 static void fclex()
@@ -60,7 +56,7 @@ static void fstsw_ax()
   status_word &= ~SW_TOP;
   status_word |= (top&7) << SW_TOPS;
 
-  *(short *) &EAX_REG = status_word;
+  *(short *) &FPU_EAX = status_word;
 
 }
 
@@ -91,7 +87,7 @@ void fp_nop()
 
 void fld_i_()
 {
-  REG *st_new_ptr;
+  FPU_REG *st_new_ptr;
 
   if ( STACK_OVERFLOW )
     { stack_overflow(); return; }
@@ -117,10 +113,10 @@ void fld_i_()
 void fxch_i()
 {
   /* fxch st(i) */
-  REG t;
-  register REG *sti_ptr = &st(FPU_rm);
-  reg_move(st0_ptr, &t);
-  reg_move(sti_ptr, st0_ptr);
+  FPU_REG t;
+  register FPU_REG *sti_ptr = &st(FPU_rm);
+  reg_move(FPU_st0_ptr, &t);
+  reg_move(sti_ptr, FPU_st0_ptr);
   reg_move(&t, sti_ptr);
 }
 
@@ -135,14 +131,14 @@ void ffree_()
 void fst_i_()
 {
   /* fst st(i) */
-  reg_move(st0_ptr, &st(FPU_rm));
+  reg_move(FPU_st0_ptr, &st(FPU_rm));
 }
 
 
 void fstp_i()
 {
   /* fstp st(i) */
-  reg_move(st0_ptr, &st(FPU_rm));
+  reg_move(FPU_st0_ptr, &st(FPU_rm));
   pop();
 }
 
index c80aaefb0245c3762beb9b330157a62e6d261f4f..a984f456f3cb7981c62af01fc86820d3a78908db 100644 (file)
 
 #ifndef __ASSEMBLER__
 
-typedef void (*FUNC)();
+#include <linux/math_emu.h>
 
-#define        REG     struct  reg
+#ifdef PARANOID
+extern char emulating;
+#  define RE_ENTRANT_CHECK_OFF emulating = 0;
+#  define RE_ENTRANT_CHECK_ON emulating = 1;
+#else
+#  define RE_ENTRANT_CHECK_OFF
+#  define RE_ENTRANT_CHECK_ON
+#endif PARANOID
 
-struct reg {
-  char sign;
-  char tag;
-/*  short exp; *****/
-  long exp;
-  unsigned sigl;
-  unsigned sigh;
-};
+typedef void (*FUNC)();
+typedef struct fpu_reg FPU_REG;
 
 #define        st(x)   ( regs[((top+x) &7 )] )
 
 #define        STACK_OVERFLOW  (st_new_ptr = &st(-1), st_new_ptr->tag != TW_Empty)
 #define        NOT_EMPTY(i)    (st(i).tag != TW_Empty)
-#define        NOT_EMPTY_0     (st0_tag ^ TW_Empty)
+#define        NOT_EMPTY_0     (FPU_st0_tag ^ TW_Empty)
 
-extern unsigned char FPU_modrm;
 extern unsigned char FPU_rm;
 
-extern char    st0_tag;
-extern REG     *st0_ptr;
+extern char    FPU_st0_tag;
+extern FPU_REG *FPU_st0_ptr;
 
 extern void  *FPU_data_address;
-extern unsigned long FPU_entry_eip;
 
-extern  REG  FPU_loaded_data;
+extern  FPU_REG  FPU_loaded_data;
 
-#define pop()  { st0_ptr->tag = TW_Empty; \
-                                 top++; st0_ptr = &(regs[top&7]); }
+#define pop()  { FPU_st0_ptr->tag = TW_Empty; top++; }
 
 /* push() does not affect the tags */
-#define push() { top--; st0_ptr = st_new_ptr; }
+#define push() { top--; FPU_st0_ptr = st_new_ptr; }
 
 
 #define reg_move(x, y) { \
@@ -84,7 +82,7 @@ extern  REG  FPU_loaded_data;
 
 
 /*----- Prototypes for functions written in assembler -----*/
-/* extern void reg_move(REG *a, REG *b); */
+/* extern void reg_move(FPU_REG *a, FPU_REG *b); */
 
 extern void mul64(long long *a, long long *b, long long *result);
 extern void poly_div2(long long *x);
@@ -92,13 +90,13 @@ extern void poly_div4(long long *x);
 extern void poly_div16(long long *x);
 extern void polynomial(unsigned accum[], unsigned x[],
                       unsigned short terms[][4], int n);
-extern void normalize(REG *x);
-extern void reg_div(REG *arg1, REG *arg2, REG *answ);
-extern void reg_u_sub(REG *arg1, REG *arg2, REG *answ);
-extern void reg_u_mul(REG *arg1, REG *arg2, REG *answ);
-extern void reg_u_div(long long *arg1, long long *arg2, REG *answ);
-extern void reg_u_add(REG *arg1, REG *arg2, REG *answ);
-extern void wm_sqrt(REG *n);
+extern void normalize(FPU_REG *x);
+extern void reg_div(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ);
+extern void reg_u_sub(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ);
+extern void reg_u_mul(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ);
+extern void reg_u_div(long long *arg1, long long *arg2, FPU_REG *answ);
+extern void reg_u_add(FPU_REG *arg1, FPU_REG *arg2, FPU_REG *answ);
+extern void wm_sqrt(FPU_REG *n);
 extern unsigned        shrx(void *l, unsigned x);
 extern unsigned        shrxs(void *v, unsigned x);
 extern unsigned long div_small(unsigned long long *x, unsigned long y);
index 81362c6ddfae235f690d6a09db29a946d76725f8..0d02f87e6803338a683ca683f570e0e7fd0d1bd2 100644 (file)
  |                                                                           |
  +---------------------------------------------------------------------------*/
 
+/*---------------------------------------------------------------------------+
+ | Note:                                                                     |
+ |    The file contains code which accesses user memory.                     |
+ |    Emulator static data may change when user memory is accessed, due to   |
+ |    other processes using the emulator while swapping is in progress.      |
+ +---------------------------------------------------------------------------*/
+
 /*---------------------------------------------------------------------------+
  | math_emulate() is the sole entry point for wm-FPU-emu                     |
  +---------------------------------------------------------------------------*/
@@ -58,32 +65,30 @@ static unsigned char type_table[64] = {
 };
 
 
-unsigned char  FPU_lookahead;
-unsigned char  FPU_modrm;
+/* Be careful when using any of these global variables...
+   they might change if swapping is triggered */
 unsigned char  FPU_rm;
-char          st0_tag;
-struct reg     *st0_ptr;
-
-struct info    *FPU_info;
-
-unsigned long  FPU_entry_eip;
+char          FPU_st0_tag;
+FPU_REG       *FPU_st0_ptr;
 
+#ifdef PARANOID
+char emulating=0;
+#endif PARANOID
 
 #define bswapw(x) __asm__("xchgb %%al,%%ah":"=a" (x):"0" ((short)x))
 
 
 void math_emulate(long arg)
 {
+  unsigned char  FPU_modrm;
   unsigned short code;
 
 #ifdef PARANOID
-  static int emulating=0;
-
   if ( emulating )
     {
       printk("ERROR: wm-FPU-emu is not RE-ENTRANT!\r\n");
     }
-emulating = 1;
+  RE_ENTRANT_CHECK_ON
 #endif PARANOID
 
   if (!current->used_math)
@@ -114,50 +119,57 @@ do_another:
 
   FPU_entry_eip = FPU_ORIG_EIP = FPU_EIP;
 
+  RE_ENTRANT_CHECK_OFF
   code = get_fs_word((unsigned short *) FPU_EIP);
+  RE_ENTRANT_CHECK_ON
+
   if ( (code & 0xff) == 0x66 )
     {
       FPU_EIP++;
+      RE_ENTRANT_CHECK_OFF
       code = get_fs_word((unsigned short *) FPU_EIP);
+      RE_ENTRANT_CHECK_ON
     }
   FPU_EIP += 2;
 
   FPU_modrm = code >> 8;
   FPU_rm = FPU_modrm & 7;
 
-  st0_ptr = &st(0);
-  st0_tag = st0_ptr->tag;
-
   if ( FPU_modrm < 0300 )
     {
       /* All of these instructions use the mod/rm byte to get a data address */
-      get_address();
+      get_address(FPU_modrm);
       if ( !(code & 1) )
        {
+         switch ( (code >> 1) & 3 )
+           {
+           case 0:
+             reg_load_single();
+             break;
+           case 1:
+             reg_load_int32();
+             break;
+           case 2:
+             reg_load_double();
+             break;
+           case 3:
+             reg_load_int16();
+             break;
+           }
+
+         /* No more access to user memory, it is safe
+            to use static data now */
+         FPU_st0_ptr = &st(0);
+         FPU_st0_tag = FPU_st0_ptr->tag;
          if ( NOT_EMPTY_0 )
            {
-             switch ( (code >> 1) & 3 )
-               {
-               case 0:
-                 reg_load_single();
-                 break;
-               case 1:
-                 reg_load_int32();
-                 break;
-               case 2:
-                 reg_load_double();
-                 break;
-               case 3:
-                 reg_load_int16();
-                 break;
-               }
              switch ( (FPU_modrm >> 3) & 7 )
                {
                case 0:         /* fadd */
-                 reg_add(st0_ptr, &FPU_loaded_data, st0_ptr);
+                 reg_add(FPU_st0_ptr, &FPU_loaded_data, FPU_st0_ptr);
                  break;
                case 1:         /* fmul */
-                 reg_mul(st0_ptr, &FPU_loaded_data, st0_ptr);
+                 reg_mul(FPU_st0_ptr, &FPU_loaded_data, FPU_st0_ptr);
                  break;
                case 2:         /* fcom */
                  compare_st_data();
@@ -167,16 +179,16 @@ do_another:
                  pop();
                  break;
                case 4:         /* fsub */
-                 reg_sub(st0_ptr, &FPU_loaded_data, st0_ptr);
+                 reg_sub(FPU_st0_ptr, &FPU_loaded_data, FPU_st0_ptr);
                  break;
                case 5:         /* fsubr */
-                 reg_sub(&FPU_loaded_data, st0_ptr, st0_ptr);
+                 reg_sub(&FPU_loaded_data, FPU_st0_ptr, FPU_st0_ptr);
                  break;
                case 6:         /* fdiv */
-                 reg_div(st0_ptr, &FPU_loaded_data, st0_ptr);
+                 reg_div(FPU_st0_ptr, &FPU_loaded_data, FPU_st0_ptr);
                  break;
                case 7:         /* fdivr */
-                 reg_div(&FPU_loaded_data, st0_ptr, st0_ptr);
+                 reg_div(&FPU_loaded_data, FPU_st0_ptr, FPU_st0_ptr);
                  break;
                }
            }
@@ -184,13 +196,18 @@ do_another:
            stack_underflow();
        }
       else
-       load_store_instr(((FPU_modrm & 0x38) | (code & 6)) >> 1);
+       {
+         load_store_instr(((FPU_modrm & 0x38) | (code & 6)) >> 1);
+       }
 
-      data_operand_offset = FPU_data_address;
+      data_operand_offset = (unsigned long)FPU_data_address;
     }
   else
     {
+      /* None of these instructions access user memory */
       unsigned char instr_index = (FPU_modrm & 0x38) | (code & 7);
+      FPU_st0_ptr = &st(0);
+      FPU_st0_tag = FPU_st0_ptr->tag;
       switch ( type_table[(int) instr_index] )
        {
        case _NONE_:
@@ -231,7 +248,9 @@ instruction_done:
     {
       unsigned char next;
 skip_fwait:
+      RE_ENTRANT_CHECK_OFF
       next = get_fs_byte((unsigned char *) FPU_EIP);
+      RE_ENTRANT_CHECK_ON
 test_for_fp:
       if ( (next & 0xf8) == 0xd8 )
        {
@@ -241,16 +260,15 @@ test_for_fp:
        { FPU_EIP++; goto skip_fwait; }
       if ( next == 0x66 )  /* size prefix */
        {
+         RE_ENTRANT_CHECK_OFF
          next = get_fs_byte((unsigned char *) (FPU_EIP+1));
+         RE_ENTRANT_CHECK_ON
          if ( (next & 0xf8) == 0xd8 )
            goto test_for_fp;
        }
     }
 
-#ifdef PARANOID
-  emulating = 0;
-#endif PARANOID
-
+  RE_ENTRANT_CHECK_OFF
 }
 
 
index 10fbf6a6d85d5096b3fa00842917f3dd581b7a58..ce160a1bc99db80f2dfb5c46125b73b6b6e16892 100644 (file)
@@ -20,7 +20,7 @@ static void fchs()
 {
   if ( NOT_EMPTY_0 )
     {
-      st0_ptr->sign ^= SIGN_POS^SIGN_NEG;
+      FPU_st0_ptr->sign ^= SIGN_POS^SIGN_NEG;
       status_word &= ~SW_C1;
     }
   else
@@ -29,9 +29,9 @@ static void fchs()
 
 static void fabs()
 {
-  if ( st0_tag ^ TW_Empty )
+  if ( FPU_st0_tag ^ TW_Empty )
     {
-      st0_ptr->sign = SIGN_POS;
+      FPU_st0_ptr->sign = SIGN_POS;
       status_word &= ~SW_C1;
     }
   else
@@ -41,13 +41,13 @@ static void fabs()
 
 static void ftst_()
 {
-  switch (st0_tag)
+  switch (FPU_st0_tag)
     {
     case TW_Zero:
       setcc(SW_C3);
       break;
     case TW_Valid:
-      if (st0_ptr->sign == SIGN_POS)
+      if (FPU_st0_ptr->sign == SIGN_POS)
         setcc(0);
       else
         setcc(SW_C0);
@@ -57,7 +57,7 @@ static void ftst_()
       EXCEPTION(EX_Invalid);
       break;
     case TW_Infinity:
-      if (st0_ptr->sign == SIGN_POS)
+      if (FPU_st0_ptr->sign == SIGN_POS)
         setcc(0);
       else
         setcc(SW_C3);
@@ -78,7 +78,7 @@ static void ftst_()
 static void fxam()
 {
   int c=0;
-  switch (st0_tag)
+  switch (FPU_st0_tag)
     {
     case TW_Empty:
       c = SW_C3|SW_C0;
@@ -87,7 +87,7 @@ static void fxam()
       c = SW_C3;
       break;
     case TW_Valid:
-      if (st0_ptr->sigh & 0x80000000)
+      if (FPU_st0_ptr->sigh & 0x80000000)
         c = SW_C2;
       else
         c = SW_C3|SW_C2;
@@ -99,7 +99,7 @@ static void fxam()
       c = SW_C2|SW_C0;
       break;
     }
-  if (st0_ptr->sign == SIGN_NEG)
+  if (FPU_st0_ptr->sign == SIGN_NEG)
     c |= SW_C1;
   setcc(c);
 }
index e2fbbb1cdb0ee88f1360c26fc461f28ac467462d..78492f3567fc0e9bbce6560e878af9cc22554391 100644 (file)
@@ -2,11 +2,11 @@
 extern void Un_impl(void);
 extern void emu_printall(void);
 extern void exception(int n);
-extern void real_2op_NaN(struct reg *a, struct reg *b, struct reg *dest);
-extern void arith_invalid(struct reg *dest);
-extern void divide_by_zero(int sign, struct reg *dest);
-extern void arith_overflow(struct reg *dest);
-extern void arith_underflow(struct reg *dest);
+extern void real_2op_NaN(struct fpu_reg *a, struct fpu_reg *b, struct fpu_reg *dest);
+extern void arith_invalid(struct fpu_reg *dest);
+extern void divide_by_zero(int sign, struct fpu_reg *dest);
+extern void arith_overflow(struct fpu_reg *dest);
+extern void arith_underflow(struct fpu_reg *dest);
 extern void stack_overflow(void);
 extern void stack_underflow(void);
 /* fpu_arith.c */
@@ -43,30 +43,30 @@ extern void math_emulate(long arg);
 /* fpu_etc.c */
 extern void fp_etc(void);
 /* fpu_trig.c */
-extern void convert_l2reg(long *arg, struct reg *dest);
+extern void convert_l2reg(long *arg, struct fpu_reg *dest);
 extern void trig_a(void);
 extern void trig_b(void);
 /* get_address.c */
-extern void get_address(void);
+extern void get_address(unsigned char FPU_modrm);
 /* load_store.c */
 extern void load_store_instr(char type);
 /* poly_2xm1.c */
-extern int poly_2xm1(struct reg *arg, struct reg *result);
+extern int poly_2xm1(struct fpu_reg *arg, struct fpu_reg *result);
 /* poly_atan.c */
-extern void poly_atan(struct reg *arg);
-extern void poly_add_1(struct reg *src);
+extern void poly_atan(struct fpu_reg *arg);
+extern void poly_add_1(struct fpu_reg *src);
 /* poly_l2.c */
-extern void poly_l2(struct reg *arg, struct reg *result);
-extern int poly_l2p1(struct reg *arg, struct reg *result);
+extern void poly_l2(struct fpu_reg *arg, struct fpu_reg *result);
+extern int poly_l2p1(struct fpu_reg *arg, struct fpu_reg *result);
 /* poly_sin.c */
-extern void poly_sine(struct reg *arg, struct reg *result);
+extern void poly_sine(struct fpu_reg *arg, struct fpu_reg *result);
 /* poly_tan.c */
-extern void poly_tan(struct reg *arg, struct reg *y_reg);
+extern void poly_tan(struct fpu_reg *arg, struct fpu_reg *y_reg);
 /* reg_add_sub.c */
-extern void reg_add(struct reg *a, struct reg *b, struct reg *dest);
-extern void reg_sub(struct reg *a, struct reg *b, struct reg *dest);
+extern void reg_add(struct fpu_reg *a, struct fpu_reg *b, struct fpu_reg *dest);
+extern void reg_sub(struct fpu_reg *a, struct fpu_reg *b, struct fpu_reg *dest);
 /* reg_compare.c */
-extern int compare(struct reg *b);
+extern int compare(struct fpu_reg *b);
 extern void compare_st_data(void);
 extern void fcom_st(void);
 extern void fcompst(void);
@@ -91,10 +91,10 @@ extern int reg_store_int64(void);
 extern int reg_store_int32(void);
 extern int reg_store_int16(void);
 extern int reg_store_bcd(void);
-extern int round_to_int(struct reg *r);
+extern int round_to_int(struct fpu_reg *r);
 extern char *fldenv(void);
 extern void frstor(void);
 extern char *fstenv(void);
 extern void fsave(void);
 /* reg_mul.c */
-extern void reg_mul(struct reg *a, struct reg *b, struct reg *dest);
+extern void reg_mul(struct fpu_reg *a, struct fpu_reg *b, struct fpu_reg *dest);
index c8998b8dd459e394ff015f3dd51238862987058b..3f0def78bbec9c739d0629406f97ea713cc285b5 100644 (file)
 
 /* system dependent definitions */
 
-#include <linux/math_emu.h>
+#include <linux/sched.h>
 #include <linux/kernel.h>
 
+#define I387                   (current->tss.i387)
+#define FPU_info               (I387.soft.info)
+
 #define FPU_CS                 (*(unsigned short *) &(FPU_info->___cs))
 #define FPU_DS                 (*(unsigned short *) &(FPU_info->___ds))
+#define FPU_EAX                        (FPU_info->___eax)
 #define FPU_EFLAGS             (FPU_info->___eflags)
 #define FPU_EIP                        (FPU_info->___eip)
 #define FPU_ORIG_EIP           (FPU_info->___orig_eip)
 
+#define FPU_lookahead           (I387.soft.lookahead)
+#define FPU_entry_eip           (I387.soft.entry_eip)
+
 #define status_word            (I387.soft.swd)
 #define control_word           (I387.soft.cwd)
-#define regs                   ((REG *)(&(I387.soft.regs_space)))
+#define regs                   (I387.soft.regs)
 #define top                    (I387.soft.top)
 
 #define ip_offset              (I387.soft.fip)
@@ -30,6 +37,4 @@
 #define data_operand_offset    (I387.soft.foo)
 #define operand_selector       (I387.soft.fos)
 
-extern  struct info    *FPU_info;
-
 #endif
index a298f2e4514b48a58c5b6f7ca76b989e10c1ec5e..0def16732ef279af2d86631db2bdf54e41cec224 100644 (file)
@@ -18,9 +18,9 @@
 
 
 
-static int trig_arg(REG *X)
+static int trig_arg(FPU_REG *X)
 {
-  REG tmp, quot;
+  FPU_REG tmp, quot;
   int rv;
   long long q;
   int old_cw = control_word;
@@ -48,7 +48,7 @@ static int trig_arg(REG *X)
 
 
 /* Convert a long to register */
-void convert_l2reg(long *arg, REG *dest)
+void convert_l2reg(long *arg, FPU_REG *dest)
 {
   long num = *arg;
   
@@ -70,14 +70,14 @@ void convert_l2reg(long *arg, REG *dest)
 
 static void single_arg_error(void)
 {
-  switch ( st0_tag )
+  switch ( FPU_st0_tag )
     {
     case TW_NaN:
-      if ( !(st0_ptr->sigh & 0x40000000) )   /* Signaling ? */
+      if ( !(FPU_st0_ptr->sigh & 0x40000000) )   /* Signaling ? */
        {
          EXCEPTION(EX_Invalid);
          /* Convert to a QNaN */
-         st0_ptr->sigh |= 0x40000000;
+         FPU_st0_ptr->sigh |= 0x40000000;
        }
     case TW_Empty:
       stack_underflow();
@@ -93,18 +93,18 @@ static void single_arg_error(void)
 
 static void f2xm1()
 {
-  switch ( st0_tag )
+  switch ( FPU_st0_tag )
     {
     case TW_Valid:
       {
-       struct reg rv, tmp;
+       FPU_REG rv, tmp;
        
-       if ( st0_ptr->sign == SIGN_POS )
+       if ( FPU_st0_ptr->sign == SIGN_POS )
          {
            /* poly_2xm1(x) requires 0 < x < 1. */
-           if ( poly_2xm1(st0_ptr, &rv) )
+           if ( poly_2xm1(FPU_st0_ptr, &rv) )
              return;
-           reg_mul(&rv, st0_ptr, st0_ptr);
+           reg_mul(&rv, FPU_st0_ptr, FPU_st0_ptr);
            return;
          }
        else
@@ -112,24 +112,24 @@ static void f2xm1()
 /* **** Should change poly_2xm1() to at least handle numbers near 0 */
            /* poly_2xm1(x) doesn't handle negative numbers. */
            /* So we compute (poly_2xm1(x+1)-1)/2, for -1 < x < 0 */
-           reg_add(st0_ptr, &CONST_1, &tmp);
+           reg_add(FPU_st0_ptr, &CONST_1, &tmp);
            poly_2xm1(&tmp, &rv);
            reg_mul(&rv, &tmp, &tmp);
-           reg_sub(&tmp, &CONST_1, st0_ptr);
-           st0_ptr->exp--;
+           reg_sub(&tmp, &CONST_1, FPU_st0_ptr);
+           FPU_st0_ptr->exp--;
          }
-       if ( st0_ptr->exp <= EXP_UNDER )
-         arith_underflow(st0_ptr);
+       if ( FPU_st0_ptr->exp <= EXP_UNDER )
+         arith_underflow(FPU_st0_ptr);
        return;
       }
     case TW_Zero:
       return;
     case TW_Infinity:
-      if ( st0_ptr->sign == SIGN_NEG )
+      if ( FPU_st0_ptr->sign == SIGN_NEG )
        {
          /* -infinity gives -1 (p16-10) */
-         reg_move(&CONST_1, st0_ptr);
-         st0_ptr->sign = SIGN_NEG;
+         reg_move(&CONST_1, FPU_st0_ptr);
+         FPU_st0_ptr->sign = SIGN_NEG;
        }
       return;
     default:
@@ -139,48 +139,48 @@ static void f2xm1()
 
 static void fptan()
 {
-  REG *st_new_ptr;
+  FPU_REG *st_new_ptr;
   int q;
-  char arg_sign = st0_ptr->sign;
+  char arg_sign = FPU_st0_ptr->sign;
 
   if ( STACK_OVERFLOW )
     { stack_overflow(); return; }
 
-  switch ( st0_tag )
+  switch ( FPU_st0_tag )
     {
     case TW_Valid:
-      st0_ptr->sign = SIGN_POS;
-      if ( (q = trig_arg(st0_ptr)) != -1 )
+      FPU_st0_ptr->sign = SIGN_POS;
+      if ( (q = trig_arg(FPU_st0_ptr)) != -1 )
        {
          if (q & 1)
-           reg_sub(&CONST_1, st0_ptr, st0_ptr);
+           reg_sub(&CONST_1, FPU_st0_ptr, FPU_st0_ptr);
          
-         poly_tan(st0_ptr, st0_ptr);
+         poly_tan(FPU_st0_ptr, FPU_st0_ptr);
 
-         st0_ptr->sign = (q & 1) ^ arg_sign;
+         FPU_st0_ptr->sign = (q & 1) ^ arg_sign;
          
-         if ( st0_ptr->exp <= EXP_UNDER )
-           arith_underflow(st0_ptr);
+         if ( FPU_st0_ptr->exp <= EXP_UNDER )
+           arith_underflow(FPU_st0_ptr);
          
          push();
-         reg_move(&CONST_1, st0_ptr);
+         reg_move(&CONST_1, FPU_st0_ptr);
          setcc(0);
        }
       else
        {
          /* Operand is out of range */
          setcc(SW_C2);
-         st0_ptr->sign = arg_sign;         /* restore st(0) */
+         FPU_st0_ptr->sign = arg_sign;         /* restore st(0) */
          return;
        }
       break;
     case TW_Infinity:
-      arith_invalid(st0_ptr);
+      arith_invalid(FPU_st0_ptr);
       setcc(0);
       return;
     case TW_Zero:
       push();
-      reg_move(&CONST_1, st0_ptr);
+      reg_move(&CONST_1, FPU_st0_ptr);
       setcc(0);
       break;
     default:
@@ -192,54 +192,54 @@ static void fptan()
 
 static void fxtract()
 {
-  REG *st_new_ptr;
-  register REG *st1_ptr = st0_ptr;  /* anticipate */
+  FPU_REG *st_new_ptr;
+  register FPU_REG *st1_ptr = FPU_st0_ptr;  /* anticipate */
 
   if ( STACK_OVERFLOW )
     {  stack_overflow(); return; }
 
-  if ( !(st0_tag ^ TW_Valid) )
+  if ( !(FPU_st0_tag ^ TW_Valid) )
     {
       long e;
          
       push();
-      reg_move(st1_ptr, st0_ptr);
-      st0_ptr->exp = EXP_BIAS;
+      reg_move(st1_ptr, FPU_st0_ptr);
+      FPU_st0_ptr->exp = EXP_BIAS;
       e = st1_ptr->exp - EXP_BIAS;
       convert_l2reg(&e, st1_ptr);
       return;
     }
-  else if ( st0_tag == TW_Zero )
+  else if ( FPU_st0_tag == TW_Zero )
     {
-      char sign = st0_ptr->sign;
-      divide_by_zero(SIGN_NEG, st0_ptr);
+      char sign = FPU_st0_ptr->sign;
+      divide_by_zero(SIGN_NEG, FPU_st0_ptr);
       push();
-      reg_move(&CONST_Z, st0_ptr);
-      st0_ptr->sign = sign;
+      reg_move(&CONST_Z, FPU_st0_ptr);
+      FPU_st0_ptr->sign = sign;
       return;
     }
-  else if ( st0_tag == TW_Infinity )
+  else if ( FPU_st0_tag == TW_Infinity )
     {
-      char sign = st0_ptr->sign;
-      st0_ptr->sign = SIGN_POS;
+      char sign = FPU_st0_ptr->sign;
+      FPU_st0_ptr->sign = SIGN_POS;
       push();
-      reg_move(&CONST_INF, st0_ptr);
-      st0_ptr->sign = sign;
+      reg_move(&CONST_INF, FPU_st0_ptr);
+      FPU_st0_ptr->sign = sign;
       return;
     }
-  else if ( st0_tag == TW_NaN )
+  else if ( FPU_st0_tag == TW_NaN )
     {
-      if ( !(st0_ptr->sigh & 0x40000000) )   /* Signaling ? */
+      if ( !(FPU_st0_ptr->sigh & 0x40000000) )   /* Signaling ? */
        {
          EXCEPTION(EX_Invalid);
          /* Convert to a QNaN */
-         st0_ptr->sigh |= 0x40000000;
+         FPU_st0_ptr->sigh |= 0x40000000;
        }
       push();
-      reg_move(st1_ptr, st0_ptr);
+      reg_move(st1_ptr, FPU_st0_ptr);
       return;
     }
-  else if ( st0_tag == TW_Empty )
+  else if ( FPU_st0_tag == TW_Empty )
     {
       /* Is this the correct behaviour? */
       if ( control_word & EX_Invalid )
@@ -260,42 +260,42 @@ static void fxtract()
 
 static void fdecstp()
 {
-  top--;  /* st0_ptr will be fixed in math_emulate() before the next instr */
+  top--;  /* FPU_st0_ptr will be fixed in math_emulate() before the next instr */
 }
 
 static void fincstp()
 {
-  top++;  /* st0_ptr will be fixed in math_emulate() before the next instr */
+  top++;  /* FPU_st0_ptr will be fixed in math_emulate() before the next instr */
 }
 
 
 static void fsqrt_()
 {
-  if ( !(st0_tag ^ TW_Valid) )
+  if ( !(FPU_st0_tag ^ TW_Valid) )
     {
       int expon;
       
-      if (st0_ptr->sign == SIGN_NEG)
+      if (FPU_st0_ptr->sign == SIGN_NEG)
        {
-         arith_invalid(st0_ptr);
+         arith_invalid(FPU_st0_ptr);
          return;
        }
 
-      expon = st0_ptr->exp - EXP_BIAS;
-      st0_ptr->exp = EXP_BIAS + (expon & 1);  /* make st(0) in  [1.0 .. 4.0) */
+      expon = FPU_st0_ptr->exp - EXP_BIAS;
+      FPU_st0_ptr->exp = EXP_BIAS + (expon & 1);  /* make st(0) in  [1.0 .. 4.0) */
       
-      wm_sqrt(st0_ptr);        /* Do the computation */
+      wm_sqrt(FPU_st0_ptr);    /* Do the computation */
       
-      st0_ptr->exp += expon >> 1;
-      st0_ptr->tag = TW_Valid;
-      st0_ptr->sign = SIGN_POS;
+      FPU_st0_ptr->exp += expon >> 1;
+      FPU_st0_ptr->tag = TW_Valid;
+      FPU_st0_ptr->sign = SIGN_POS;
     }
-  else if ( st0_tag == TW_Zero )
+  else if ( FPU_st0_tag == TW_Zero )
     return;
-  else if ( st0_tag == TW_Infinity )
+  else if ( FPU_st0_tag == TW_Infinity )
     {
-      if ( st0_ptr->sign == SIGN_NEG )
-       arith_invalid(st0_ptr);
+      if ( FPU_st0_ptr->sign == SIGN_NEG )
+       arith_invalid(FPU_st0_ptr);
       return;
     }
   else
@@ -305,17 +305,17 @@ static void fsqrt_()
 
 static void frndint_()
 {
-  if ( !(st0_tag ^ TW_Valid) )
+  if ( !(FPU_st0_tag ^ TW_Valid) )
     {
-      if (st0_ptr->exp > EXP_BIAS+63)
+      if (FPU_st0_ptr->exp > EXP_BIAS+63)
        return;
 
-      round_to_int(st0_ptr);  /* Fortunately, this can't overflow to 2^64 */
-      st0_ptr->exp = EXP_BIAS + 63;
-      normalize(st0_ptr);
+      round_to_int(FPU_st0_ptr);  /* Fortunately, this can't overflow to 2^64 */
+      FPU_st0_ptr->exp = EXP_BIAS + 63;
+      normalize(FPU_st0_ptr);
       return;
     }
-  else if ( (st0_tag == TW_Zero) || (st0_tag == TW_Infinity) )
+  else if ( (FPU_st0_tag == TW_Zero) || (FPU_st0_tag == TW_Infinity) )
     return;
   else
     single_arg_error();
@@ -324,28 +324,28 @@ static void frndint_()
 
 static void fsin()
 {
-  if ( st0_tag == TW_Valid )
+  if ( FPU_st0_tag == TW_Valid )
     {
       int q;
-      char arg_sign = st0_ptr->sign;
-      st0_ptr->sign = SIGN_POS;
-      if ( (q = trig_arg(st0_ptr)) != -1 )
+      char arg_sign = FPU_st0_ptr->sign;
+      FPU_st0_ptr->sign = SIGN_POS;
+      if ( (q = trig_arg(FPU_st0_ptr)) != -1 )
        {
-         REG rv;
+         FPU_REG rv;
          
          if (q & 1)
-           reg_sub(&CONST_1, st0_ptr, st0_ptr);
+           reg_sub(&CONST_1, FPU_st0_ptr, FPU_st0_ptr);
          
-         poly_sine(st0_ptr, &rv);
+         poly_sine(FPU_st0_ptr, &rv);
          
          setcc(0);
          if (q & 2)
            rv.sign ^= SIGN_POS ^ SIGN_NEG;
          rv.sign ^= arg_sign;
-         reg_move(&rv, st0_ptr);
+         reg_move(&rv, FPU_st0_ptr);
 
-         if ( st0_ptr->exp <= EXP_UNDER )
-           arith_underflow(st0_ptr);
+         if ( FPU_st0_ptr->exp <= EXP_UNDER )
+           arith_underflow(FPU_st0_ptr);
 
          return;
        }
@@ -353,19 +353,19 @@ static void fsin()
        {
          /* Operand is out of range */
          setcc(SW_C2);
-         st0_ptr->sign = arg_sign;         /* restore st(0) */
+         FPU_st0_ptr->sign = arg_sign;         /* restore st(0) */
          EXCEPTION(EX_Invalid);
          return;
        }
     }
-  else if ( st0_tag == TW_Zero )
+  else if ( FPU_st0_tag == TW_Zero )
     {
       setcc(0);
       return;
     }
-  else if ( st0_tag == TW_Infinity )
+  else if ( FPU_st0_tag == TW_Infinity )
     {
-      arith_invalid(st0_ptr);
+      arith_invalid(FPU_st0_ptr);
       setcc(0);
       return;
     }
@@ -374,7 +374,7 @@ static void fsin()
 }
 
 
-static int f_cos(REG *arg)
+static int f_cos(FPU_REG *arg)
 {
   if ( arg->tag == TW_Valid )
     {
@@ -383,7 +383,7 @@ static int f_cos(REG *arg)
       arg->sign = SIGN_POS;
       if ( (q = trig_arg(arg)) != -1 )
        {
-         REG rv;
+         FPU_REG rv;
          
          if ( !(q & 1) )
            reg_sub(&CONST_1, arg, arg);
@@ -412,9 +412,9 @@ static int f_cos(REG *arg)
       setcc(0);
       return 0;
     }
-  else if ( st0_tag == TW_Infinity )
+  else if ( FPU_st0_tag == TW_Infinity )
     {
-      arith_invalid(st0_ptr);
+      arith_invalid(FPU_st0_ptr);
       setcc(0);
       return 1;
     }
@@ -428,24 +428,24 @@ static int f_cos(REG *arg)
 
 static void fcos()
 {
-  f_cos(st0_ptr);
+  f_cos(FPU_st0_ptr);
 }
 
 
 static void fsincos()
 {
-  REG *st_new_ptr;
-  REG arg;
+  FPU_REG *st_new_ptr;
+  FPU_REG arg;
          
   if ( STACK_OVERFLOW )
     { stack_overflow(); return; }
 
-  reg_move(st0_ptr,&arg);
+  reg_move(FPU_st0_ptr,&arg);
   if ( !f_cos(&arg) )
     {
       fsin();
       push();
-      reg_move(&arg,st0_ptr);
+      reg_move(&arg,FPU_st0_ptr);
     }
 
 }
@@ -458,14 +458,14 @@ static void fsincos()
 /* Assumes that st(0) and st(1) are both TW_Valid */
 static void fprem_kernel(int round)
 {
-  REG *st1_ptr = &st(1);
+  FPU_REG *st1_ptr = &st(1);
   char st1_tag = st1_ptr->tag;
 
-  if ( !((st0_tag ^ TW_Valid) | (st1_tag ^ TW_Valid)) )
+  if ( !((FPU_st0_tag ^ TW_Valid) | (st1_tag ^ TW_Valid)) )
     {
-      REG tmp;
+      FPU_REG tmp;
       int old_cw = control_word;
-      int expdif = st0_ptr->exp - (st1_ptr)->exp;
+      int expdif = FPU_st0_ptr->exp - (st1_ptr)->exp;
       
       control_word &= ~CW_RC;
       control_word |= round;
@@ -475,7 +475,7 @@ static void fprem_kernel(int round)
          /* This should be the most common case */
          long long q;
          int c = 0;
-         reg_div(st0_ptr, st1_ptr, &tmp);
+         reg_div(FPU_st0_ptr, st1_ptr, &tmp);
          
          round_to_int(&tmp);  /* Fortunately, this can't overflow to 2^64 */
          tmp.exp = EXP_BIAS + 63;
@@ -483,7 +483,7 @@ static void fprem_kernel(int round)
          normalize(&tmp);
          
          reg_mul(st1_ptr, &tmp, &tmp);
-         reg_sub(st0_ptr, &tmp, st0_ptr);
+         reg_sub(FPU_st0_ptr, &tmp, FPU_st0_ptr);
          
          if (q&4) c |= SW_C3;
          if (q&2) c |= SW_C1;
@@ -496,7 +496,7 @@ static void fprem_kernel(int round)
          /* There is a large exponent difference ( >= 64 ) */
          int N_exp;
          
-         reg_div(st0_ptr, st1_ptr, &tmp);
+         reg_div(FPU_st0_ptr, st1_ptr, &tmp);
          /* N is 'a number between 32 and 63' (p26-113) */
          N_exp = (tmp.exp & 31) + 32;
          tmp.exp = EXP_BIAS + N_exp;
@@ -508,30 +508,30 @@ static void fprem_kernel(int round)
          tmp.exp = EXP_BIAS + expdif - N_exp;
          
          reg_mul(st1_ptr, &tmp, &tmp);
-         reg_sub(st0_ptr, &tmp, st0_ptr);
+         reg_sub(FPU_st0_ptr, &tmp, FPU_st0_ptr);
          
          setcc(SW_C2);
        }
       control_word = old_cw;
 
-      if ( st0_ptr->exp <= EXP_UNDER )
-       arith_underflow(st0_ptr);
+      if ( FPU_st0_ptr->exp <= EXP_UNDER )
+       arith_underflow(FPU_st0_ptr);
       return;
     }
-  else if ( (st0_tag == TW_Empty) | (st1_tag == TW_Empty) )
+  else if ( (FPU_st0_tag == TW_Empty) | (st1_tag == TW_Empty) )
     { stack_underflow(); return; }
-  else if ( st0_tag == TW_Zero )
+  else if ( FPU_st0_tag == TW_Zero )
     {
       if ( (st1_tag == TW_Valid) || (st1_tag == TW_Infinity) )
        { setcc(0); return; }
       if ( st1_tag == TW_Zero )
-       { arith_invalid(st0_ptr); return; }
+       { arith_invalid(FPU_st0_ptr); return; }
     }
 
-  if ( (st0_tag == TW_NaN) | (st1_tag == TW_NaN) )
-    { real_2op_NaN(st0_ptr, st1_ptr, st0_ptr); return; }
-  else if ( st0_tag == TW_Infinity )
-    { arith_invalid(st0_ptr); return; }
+  if ( (FPU_st0_tag == TW_NaN) | (st1_tag == TW_NaN) )
+    { real_2op_NaN(FPU_st0_ptr, st1_ptr, FPU_st0_ptr); return; }
+  else if ( FPU_st0_tag == TW_Infinity )
+    { arith_invalid(FPU_st0_ptr); return; }
 #ifdef PARANOID
   else
     EXCEPTION(EX_INTERNAL | 0x118);
@@ -543,94 +543,94 @@ static void fprem_kernel(int round)
 /* ST(1) <- ST(1) * log ST;  pop ST */
 static void fyl2x()
 {
-  REG *st1_ptr = &st(1);
+  FPU_REG *st1_ptr = &st(1);
   char st1_tag = st1_ptr->tag;
 
-  if ( !((st0_tag ^ TW_Valid) | (st1_tag ^ TW_Valid)) )
+  if ( !((FPU_st0_tag ^ TW_Valid) | (st1_tag ^ TW_Valid)) )
     {
-      if ( st0_ptr->sign == SIGN_POS )
+      if ( FPU_st0_ptr->sign == SIGN_POS )
        {
-         poly_l2(st0_ptr, st0_ptr);
+         poly_l2(FPU_st0_ptr, FPU_st0_ptr);
          
-         reg_mul(st0_ptr, st1_ptr, st1_ptr);
-         pop();
-         if ( st0_ptr->exp <= EXP_UNDER )
-           arith_underflow(st0_ptr);
-         else if ( st0_ptr->exp >= EXP_OVER )
-           arith_overflow(st0_ptr);
+         reg_mul(FPU_st0_ptr, st1_ptr, st1_ptr);
+         pop(); FPU_st0_ptr = &st(0);
+         if ( FPU_st0_ptr->exp <= EXP_UNDER )
+           arith_underflow(FPU_st0_ptr);
+         else if ( FPU_st0_ptr->exp >= EXP_OVER )
+           arith_overflow(FPU_st0_ptr);
        }
       else
        {
          /* negative   */
-         pop();
-         arith_invalid(st0_ptr);
+         pop(); FPU_st0_ptr = &st(0);
+         arith_invalid(FPU_st0_ptr);
        }
       return;
     }
 
-  if ( (st0_tag == TW_Empty) || (st1_tag == TW_Empty) )
+  if ( (FPU_st0_tag == TW_Empty) || (st1_tag == TW_Empty) )
     { stack_underflow(); return; }
 
-  if ( (st0_tag == TW_NaN) || (st1_tag == TW_NaN) )
+  if ( (FPU_st0_tag == TW_NaN) || (st1_tag == TW_NaN) )
     {
-      real_2op_NaN(st0_ptr, st1_ptr, st1_ptr);
+      real_2op_NaN(FPU_st0_ptr, st1_ptr, st1_ptr);
       pop();
       return;
     }
 
-  if ( (st0_tag <= TW_Zero) && (st1_tag <= TW_Zero) )
+  if ( (FPU_st0_tag <= TW_Zero) && (st1_tag <= TW_Zero) )
     {
       /* one of the args is zero, the other valid, or both zero */
-      if ( st0_tag == TW_Zero )
+      if ( FPU_st0_tag == TW_Zero )
        {
-         pop();
-         if ( st0_ptr->tag == TW_Zero )
-           arith_invalid(st0_ptr);
+         pop(); FPU_st0_ptr = &st(0);
+         if ( FPU_st0_ptr->tag == TW_Zero )
+           arith_invalid(FPU_st0_ptr);
          else
-           divide_by_zero(st1_ptr->sign ^ SIGN_NEG, st0_ptr);
+           divide_by_zero(st1_ptr->sign ^ SIGN_NEG, FPU_st0_ptr);
          return;
        }
       if ( st1_ptr->sign == SIGN_POS )
        {
          /* Zero is the valid answer */
-         char sign = st0_ptr->sign;
-         if ( st0_ptr->exp < EXP_BIAS ) sign ^= SIGN_NEG;
-         pop();
-         reg_move(&CONST_Z, st0_ptr);
-         st0_ptr->sign = sign;
+         char sign = FPU_st0_ptr->sign;
+         if ( FPU_st0_ptr->exp < EXP_BIAS ) sign ^= SIGN_NEG;
+         pop(); FPU_st0_ptr = &st(0);
+         reg_move(&CONST_Z, FPU_st0_ptr);
+         FPU_st0_ptr->sign = sign;
          return;
        }
-      pop();
-      arith_invalid(st0_ptr);
+      pop(); FPU_st0_ptr = &st(0);
+      arith_invalid(FPU_st0_ptr);
       return;
     }
 
   /* One or both arg must be an infinity */
-  if ( st0_tag == TW_Infinity )
+  if ( FPU_st0_tag == TW_Infinity )
     {
-      if ( (st0_ptr->sign == SIGN_NEG) || (st1_tag == TW_Zero) )
-       { pop(); arith_invalid(st0_ptr); return; }
+      if ( (FPU_st0_ptr->sign == SIGN_NEG) || (st1_tag == TW_Zero) )
+       { pop(); FPU_st0_ptr = &st(0); arith_invalid(FPU_st0_ptr); return; }
       else
        {
          char sign = st1_ptr->sign;
-         pop();
-         reg_move(&CONST_INF, st0_ptr);
-         st0_ptr->sign = sign;
+         pop(); FPU_st0_ptr = &st(0);
+         reg_move(&CONST_INF, FPU_st0_ptr);
+         FPU_st0_ptr->sign = sign;
          return;
        }
     }
 
   /* st(1) must be infinity here */
-  if ( (st0_tag == TW_Valid) && (st0_ptr->sign == SIGN_POS) )
+  if ( (FPU_st0_tag == TW_Valid) && (FPU_st0_ptr->sign == SIGN_POS) )
     {
-      if ( st0_ptr->exp >= EXP_BIAS )
+      if ( FPU_st0_ptr->exp >= EXP_BIAS )
        {
-         if ( (st0_ptr->exp == EXP_BIAS) &&
-             (st0_ptr->sigh == 0x80000000) &&
-             (st0_ptr->sigl == 0) )
+         if ( (FPU_st0_ptr->exp == EXP_BIAS) &&
+             (FPU_st0_ptr->sigh == 0x80000000) &&
+             (FPU_st0_ptr->sigl == 0) )
            {
-             pop();
-             arith_invalid(st0_ptr);
+             pop(); FPU_st0_ptr = &st(0);
+             arith_invalid(FPU_st0_ptr);
              return;
            }
          pop();
@@ -638,35 +638,35 @@ static void fyl2x()
        }
       else
        {
-         pop();
-         st0_ptr->sign ^= SIGN_NEG;
+         pop(); FPU_st0_ptr = &st(0);
+         FPU_st0_ptr->sign ^= SIGN_NEG;
          return;
        }
     }
   /* st(0) must be zero or negative */
-  pop();
-  arith_invalid(st0_ptr);
+  pop(); FPU_st0_ptr = &st(0);
+  arith_invalid(FPU_st0_ptr);
   return;
 }
 
 
 static void fpatan()
 {
-  REG *st1_ptr = &st(1);
+  FPU_REG *st1_ptr = &st(1);
   char st1_tag = st1_ptr->tag;
 
-  if ( !((st0_tag ^ TW_Valid) | (st1_tag ^ TW_Valid)) )
+  if ( !((FPU_st0_tag ^ TW_Valid) | (st1_tag ^ TW_Valid)) )
     {
-      struct reg sum;
-      int quadrant = st1_ptr->sign | ((st0_ptr->sign)<<1);
-      st1_ptr->sign = st0_ptr->sign = SIGN_POS;
+      FPU_REG sum;
+      int quadrant = st1_ptr->sign | ((FPU_st0_ptr->sign)<<1);
+      st1_ptr->sign = FPU_st0_ptr->sign = SIGN_POS;
       if (compare(st1_ptr) == COMP_A_LT_B)
        {
          quadrant |= 4;
-         reg_div(st0_ptr, st1_ptr, &sum);
+         reg_div(FPU_st0_ptr, st1_ptr, &sum);
        }
       else
-       reg_div(st1_ptr, st0_ptr, &sum);
+       reg_div(st1_ptr, FPU_st0_ptr, &sum);
       
       poly_atan(&sum);
       
@@ -682,37 +682,37 @@ static void fpatan()
        sum.sign ^= SIGN_POS^SIGN_NEG;
       
       reg_move(&sum, st1_ptr);
-      pop();
-      if ( st0_ptr->exp <= EXP_UNDER )
-       arith_underflow(st0_ptr);
+      pop(); FPU_st0_ptr = &st(0);
+      if ( FPU_st0_ptr->exp <= EXP_UNDER )
+       arith_underflow(FPU_st0_ptr);
       return;
     }
 
-  if ( (st0_tag == TW_Empty) || (st1_tag == TW_Empty) )
+  if ( (FPU_st0_tag == TW_Empty) || (st1_tag == TW_Empty) )
     { stack_underflow(); return; }
 
-  if ( (st0_tag == TW_NaN) || (st1_tag == TW_NaN) )
+  if ( (FPU_st0_tag == TW_NaN) || (st1_tag == TW_NaN) )
     {
-      real_2op_NaN(st0_ptr, st1_ptr, st1_ptr);
+      real_2op_NaN(FPU_st0_ptr, st1_ptr, st1_ptr);
       pop();
       return;
     }
 
-  if ( (st0_tag == TW_Infinity) || (st1_tag == TW_Infinity) )
+  if ( (FPU_st0_tag == TW_Infinity) || (st1_tag == TW_Infinity) )
     {
       char sign = st1_ptr->sign;
-      if ( st0_tag == TW_Infinity )
+      if ( FPU_st0_tag == TW_Infinity )
        {
          if ( st1_tag == TW_Infinity )
            {
-             if ( st0_ptr->sign == SIGN_POS )
+             if ( FPU_st0_ptr->sign == SIGN_POS )
                { reg_move(&CONST_PI4, st1_ptr); }
              else
                reg_add(&CONST_PI4, &CONST_PI2, st1_ptr);
            }
          else
            {
-             if ( st0_ptr->sign == SIGN_POS )
+             if ( FPU_st0_ptr->sign == SIGN_POS )
                { reg_move(&CONST_Z, st1_ptr); }
              else
                reg_move(&CONST_PI, st1_ptr);
@@ -731,7 +731,7 @@ static void fpatan()
     {
       char sign = st1_ptr->sign;
       /* st(0) must be valid or zero */
-      if ( st0_ptr->sign == SIGN_POS )
+      if ( FPU_st0_ptr->sign == SIGN_POS )
        { reg_move(&CONST_Z, st1_ptr); }
       else
        reg_move(&CONST_PI, st1_ptr);
@@ -739,7 +739,7 @@ static void fpatan()
       pop();
       return;
     }
-  else if ( st0_tag == TW_Zero )
+  else if ( FPU_st0_tag == TW_Zero )
     {
       char sign = st1_ptr->sign;
       /* st(1) must be TW_Valid here */
@@ -768,28 +768,28 @@ static void fprem1()
 
 static void fyl2xp1()
 {
-  REG *st1_ptr = &st(1);
+  FPU_REG *st1_ptr = &st(1);
   char st1_tag = st1_ptr->tag;
 
-  if ( !((st0_tag ^ TW_Valid) | (st1_tag ^ TW_Valid)) )
+  if ( !((FPU_st0_tag ^ TW_Valid) | (st1_tag ^ TW_Valid)) )
     {
-      if ( poly_l2p1(st0_ptr, st0_ptr) )
+      if ( poly_l2p1(FPU_st0_ptr, FPU_st0_ptr) )
        {
          arith_invalid(st1_ptr); pop(); return;
        }
       
-      reg_mul(st0_ptr, st1_ptr, st1_ptr);
+      reg_mul(FPU_st0_ptr, st1_ptr, st1_ptr);
       pop();
       return;
     }
-  else if ( (st0_tag == TW_Empty) | (st1_tag == TW_Empty) )
+  else if ( (FPU_st0_tag == TW_Empty) | (st1_tag == TW_Empty) )
     stack_underflow();
-  else if ( st0_tag == TW_Zero )
+  else if ( FPU_st0_tag == TW_Zero )
     {
       if ( st1_tag <= TW_Zero )
        {
-         st1_ptr->sign ^= st0_ptr->sign;
-         reg_move(st0_ptr, st1_ptr);
+         st1_ptr->sign ^= FPU_st0_ptr->sign;
+         reg_move(FPU_st0_ptr, st1_ptr);
        }
       else if ( st1_tag == TW_Infinity )
        {
@@ -810,16 +810,16 @@ static void fyl2xp1()
       pop();
       return;
     }
-  else if ( st0_tag == TW_NaN )
+  else if ( FPU_st0_tag == TW_NaN )
     {
-      real_2op_NaN(st0_ptr, st1_ptr, st1_ptr);
+      real_2op_NaN(FPU_st0_ptr, st1_ptr, st1_ptr);
       pop();
       return;
     }
-  else if ( st0_tag == TW_Infinity )
+  else if ( FPU_st0_tag == TW_Infinity )
     {
       if ( st1_tag == TW_NaN )
-       real_2op_NaN(st0_ptr, st1_ptr, st1_ptr);
+       real_2op_NaN(FPU_st0_ptr, st1_ptr, st1_ptr);
       else
        arith_invalid(st1_ptr);
       pop();
@@ -834,45 +834,45 @@ static void fyl2xp1()
 
 static void fscale()
 {
-  REG *st1_ptr = &st(1);
+  FPU_REG *st1_ptr = &st(1);
   char st1_tag = st1_ptr->tag;
 
-  if ( !((st0_tag ^ TW_Valid) | (st1_tag ^ TW_Valid)) )
+  if ( !((FPU_st0_tag ^ TW_Valid) | (st1_tag ^ TW_Valid)) )
     {
       long scale;
-      REG tmp;
+      FPU_REG tmp;
 
       /* 2^31 is far too large, 2^-31 is far too small */
       if ( st1_ptr->exp > EXP_BIAS + 30 )
        {
          char sign;
          EXCEPTION(EX_Overflow);
-         sign = st0_ptr->sign;
-         reg_move(&CONST_INF, st0_ptr);
-         st0_ptr->sign = sign;
+         sign = FPU_st0_ptr->sign;
+         reg_move(&CONST_INF, FPU_st0_ptr);
+         FPU_st0_ptr->sign = sign;
          return;
        }
       else if ( st1_ptr->exp < EXP_BIAS - 30 )
        {
          EXCEPTION(EX_Underflow);
-         reg_move(&CONST_Z, st0_ptr);
+         reg_move(&CONST_Z, FPU_st0_ptr);
          return;
        }
 
       reg_move(st1_ptr, &tmp);
       round_to_int(&tmp);               /* This can never overflow here */
       scale = st1_ptr->sign ? -tmp.sigl : tmp.sigl;
-      scale += st0_ptr->exp;
-      st0_ptr->exp = scale;
+      scale += FPU_st0_ptr->exp;
+      FPU_st0_ptr->exp = scale;
 
       if ( scale <= EXP_UNDER )
-       arith_underflow(st0_ptr);
+       arith_underflow(FPU_st0_ptr);
       else if ( scale >= EXP_OVER )
-       arith_overflow(st0_ptr);
+       arith_overflow(FPU_st0_ptr);
 
       return;
     }
-  else if ( st0_tag == TW_Valid )
+  else if ( FPU_st0_tag == TW_Valid )
     {
       if ( st1_tag == TW_Zero )
        { return; }
@@ -880,16 +880,16 @@ static void fscale()
        {
          char sign = st1_ptr->sign;
          if ( sign == SIGN_POS )
-           { reg_move(&CONST_INF, st0_ptr); }
+           { reg_move(&CONST_INF, FPU_st0_ptr); }
          else
-             reg_move(&CONST_Z, st0_ptr);
-         st0_ptr->sign = sign;
+             reg_move(&CONST_Z, FPU_st0_ptr);
+         FPU_st0_ptr->sign = sign;
          return;
        }
       if ( st1_tag == TW_NaN )
-       { real_2op_NaN(st0_ptr, st1_ptr, st0_ptr); return; }
+       { real_2op_NaN(FPU_st0_ptr, st1_ptr, FPU_st0_ptr); return; }
     }
-  else if ( st0_tag == TW_Zero )
+  else if ( FPU_st0_tag == TW_Zero )
     {
       if ( st1_tag <= TW_Zero ) { return; }
       else if ( st1_tag == TW_Infinity )
@@ -897,29 +897,29 @@ static void fscale()
          if ( st1_ptr->sign == SIGN_NEG )
            return;
          else
-           { arith_invalid(st0_ptr); return; }
+           { arith_invalid(FPU_st0_ptr); return; }
        }
       else if ( st1_tag == TW_NaN )
-       { real_2op_NaN(st0_ptr, st1_ptr, st0_ptr); return; }
+       { real_2op_NaN(FPU_st0_ptr, st1_ptr, FPU_st0_ptr); return; }
     }
-  else if ( st0_tag == TW_Infinity )
+  else if ( FPU_st0_tag == TW_Infinity )
     {
       if ( ((st1_tag == TW_Infinity) && (st1_ptr->sign == SIGN_POS))
          || (st1_tag <= TW_Zero) )
        return;
       else if ( st1_tag == TW_Infinity )
-       { arith_invalid(st0_ptr); return; }
+       { arith_invalid(FPU_st0_ptr); return; }
       else if ( st1_tag == TW_NaN )
-       { real_2op_NaN(st0_ptr, st1_ptr, st0_ptr); return; }
+       { real_2op_NaN(FPU_st0_ptr, st1_ptr, FPU_st0_ptr); return; }
     }
-  else if ( st0_tag == TW_NaN )
+  else if ( FPU_st0_tag == TW_NaN )
     {
       if ( st1_tag != TW_Empty )
-       { real_2op_NaN(st0_ptr, st1_ptr, st0_ptr); return; }
+       { real_2op_NaN(FPU_st0_ptr, st1_ptr, FPU_st0_ptr); return; }
     }
 
 #ifdef PARANOID
-  if ( !((st0_tag == TW_Empty) || (st1_tag == TW_Empty)) )
+  if ( !((FPU_st0_tag == TW_Empty) || (st1_tag == TW_Empty)) )
     {
       EXCEPTION(EX_INTERNAL | 0x115);
       return;
index e4e70469afc8f4c59afffd7684d130b78edd69a8..75b149e0c45a61c72152aa634456ca235c958cd2 100644 (file)
@@ -9,9 +9,15 @@
  |                                                                           |
  +---------------------------------------------------------------------------*/
 
+/*---------------------------------------------------------------------------+
+ | Note:                                                                     |
+ |    The file contains code which accesses user memory.                     |
+ |    Emulator static data may change when user memory is accessed, due to   |
+ |    other processes using the emulator while swapping is in progress.      |
+ +---------------------------------------------------------------------------*/
+
 
 #include <linux/stddef.h>
-#include <linux/math_emu.h>
 
 #include <asm/segment.h>
 
@@ -19,8 +25,6 @@
 #include "exception.h"
 #include "fpu_emu.h"
 
-
-
 static int reg_offset[] = {
        offsetof(struct info,___eax),
        offsetof(struct info,___ecx),
@@ -43,8 +47,10 @@ static void *sib(int mod)
 {
   unsigned char ss,index,base;
   long offset;
-  
+
+  RE_ENTRANT_CHECK_OFF
   base = get_fs_byte((char *) FPU_EIP);   /* The SIB byte */
+  RE_ENTRANT_CHECK_ON
   FPU_EIP++;
   ss = base >> 6;
   index = (base >> 3) & 7;
@@ -70,13 +76,17 @@ static void *sib(int mod)
   if (mod == 1)
     {
       /* 8 bit signed displacement */
+      RE_ENTRANT_CHECK_OFF
       offset += (signed char) get_fs_byte((char *) FPU_EIP);
+      RE_ENTRANT_CHECK_ON
       FPU_EIP++;
     }
   else if (mod == 2 || base == 5) /* The second condition also has mod==0 */
     {
       /* 32 bit displacment */
+      RE_ENTRANT_CHECK_OFF
       offset += (signed) get_fs_long((unsigned long *) FPU_EIP);
+      RE_ENTRANT_CHECK_ON
       FPU_EIP += 4;
     }
 
@@ -101,7 +111,7 @@ static void *sib(int mod)
 
 */
 
-void get_address(void)
+void get_address(unsigned char FPU_modrm)
 {
   unsigned char mod;
   long *cpu_reg_ptr;
@@ -122,7 +132,9 @@ void get_address(void)
       if (FPU_rm == 5)
        {
          /* Special case: disp32 */
+         RE_ENTRANT_CHECK_OFF
          offset = get_fs_long((unsigned long *) FPU_EIP);
+         RE_ENTRANT_CHECK_ON
          FPU_EIP += 4;
          FPU_data_address = (void *) offset;
          return;
@@ -135,12 +147,16 @@ void get_address(void)
        }
     case 1:
       /* 8 bit signed displacement */
+      RE_ENTRANT_CHECK_OFF
       offset = (signed char) get_fs_byte((char *) FPU_EIP);
+      RE_ENTRANT_CHECK_ON
       FPU_EIP++;
       break;
     case 2:
       /* 32 bit displacement */
+      RE_ENTRANT_CHECK_OFF
       offset = (signed) get_fs_long((unsigned long *) FPU_EIP);
+      RE_ENTRANT_CHECK_ON
       FPU_EIP += 4;
       break;
     case 3:
index 342f463b33e561ce9f011e1f63ec21951a124676..7e66a5182346c2f12794c695ff1581ea272979e0 100644 (file)
  |                                                                           |
  +---------------------------------------------------------------------------*/
 
+/*---------------------------------------------------------------------------+
+ | Note:                                                                     |
+ |    The file contains code which accesses user memory.                     |
+ |    Emulator static data may change when user memory is accessed, due to   |
+ |    other processes using the emulator while swapping is in progress.      |
+ +---------------------------------------------------------------------------*/
+
 #include <asm/segment.h>
 
 #include "fpu_system.h"
 #include "status_w.h"
 
 
-#define _NONE_ 0
-#define _REG0_ 1   /* Need to check for not empty st(0) */
-#define _REGI_ 2   /* Need to check for not empty st(0) and st(rm) */
-#define _REGi_ 0   /* Uses st(rm) */
+#define _NONE_ 0   /* FPU_st0_ptr etc not needed */
+#define _REG0_ 1   /* Will be storing st(0) */
 #define _PUSH_ 3   /* Need to check for space to push onto stack */
 #define _null_ 4   /* Function illegal or not implemented */
 
+#define pop_0()        { pop_ptr->tag = TW_Empty; top++; }
+
+
 static unsigned char type_table[32] = {
   _PUSH_, _PUSH_, _PUSH_, _PUSH_,
   _null_, _null_, _null_, _null_,
@@ -38,18 +46,25 @@ static unsigned char type_table[32] = {
 
 void load_store_instr(char type)
 {
+  FPU_REG *pop_ptr;  /* We need a version of FPU_st0_ptr which won't change. */
+
   switch ( type_table[(int) (unsigned) type] )
     {
     case _NONE_:
       break;
     case _REG0_:
+      pop_ptr = &st(0);       /* Some of these instructions pop after
+                                storing */
+
+      FPU_st0_ptr = pop_ptr;      /* Set the global variables. */
+      FPU_st0_tag = FPU_st0_ptr->tag;
       break;
     case _PUSH_:
       {
-       REG *st_new_ptr;
-       if ( STACK_OVERFLOW )
+       pop_ptr = &st(-1);
+       if ( pop_ptr->tag != TW_Empty )
          { stack_overflow(); return; }
-       push();
+       top--;
       }
       break;
     case _null_:
@@ -64,19 +79,19 @@ switch ( type )
   {
   case 000:       /* fld m32real */
     reg_load_single();
-    reg_move(&FPU_loaded_data, st0_ptr);
+    reg_move(&FPU_loaded_data, pop_ptr);
     break;
   case 001:      /* fild m32int */
     reg_load_int32();
-    reg_move(&FPU_loaded_data, st0_ptr);
+    reg_move(&FPU_loaded_data, pop_ptr);
     break;
   case 002:      /* fld m64real */
     reg_load_double();
-    reg_move(&FPU_loaded_data, st0_ptr);
+    reg_move(&FPU_loaded_data, pop_ptr);
     break;
   case 003:      /* fild m16int */
     reg_load_int16();
-    reg_move(&FPU_loaded_data, st0_ptr);
+    reg_move(&FPU_loaded_data, pop_ptr);
     break;
   case 010:      /* fst m32real */
     reg_store_single();
@@ -92,22 +107,22 @@ switch ( type )
     break;
   case 014:     /* fstp m32real */
     if ( reg_store_single() )
-      pop();  /* pop only if the number was actually stored
+      pop_0();  /* pop only if the number was actually stored
                 (see the 80486 manual p16-28) */
     break;
   case 015:     /* fistp m32int */
     if ( reg_store_int32() )
-      pop();  /* pop only if the number was actually stored
+      pop_0();  /* pop only if the number was actually stored
                 (see the 80486 manual p16-28) */
     break;
   case 016:     /* fstp m64real */
     if ( reg_store_double() )
-      pop();  /* pop only if the number was actually stored
+      pop_0();  /* pop only if the number was actually stored
                 (see the 80486 manual p16-28) */
     break;
   case 017:     /* fistp m16int */
     if ( reg_store_int16() )
-      pop();  /* pop only if the number was actually stored
+      pop_0();  /* pop only if the number was actually stored
                 (see the 80486 manual p16-28) */
     break;
   case 020:     /* fldenv  m14/28byte */
@@ -118,10 +133,12 @@ switch ( type )
     break;
   case 023:     /* fbld m80dec */
     reg_load_bcd();
-    reg_move(&FPU_loaded_data, st0_ptr);
+    reg_move(&FPU_loaded_data, pop_ptr);
     break;
   case 024:     /* fldcw */
+    RE_ENTRANT_CHECK_OFF
     control_word = get_fs_word((unsigned short *) FPU_data_address);
+    RE_ENTRANT_CHECK_ON
 #ifdef NO_UNDERFLOW_TRAP
     if ( !(control_word & EX_Underflow) )
       {
@@ -133,11 +150,11 @@ switch ( type )
     break;
   case 025:      /* fld m80real */
     reg_load_extended();
-    reg_move(&FPU_loaded_data, st0_ptr);
+    reg_move(&FPU_loaded_data, pop_ptr);
     break;
   case 027:      /* fild m64int */
     reg_load_int64();
-    reg_move(&FPU_loaded_data, st0_ptr);
+    reg_move(&FPU_loaded_data, pop_ptr);
     break;
   case 030:     /* fstenv  m14/28byte */
     fstenv();
@@ -151,31 +168,35 @@ switch ( type )
     break;
   case 033:      /* fbstp m80dec */
     if ( reg_store_bcd() )
-      pop();  /* pop only if the number was actually stored
+      pop_0();  /* pop only if the number was actually stored
                 (see the 80486 manual p16-28) */
     break;
   case 034:      /* fstcw m16int */
+    RE_ENTRANT_CHECK_OFF
     verify_area(FPU_data_address,2);
     put_fs_word(control_word, (short *) FPU_data_address);
+    RE_ENTRANT_CHECK_ON
     FPU_data_address = (void *)data_operand_offset; /* We want no net effect */
     FPU_entry_eip = ip_offset;               /* We want no net effect */
     break;
   case 035:      /* fstp m80real */
     if ( reg_store_extended() )
-      pop();  /* pop only if the number was actually stored
+      pop_0();  /* pop only if the number was actually stored
                 (see the 80486 manual p16-28) */
     break;
   case 036:      /* fstsw m2byte */
     status_word &= ~SW_TOP;
     status_word |= (top&7) << SW_TOPS;
+    RE_ENTRANT_CHECK_OFF
     verify_area(FPU_data_address,2);
     put_fs_word(status_word,(short *) FPU_data_address);
+    RE_ENTRANT_CHECK_ON
     FPU_data_address = (void *)data_operand_offset; /* We want no net effect */
     FPU_entry_eip = ip_offset;               /* We want no net effect */
     break;
   case 037:      /* fistp m64int */
     if ( reg_store_int64() )
-      pop();  /* pop only if the number was actually stored
+      pop_0();  /* pop only if the number was actually stored
                 (see the 80486 manual p16-28) */
     break;
   }
index 266617f4a9c817806d21c967e7b20f14f3758679..749df16ee5f72a0e38cf361c32a9b672a92a3639 100644 (file)
@@ -37,11 +37,11 @@ static unsigned short       lterms[HIPOWER][4] =
 /*--- poly_2xm1() -----------------------------------------------------------+
  |                                                                           |
  +---------------------------------------------------------------------------*/
-int    poly_2xm1(REG *arg, REG *result)
+int    poly_2xm1(FPU_REG *arg, FPU_REG *result)
 {
   short                exponent;
   long long     Xll;
-  REG           accum;
+  FPU_REG           accum;
 
 
   exponent = arg->exp - EXP_BIAS;
index 06b45e20fdec93b4493b384b06f695b62b6c579a..b62b0e7105cd113969960ca3b0cd5100b1c798cc 100644 (file)
@@ -1,7 +1,7 @@
 /*---------------------------------------------------------------------------+
  |  p_atan.c                                                                 |
  |                                                                           |
- | Compute the tan of a REG, using a polynomial approximation.               |
+ | Compute the tan of a FPU_REG, using a polynomial approximation.           |
  |                                                                           |
  | Copyright (C) 1992    W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
  |                       Australia.  E-mail apm233m@vaxc.cc.monash.edu.au    |
@@ -45,12 +45,12 @@ static unsigned denomterm[2] =
 /*--- poly_atan() -----------------------------------------------------------+
  |                                                                           |
  +---------------------------------------------------------------------------*/
-void   poly_atan(REG *arg)
+void   poly_atan(FPU_REG *arg)
 {
   char         recursions = 0;
   short                exponent;
-  REG           odd_poly, even_poly, pos_poly, neg_poly;
-  REG           argSq;
+  FPU_REG       odd_poly, even_poly, pos_poly, neg_poly;
+  FPU_REG       argSq;
   long long     arg_signif, argSqSq;
   
 
@@ -90,7 +90,7 @@ void  poly_atan(REG *arg)
       /* convert the argument by an identity for atan */
       if ( (exponent >= -1) || (arg->sigh > 0xd413ccd0) )
        {
-         REG numerator, denom;
+         FPU_REG numerator, denom;
 
          recursions++;
 
@@ -183,7 +183,7 @@ void        poly_atan(REG *arg)
    i.e. have an exponent (not checked) of EXP_BIAS-1 but need not
    be normalized.
    This function adds 1.0 to the (assumed positive) argument. */
-void poly_add_1(REG *src)
+void poly_add_1(FPU_REG *src)
 {
 /* Rounding in a consistent direction produces better results
    for the use of this function in poly_atan. Simple truncation
index 3ca20c34feac3afd6b939b2070781b67f3c4468f..193c3e40ceb945801936ecd547f2a91a89195dff 100644 (file)
@@ -1,7 +1,7 @@
 /*---------------------------------------------------------------------------+
  |  poly_l2.c                                                                |
  |                                                                           |
- | Compute the base 2 logarithm of a REG, using a polynomial approximation.  |
+ | Compute the base 2 log of a FPU_REG, using a polynomial approximation.    |
  |                                                                           |
  | Copyright (C) 1992    W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
  |                       Australia.  E-mail apm233m@vaxc.cc.monash.edu.au    |
@@ -38,13 +38,13 @@ static unsigned short       lterms[HIPOWER][4] =
 /*--- poly_l2() -------------------------------------------------------------+
  |   Base 2 logarithm by a polynomial approximation.                         |
  +---------------------------------------------------------------------------*/
-void   poly_l2(REG *arg, REG *result)
+void   poly_l2(FPU_REG *arg, FPU_REG *result)
 {
   short                  exponent;
   char           zero;         /* flag for an Xx == 0 */
   unsigned short  bits, shift;
   long long       Xsq;
-  REG            accum, denom, num, Xx;
+  FPU_REG        accum, denom, num, Xx;
 
 
   exponent = arg->exp - EXP_BIAS;
@@ -96,7 +96,7 @@ void  poly_l2(REG *arg, REG *result)
       /* If the exponent is zero, then we would lose precision by
         sticking to fixed point computation here */
       /* We need to re-compute Xx because of loss of precision. */
-      REG     lXx;
+      FPU_REG   lXx;
       char     sign;
       
       sign = accum.sign;
@@ -137,7 +137,6 @@ void        poly_l2(REG *arg, REG *result)
 
          reg_u_mul(&lXx, &accum, &accum);
          accum.exp += - EXP_BIAS + 1;
-/*       normalize(&accum); ********/
 
          reg_u_add(&lXx, &accum, result);
          
@@ -222,11 +221,11 @@ void      poly_l2(REG *arg, REG *result)
  |   Base 2 logarithm by a polynomial approximation.                         |
  |   log2(x+1)                                                               |
  +---------------------------------------------------------------------------*/
-int    poly_l2p1(REG *arg, REG *result)
+int    poly_l2p1(FPU_REG *arg, FPU_REG *result)
 {
   char         sign = 0;
   long long     Xsq;
-  REG          arg_pl1, denom, accum, local_arg, poly_arg;
+  FPU_REG              arg_pl1, denom, accum, local_arg, poly_arg;
 
 
   sign = arg->sign;
index 8ec11751da99fdc3eee8ae8de91359225e1ae9ed..91a9cf320a9d3bf7fe40fbcd356a6b19e37b1c99 100644 (file)
@@ -38,10 +38,10 @@ static unsigned short       negterms[HIPOWER][4] =
 /*--- poly_sine() -----------------------------------------------------------+
  |                                                                           |
  +---------------------------------------------------------------------------*/
-void   poly_sine(REG *arg, REG *result)
+void   poly_sine(FPU_REG *arg, FPU_REG *result)
 {
   short        exponent;
-  REG  Xx, Xx2, Xx4, accum, negaccum;
+  FPU_REG      Xx, Xx2, Xx4, accum, negaccum;
   
   
   exponent = arg->exp - EXP_BIAS;
@@ -129,18 +129,22 @@ void      poly_sine(REG *arg, REG *result)
          )
        {
 #ifdef DEBUGGING
+         RE_ENTRANT_CHECK_OFF
          printk("\nEXP=%d, MS=%08x, LS=%08x\n", result->exp,
                 result->sigh, result->sigl);
+         RE_ENTRANT_CHECK_ON
 #endif DEBUGGING
          EXCEPTION(EX_INTERNAL|0x103);
        }
       
 #ifdef DEBUGGING
+      RE_ENTRANT_CHECK_OFF
       printk("\n***CORRECTING ILLEGAL RESULT*** in poly_sin() computation\n");
       printk("EXP=%d, MS=%08x, LS=%08x\n", result->exp,
             result->sigh, result->sigl);
+      RE_ENTRANT_CHECK_ON
 #endif DEBUGGING
-      
+
       result->sigl = 0;        /* Truncate the result to 1.00 */
     }
 }
index 2f8fb41d93f8cd61be642a282720f1382196aa36..0129f5b3e8d5f0f9ba92022932ba6675ed52c71f 100644 (file)
@@ -1,7 +1,7 @@
 /*---------------------------------------------------------------------------+
  |  poly_tan.c                                                               |
  |                                                                           |
- | Compute the tan of a REG, using a polynomial approximation.               |
+ | Compute the tan of a FPU_REG, using a polynomial approximation.           |
  |                                                                           |
  | Copyright (C) 1992    W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
  |                       Australia.  E-mail apm233m@vaxc.cc.monash.edu.au    |
@@ -47,12 +47,12 @@ static unsigned short       evennegterms[HIPOWERen][4] =
 /*--- poly_tan() ------------------------------------------------------------+
  |                                                                           |
  +---------------------------------------------------------------------------*/
-void   poly_tan(REG *arg, REG *y_reg)
+void   poly_tan(FPU_REG *arg, FPU_REG *y_reg)
 {
   char         invert = 0;
   short                exponent;
-  REG           odd_poly, even_poly, pos_poly, neg_poly;
-  REG           argSq;
+  FPU_REG       odd_poly, even_poly, pos_poly, neg_poly;
+  FPU_REG       argSq;
   long long     arg_signif, argSqSq;
   
 
index bd801bb3ccf6f769902a743b5a522562d2e37da2..6167fe615b6fa49451bebe2eee6bf4bfdde54ee4 100644 (file)
@@ -10,8 +10,8 @@
  +---------------------------------------------------------------------------*/
 
 /*---------------------------------------------------------------------------+
- | For each function, the destination may be any REG, including one of the   |
- | source REGs.                                                              |
+ | For each function, the destination may be any FPU_REG, including one of   |
+ | the source FPU_REGs.                                                      |
  +---------------------------------------------------------------------------*/
 
 #include "exception.h"
@@ -20,7 +20,7 @@
 
 
 
-void reg_add(REG *a, REG *b, REG *dest)
+void reg_add(FPU_REG *a, FPU_REG *b, FPU_REG *dest)
 {
   int diff;
   
@@ -85,7 +85,7 @@ void reg_add(REG *a, REG *b, REG *dest)
 
 
 /* Subtract b from a.  (a-b) -> dest */
-void reg_sub(REG *a, REG *b, REG *dest)
+void reg_sub(FPU_REG *a, FPU_REG *b, FPU_REG *dest)
 {
   int diff;
 
index 0cb557af8292aa69bce6f0128cb522ebacc923c4..5a5172a8a1b91f767c0ce1e0d4daca71e1bf9f6f 100644 (file)
@@ -10,7 +10,7 @@
  +---------------------------------------------------------------------------*/
 
 /*---------------------------------------------------------------------------+
- | compare() is the core REG comparison function                             |
+ | compare() is the core FPU_REG comparison function                         |
  +---------------------------------------------------------------------------*/
 
 #include "fpu_system.h"
 #include "status_w.h"
 
 
-int compare(REG *b)
+int compare(FPU_REG *b)
 {
   int diff;
 
-  if ( st0_ptr->tag | b->tag )
+  if ( FPU_st0_ptr->tag | b->tag )
     {
-      if ( st0_ptr->tag == TW_Zero )
+      if ( FPU_st0_ptr->tag == TW_Zero )
        {
          if ( b->tag == TW_Zero ) return COMP_A_EQ_B;
          if ( b->tag == TW_Valid )
@@ -35,29 +35,29 @@ int compare(REG *b)
        }
       else if ( b->tag == TW_Zero )
        {
-         if ( st0_ptr->tag == TW_Valid )
+         if ( FPU_st0_ptr->tag == TW_Valid )
            {
-             return (st0_ptr->sign == SIGN_POS) ? COMP_A_GT_B : COMP_A_LT_B ;
+             return (FPU_st0_ptr->sign == SIGN_POS) ? COMP_A_GT_B : COMP_A_LT_B ;
            }
        }
 
-      if ( st0_ptr->tag == TW_Infinity )
+      if ( FPU_st0_ptr->tag == TW_Infinity )
        {
          if ( (b->tag == TW_Valid) || (b->tag == TW_Zero) )
            {
-             return (st0_ptr->sign == SIGN_POS) ? COMP_A_GT_B : COMP_A_LT_B;
+             return (FPU_st0_ptr->sign == SIGN_POS) ? COMP_A_GT_B : COMP_A_LT_B;
            }
          else if ( b->tag == TW_Infinity )
            {
              /* The 80486 book says that infinities can be equal! */
-             return (st0_ptr->sign == b->sign) ? COMP_A_EQ_B :
-               ((st0_ptr->sign == SIGN_POS) ? COMP_A_GT_B : COMP_A_LT_B);
+             return (FPU_st0_ptr->sign == b->sign) ? COMP_A_EQ_B :
+               ((FPU_st0_ptr->sign == SIGN_POS) ? COMP_A_GT_B : COMP_A_LT_B);
            }
          /* Fall through to the NaN code */
        }
       else if ( b->tag == TW_Infinity )
        {
-         if ( (st0_ptr->tag == TW_Valid) || (st0_ptr->tag == TW_Zero) )
+         if ( (FPU_st0_ptr->tag == TW_Valid) || (FPU_st0_ptr->tag == TW_Zero) )
            {
              return (b->sign == SIGN_POS) ? COMP_A_LT_B : COMP_A_GT_B;
            }
@@ -66,9 +66,9 @@ int compare(REG *b)
 
       /* The only possibility now should be that one of the arguments
         is a NaN */
-      if ( (st0_ptr->tag == TW_NaN) || (b->tag == TW_NaN) )
+      if ( (FPU_st0_ptr->tag == TW_NaN) || (b->tag == TW_NaN) )
        {
-         if ( ((st0_ptr->tag == TW_NaN) && !(st0_ptr->sigh & 0x40000000))
+         if ( ((FPU_st0_ptr->tag == TW_NaN) && !(FPU_st0_ptr->sigh & 0x40000000))
              || ((b->tag == TW_NaN) && !(b->sigh & 0x40000000)) )
            /* At least one arg is a signaling NaN */
            return COMP_NOCOMP | COMP_SNAN | COMP_NAN;
@@ -81,25 +81,25 @@ int compare(REG *b)
     }
   
 #ifdef PARANOID
-  if (!(st0_ptr->sigh & 0x80000000)) EXCEPTION(EX_Invalid);
+  if (!(FPU_st0_ptr->sigh & 0x80000000)) EXCEPTION(EX_Invalid);
   if (!(b->sigh & 0x80000000)) EXCEPTION(EX_Invalid);
 #endif PARANOID
   
-  if (st0_ptr->sign != b->sign)
-    return (st0_ptr->sign == SIGN_POS) ? COMP_A_GT_B : COMP_A_LT_B;
+  if (FPU_st0_ptr->sign != b->sign)
+    return (FPU_st0_ptr->sign == SIGN_POS) ? COMP_A_GT_B : COMP_A_LT_B;
   
-  diff = st0_ptr->exp - b->exp;
+  diff = FPU_st0_ptr->exp - b->exp;
   if ( diff == 0 )
     {
-      diff = st0_ptr->sigh - b->sigh;
+      diff = FPU_st0_ptr->sigh - b->sigh;
       if ( diff == 0 )
-       diff = st0_ptr->sigl - b->sigl;
+       diff = FPU_st0_ptr->sigl - b->sigl;
     }
 
   if ( diff > 0 )
-    return (st0_ptr->sign == SIGN_POS) ? COMP_A_GT_B : COMP_A_LT_B ;
+    return (FPU_st0_ptr->sign == SIGN_POS) ? COMP_A_GT_B : COMP_A_LT_B ;
   if ( diff < 0 )
-    return (st0_ptr->sign == SIGN_POS) ? COMP_A_LT_B : COMP_A_GT_B ;
+    return (FPU_st0_ptr->sign == SIGN_POS) ? COMP_A_LT_B : COMP_A_GT_B ;
   return COMP_A_EQ_B;
 
 }
@@ -235,7 +235,7 @@ void fcompp()
   if (FPU_rm != 1)
     return Un_impl();
   compare_st_st(1);
-  pop();
+  pop(); FPU_st0_ptr = &st(0);
   pop();
 }
 
@@ -261,7 +261,7 @@ void fucompp()
   if (FPU_rm == 1)
     {
       compare_u_st_st(1);
-      pop();
+      pop(); FPU_st0_ptr = &st(0);
       pop();
     }
   else
index e8b035028957d91e53ae5ebbb3d7c69f903d82bd..aadf5890e0f31bd0048b806387318a088eda825d 100644 (file)
@@ -1,7 +1,7 @@
 /*---------------------------------------------------------------------------+
  |  reg_constant.c                                                           |
  |                                                                           |
- | All of the constant REGs                                                  |
+ | All of the constant FPU_REGs                                              |
  |                                                                           |
  | Copyright (C) 1992    W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
  |                       Australia.  E-mail apm233m@vaxc.cc.monash.edu.au    |
 #include "reg_constant.h"
 
 
-struct reg CONST_1    = { SIGN_POS, TW_Valid, EXP_BIAS,
+FPU_REG CONST_1    = { SIGN_POS, TW_Valid, EXP_BIAS,
                            0x00000000, 0x80000000 };
-struct reg CONST_2    = { SIGN_POS, TW_Valid, EXP_BIAS+1,
+FPU_REG CONST_2    = { SIGN_POS, TW_Valid, EXP_BIAS+1,
                            0x00000000, 0x80000000 };
-struct reg CONST_HALF = { SIGN_POS, TW_Valid, EXP_BIAS-1,
+FPU_REG CONST_HALF = { SIGN_POS, TW_Valid, EXP_BIAS-1,
                            0x00000000, 0x80000000 };
-struct reg CONST_L2T  = { SIGN_POS, TW_Valid, EXP_BIAS+1,
+FPU_REG CONST_L2T  = { SIGN_POS, TW_Valid, EXP_BIAS+1,
                            0xcd1b8afe, 0xd49a784b };
-struct reg CONST_L2E  = { SIGN_POS, TW_Valid, EXP_BIAS,
+FPU_REG CONST_L2E  = { SIGN_POS, TW_Valid, EXP_BIAS,
                            0x5c17f0bc, 0xb8aa3b29 };
-struct reg CONST_PI   = { SIGN_POS, TW_Valid, EXP_BIAS+1,
+FPU_REG CONST_PI   = { SIGN_POS, TW_Valid, EXP_BIAS+1,
                            0x2168c235, 0xc90fdaa2 };
-struct reg CONST_PI2  = { SIGN_POS, TW_Valid, EXP_BIAS,
+FPU_REG CONST_PI2  = { SIGN_POS, TW_Valid, EXP_BIAS,
                            0x2168c235, 0xc90fdaa2 };
-struct reg CONST_PI4  = { SIGN_POS, TW_Valid, EXP_BIAS-1,
+FPU_REG CONST_PI4  = { SIGN_POS, TW_Valid, EXP_BIAS-1,
                            0x2168c235, 0xc90fdaa2 };
-struct reg CONST_LG2  = { SIGN_POS, TW_Valid, EXP_BIAS-2,
+FPU_REG CONST_LG2  = { SIGN_POS, TW_Valid, EXP_BIAS-2,
                            0xfbcff799, 0x9a209a84 };
-struct reg CONST_LN2  = { SIGN_POS, TW_Valid, EXP_BIAS-1,
+FPU_REG CONST_LN2  = { SIGN_POS, TW_Valid, EXP_BIAS-1,
                            0xd1cf79ac, 0xb17217f7 };
 
 /* Only the sign (and tag) is used in internal zeroes */
-struct reg CONST_Z    = { SIGN_POS, TW_Zero, 0,          0x0,        0x0 };
+FPU_REG CONST_Z    = { SIGN_POS, TW_Zero, 0,          0x0,        0x0 };
 
 /* Only the sign and significand (and tag) are used in internal NaNs */
 /* The 80486 never generates one of these 
-struct reg CONST_SNAN = { SIGN_POS, TW_NaN, EXP_OVER, 0x00000001, 0x80000000 };
+FPU_REG CONST_SNAN = { SIGN_POS, TW_NaN, EXP_OVER, 0x00000001, 0x80000000 };
  */
 /* This is the real indefinite QNaN */
-struct reg CONST_QNaN = { SIGN_NEG, TW_NaN, EXP_OVER, 0x00000000, 0xC0000000 };
+FPU_REG CONST_QNaN = { SIGN_NEG, TW_NaN, EXP_OVER, 0x00000000, 0xC0000000 };
 
 /* Only the sign (and tag) is used in internal infinities */
-struct reg CONST_INF  = { SIGN_POS, TW_Infinity, EXP_OVER, 0x00000000, 0x80000000 };
+FPU_REG CONST_INF  = { SIGN_POS, TW_Infinity, EXP_OVER, 0x00000000, 0x80000000 };
 
 
 
-static void fld_const(REG *c)
+static void fld_const(FPU_REG *c)
 {
-  REG *st_new_ptr;
+  FPU_REG *st_new_ptr;
 
   if ( STACK_OVERFLOW )
     {
@@ -61,7 +61,7 @@ static void fld_const(REG *c)
       return;
     }
   push();
-  reg_move(c, st0_ptr);
+  reg_move(c, FPU_st0_ptr);
   status_word &= ~SW_C1;
 }
 
index 4297588320d1dd8ae22c5fd9eefa5a59b10b3670..a039bc69b0fe024d8a6709cda5c3a72202138015 100644 (file)
 
 #include "fpu_emu.h"
 
-extern REG CONST_1;
-extern REG CONST_2;
-extern REG CONST_HALF;
-extern REG CONST_L2T;
-extern REG CONST_L2E;
-extern REG CONST_PI;
-extern REG CONST_PI2;
-extern REG CONST_PI4;
-extern REG CONST_LG2;
-extern REG CONST_LN2;
-extern REG CONST_Z;
-extern REG CONST_PINF;
-extern REG CONST_INF;
-extern REG CONST_MINF;
-extern REG CONST_QNaN;
+extern FPU_REG CONST_1;
+extern FPU_REG CONST_2;
+extern FPU_REG CONST_HALF;
+extern FPU_REG CONST_L2T;
+extern FPU_REG CONST_L2E;
+extern FPU_REG CONST_PI;
+extern FPU_REG CONST_PI2;
+extern FPU_REG CONST_PI4;
+extern FPU_REG CONST_LG2;
+extern FPU_REG CONST_LN2;
+extern FPU_REG CONST_Z;
+extern FPU_REG CONST_PINF;
+extern FPU_REG CONST_INF;
+extern FPU_REG CONST_MINF;
+extern FPU_REG CONST_QNaN;
 
 #endif _REG_CONSTANT_H_
-
index 3d5a4aa84465573bb41838af0350e34a03d6e872..46979b5ae67fbb85c46744b9346c4bb494fe7117 100644 (file)
@@ -2,13 +2,13 @@
 /*---------------------------------------------------------------------------+
  |  reg_div.S                                                                |
  |                                                                           |
- | Divide one REG by another and put the result in a destination REG.        |
+ | Divide one FPU_REG by another and put the result in a destination FPU_REG.|
  |                                                                           |
  | Copyright (C) 1992    W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
  |                       Australia.  E-mail apm233m@vaxc.cc.monash.edu.au    |
  |                                                                           |
  | Call from C as:                                                           |
- |   void reg_div(REG *a, REG *b, REG *dest)                                 |
+ |   void reg_div(FPU_REG *a, FPU_REG *b, FPU_REG *dest)                     |
  |                                                                           |
  +---------------------------------------------------------------------------*/
 
index 48093861fee60dff5011fe91d1e3cb5bc6361685..9028bd467c409e1f92b3f190f8c77522c3548673 100644 (file)
@@ -1,7 +1,7 @@
 /*---------------------------------------------------------------------------+
  |  reg_ld_str.c                                                             |
  |                                                                           |
- | All of the functions which transfer data between user memory and REGs.    |
+ | All of the functions which transfer data between user memory and FPU_REGs.|
  |                                                                           |
  | Copyright (C) 1992    W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
  |                       Australia.  E-mail apm233m@vaxc.cc.monash.edu.au    |
@@ -9,6 +9,13 @@
  |                                                                           |
  +---------------------------------------------------------------------------*/
 
+/*---------------------------------------------------------------------------+
+ | Note:                                                                     |
+ |    The file contains code which accesses user memory.                     |
+ |    Emulator static data may change when user memory is accessed, due to   |
+ |    other processes using the emulator while swapping is in progress.      |
+ +---------------------------------------------------------------------------*/
+
 #include <asm/segment.h>
 
 #include "fpu_system.h"
 #define SINGLE_Emin (-126)       /* smallest valid exponent */
 
 
-REG FPU_loaded_data;
+FPU_REG FPU_loaded_data;
 
 
 /* Get a long double from user memory */
 void reg_load_extended(void)
 {
   long double *s = (long double *)FPU_data_address;
-  FPU_loaded_data.sigl = get_fs_long((unsigned long *) s);
-  FPU_loaded_data.sigh = get_fs_long(1 + (unsigned long *) s);
-  FPU_loaded_data.exp = get_fs_word(4 + (unsigned short *) s);
+  unsigned long sigl, sigh, exp;
+
+  RE_ENTRANT_CHECK_OFF
+  /* Use temporary variables here because FPU_loaded data is
+     static and hence re-entrancy problems can arise */
+  sigl = get_fs_long((unsigned long *) s);
+  sigh = get_fs_long(1 + (unsigned long *) s);
+  exp = get_fs_word(4 + (unsigned short *) s);
+  RE_ENTRANT_CHECK_ON
+
+  FPU_loaded_data.sigl = sigl;
+  FPU_loaded_data.sigh = sigh;
+  FPU_loaded_data.exp = exp;
+
   if (FPU_loaded_data.exp & 0x8000)
     FPU_loaded_data.sign = SIGN_NEG;
   else
@@ -86,9 +104,13 @@ void reg_load_extended(void)
 void reg_load_double(void)
 {
   double *dfloat = (double *)FPU_data_address;
-  unsigned m64 = get_fs_long(1 + (unsigned long *) dfloat);
-  unsigned l64 = get_fs_long((unsigned long *) dfloat);
   int exp;
+  unsigned m64, l64;
+
+  RE_ENTRANT_CHECK_OFF
+  m64 = get_fs_long(1 + (unsigned long *) dfloat);
+  l64 = get_fs_long((unsigned long *) dfloat);
+  RE_ENTRANT_CHECK_ON
 
   if (m64 & 0x80000000)
     FPU_loaded_data.sign = SIGN_NEG;
@@ -157,9 +179,13 @@ void reg_load_double(void)
 void reg_load_single(void)
 {
   float *single = (float *)FPU_data_address;
-  unsigned m32 = get_fs_long((unsigned long *) single);
+  unsigned m32;
   int exp;
 
+  RE_ENTRANT_CHECK_OFF
+  m32 = get_fs_long((unsigned long *) single);
+  RE_ENTRANT_CHECK_ON
+
   if (m32 & 0x80000000)
     FPU_loaded_data.sign = SIGN_NEG;
   else
@@ -220,8 +246,11 @@ void reg_load_int64(void)
   long long *_s = (long long *)FPU_data_address;
   int e;
   long long s;
+
+  RE_ENTRANT_CHECK_OFF
   ((unsigned long *)&s)[0] = get_fs_long((unsigned long *) _s);
   ((unsigned long *)&s)[1] = get_fs_long(1 + (unsigned long *) _s);
+  RE_ENTRANT_CHECK_ON
 
   if (s == 0)
     { reg_move(&CONST_Z, &FPU_loaded_data); return; }
@@ -246,10 +275,13 @@ void reg_load_int64(void)
 void reg_load_int32(void)
 {
   long *_s = (long *)FPU_data_address;
-  long s = (long)get_fs_long((unsigned long *) _s);
-
+  long s;
   int e;
 
+  RE_ENTRANT_CHECK_OFF
+  s = (long)get_fs_long((unsigned long *) _s);
+  RE_ENTRANT_CHECK_ON
+
   if (s == 0)
     { reg_move(&CONST_Z, &FPU_loaded_data); return; }
 
@@ -274,9 +306,11 @@ void reg_load_int32(void)
 void reg_load_int16(void)
 {
   short *_s = (short *)FPU_data_address;
-  int s = (int)get_fs_word((unsigned short *) _s);
+  int s, e;
 
-  int e;
+  RE_ENTRANT_CHECK_OFF
+  s = (int)get_fs_word((unsigned short *) _s);
+  RE_ENTRANT_CHECK_ON
 
   if (s == 0)
     { reg_move(&CONST_Z, &FPU_loaded_data); return; }
@@ -310,14 +344,28 @@ void reg_load_bcd(void)
   for ( pos = 8; pos >= 0; pos--)
     {
       l *= 10;
+      RE_ENTRANT_CHECK_OFF
       bcd = (unsigned char)get_fs_byte((unsigned char *) s+pos);
+      RE_ENTRANT_CHECK_ON
       l += bcd >> 4;
       l *= 10;
       l += bcd & 0x0f;
     }
+  
+  /* Finish all access to user memory before putting stuff into
+     the static FPU_loaded_data */
+  RE_ENTRANT_CHECK_OFF
+  FPU_loaded_data.sign =
+    ((unsigned char)get_fs_byte((unsigned char *) s+9)) & 0x80 ?
+      SIGN_NEG : SIGN_POS;
+  RE_ENTRANT_CHECK_ON
 
   if (l == 0)
-    { reg_move(&CONST_Z, &FPU_loaded_data); }
+    {
+      char sign = FPU_loaded_data.sign;
+      reg_move(&CONST_Z, &FPU_loaded_data);
+      FPU_loaded_data.sign = sign;
+    }
   else
     {
       *((long long *)&FPU_loaded_data.sigl) = l;
@@ -325,10 +373,6 @@ void reg_load_bcd(void)
       FPU_loaded_data.tag = TW_Valid;
       normalize(&FPU_loaded_data);
     }
-  
-  FPU_loaded_data.sign =
-    ((unsigned char)get_fs_byte((unsigned char *) s+9)) & 0x80 ?
-      SIGN_NEG : SIGN_POS;
 }
 
 /*===========================================================================*/
@@ -337,12 +381,12 @@ void reg_load_bcd(void)
 int reg_store_extended(void)
 {
   long double *d = (long double *)FPU_data_address;
-  short e;
+  long e = FPU_st0_ptr->exp - EXP_BIAS + EXTENDED_Ebias;
+  unsigned short sign = FPU_st0_ptr->sign*0x8000;
+  unsigned long ls, ms;
 
-  verify_area(d,10);
-  e = st0_ptr->exp - EXP_BIAS + EXTENDED_Ebias;
 
-  if ( st0_ptr->tag == TW_Valid )
+  if ( FPU_st0_tag == TW_Valid )
     {
       if ( e >= 0x7fff )
        {
@@ -351,8 +395,8 @@ int reg_store_extended(void)
          if ( control_word & EX_Overflow )
            {
              /* Overflow to infinity */
-             put_fs_long(0, (unsigned long *) d);
-             put_fs_long(0x80000000, 1 + (unsigned long *) d);
+             ls = 0;
+             ms = 0x80000000;
              e = 0x7fff;
            }
          else
@@ -363,20 +407,20 @@ int reg_store_extended(void)
          if ( e == 0 )
            {
              EXCEPTION(EX_Denormal);  /* Pseudo de-normal */
-             put_fs_long(st0_ptr->sigl, (unsigned long *) d);
-             put_fs_long(st0_ptr->sigh, 1 + (unsigned long *) d);
+             ls = FPU_st0_ptr->sigl;
+             ms = FPU_st0_ptr->sigh;
            }
          else if ( e > -64 )
            {
              /* Make a de-normal */
-             REG tmp;
+             FPU_REG tmp;
              EXCEPTION(EX_Denormal);  /* De-normal */
-             reg_move(st0_ptr, &tmp);
+             reg_move(FPU_st0_ptr, &tmp);
              tmp.exp += -EXTENDED_Emin + 64;  /* largest exp to be 63 */
              round_to_int(&tmp);
              e = 0;
-             put_fs_long(tmp.sigl, (unsigned long *) d);
-             put_fs_long(tmp.sigh, 1 + (unsigned long *) d);
+             ls = tmp.sigl;
+             ms = tmp.sigh;
            }
          else
            {
@@ -385,8 +429,8 @@ int reg_store_extended(void)
              if ( control_word & EX_Underflow )
                {
                  /* Underflow to zero */
-                 put_fs_long(0, (unsigned long *) d);
-                 put_fs_long(0, 1 + (unsigned long *) d);
+                 ls = 0;
+                 ms = 0;
                  e = 0;
                }
              else
@@ -395,29 +439,28 @@ int reg_store_extended(void)
        }
       else
        {
-         put_fs_long(st0_ptr->sigl, (unsigned long *) d);
-         put_fs_long(st0_ptr->sigh, 1 + (unsigned long *) d);
+         ls = FPU_st0_ptr->sigl;
+         ms = FPU_st0_ptr->sigh;
        }
     }
-  else if ( st0_ptr->tag == TW_Zero )
+  else if ( FPU_st0_tag == TW_Zero )
     {
-      put_fs_long(0, (unsigned long *) d);
-      put_fs_long(0, 1 + (unsigned long *) d);
+      ls = ms = 0;
       e = 0;
     }
-  else if ( st0_ptr->tag == TW_Infinity )
+  else if ( FPU_st0_tag == TW_Infinity )
     {
-      put_fs_long(0, (unsigned long *) d);
-      put_fs_long(0x80000000, 1 + (unsigned long *) d);
+      ls = 0;
+      ms = 0x80000000;
       e = 0x7fff;
     }
-  else if ( st0_ptr->tag == TW_NaN )
+  else if ( FPU_st0_tag == TW_NaN )
     {
-      put_fs_long(st0_ptr->sigl, (unsigned long *) d);
-      put_fs_long(st0_ptr->sigh, 1 + (unsigned long *) d);
+      ls = FPU_st0_ptr->sigl;
+      ms = FPU_st0_ptr->sigh;
       e = 0x7fff;
     }
-  else if ( st0_ptr->tag == TW_Empty )
+  else if ( FPU_st0_tag == TW_Empty )
     {
       /* Empty register (stack underflow) */
       EXCEPTION(EX_StackUnder);
@@ -425,10 +468,9 @@ int reg_store_extended(void)
        {
          /* The masked response */
          /* Put out the QNaN indefinite */
-         put_fs_long(0, (unsigned long *) d);
-         put_fs_long(0xc0000000, 1 + (unsigned long *) d);
-         put_fs_word(0xffff, 4 + (short *) d);
-         return 1;
+         ls = 0;
+         ms = 0xc0000000;
+         e = 0xffff;
        }
       else
        return 0;
@@ -439,10 +481,15 @@ int reg_store_extended(void)
       EXCEPTION(EX_Invalid);
       /* Store a NaN */
       e = 0x7fff;
-      put_fs_long(1, (unsigned long *) d);
-      put_fs_long(0x80000000, 1 + (unsigned long *) d);
+      ls = 1;
+      ms = 0x80000000;
     }
-  put_fs_word(e + st0_ptr->sign*0x8000, 4 + (short *) d);
+  RE_ENTRANT_CHECK_OFF
+  verify_area(d,10);
+  put_fs_long(ls, (unsigned long *) d);
+  put_fs_long(ms, 1 + (unsigned long *) d);
+  put_fs_word((unsigned short)e | sign, 4 + (short *) d);
+  RE_ENTRANT_CHECK_ON
 
   return 1;
 
@@ -455,20 +502,19 @@ int reg_store_double(void)
   double *dfloat = (double *)FPU_data_address;
   unsigned long l[2];
 
-  verify_area((void *)dfloat,8);
 
-  if (st0_ptr->tag == TW_Valid)
+  if (FPU_st0_tag == TW_Valid)
     {
       /* Rounding can get a little messy.. */
-      int exp = st0_ptr->exp - EXP_BIAS;
-      int increment = ((st0_ptr->sigl & 0x7ff) > 0x400) |      /* nearest */
-       ((st0_ptr->sigl & 0xc00) == 0xc00);             /* odd -> even */
+      int exp = FPU_st0_ptr->exp - EXP_BIAS;
+      int increment = ((FPU_st0_ptr->sigl & 0x7ff) > 0x400) |  /* nearest */
+       ((FPU_st0_ptr->sigl & 0xc00) == 0xc00);                 /* odd -> even */
       if ( increment )
        {
-         if ( st0_ptr->sigl >= 0xfffff800 )
+         if ( FPU_st0_ptr->sigl >= 0xfffff800 )
            {
              /* the sigl part overflows */
-             if ( st0_ptr->sigh == 0xffffffff )
+             if ( FPU_st0_ptr->sigh == 0xffffffff )
                {
                  /* The sigh part overflows */
                  l[0] = l[1] = 0;
@@ -477,22 +523,22 @@ int reg_store_double(void)
              else
                {
                  /* No overflow of sigh will happen, can safely increment */
-                 l[0] = (st0_ptr->sigh+1) << 21;
-                 l[1] = (((st0_ptr->sigh+1) >> 11) & 0xfffff);
+                 l[0] = (FPU_st0_ptr->sigh+1) << 21;
+                 l[1] = (((FPU_st0_ptr->sigh+1) >> 11) & 0xfffff);
                }
            }
          else
            {
              /* We only need to increment sigl */
-             l[0] = ((st0_ptr->sigl+0x800) >> 11) | (st0_ptr->sigh << 21);
-             l[1] = ((st0_ptr->sigh >> 11) & 0xfffff);
+             l[0] = ((FPU_st0_ptr->sigl+0x800) >> 11) | (FPU_st0_ptr->sigh << 21);
+             l[1] = ((FPU_st0_ptr->sigh >> 11) & 0xfffff);
            }
        }
       else
        {
          /* No increment required */
-         l[0] = (st0_ptr->sigl >> 11) | (st0_ptr->sigh << 21);
-         l[1] = ((st0_ptr->sigh >> 11) & 0xfffff);
+         l[0] = (FPU_st0_ptr->sigl >> 11) | (FPU_st0_ptr->sigh << 21);
+         l[1] = ((FPU_st0_ptr->sigh >> 11) & 0xfffff);
        }
 
       if ( exp > DOUBLE_Emax )
@@ -513,9 +559,9 @@ int reg_store_double(void)
          if ( exp > DOUBLE_Emin-53 )
            {
              /* Make a de-normal */
-             REG tmp;
+             FPU_REG tmp;
              EXCEPTION(EX_Denormal);
-             reg_move(st0_ptr, &tmp);
+             reg_move(FPU_st0_ptr, &tmp);
              tmp.exp += -DOUBLE_Emin + 52;  /* largest exp to be 51 */
              round_to_int(&tmp);
              l[0] = tmp.sigl;
@@ -540,21 +586,21 @@ int reg_store_double(void)
          l[1] |= (((exp+DOUBLE_Ebias) & 0x7ff) << 20);
        }
     }
-  else if (st0_ptr->tag == TW_Zero)
+  else if (FPU_st0_tag == TW_Zero)
     {
       /* Number is zero */
       l[0] = l[1] = 0;
     }
-  else if (st0_ptr->tag == TW_Infinity)
+  else if (FPU_st0_tag == TW_Infinity)
     {
       l[0] = 0;
       l[1] = 0x7ff00000;
     }
-  else if (st0_ptr->tag == TW_NaN)
+  else if (FPU_st0_tag == TW_NaN)
     {
-      /* See if we can get a valid NaN from the REG */
-      l[0] = (st0_ptr->sigl >> 11) | (st0_ptr->sigh << 21);
-      l[1] = ((st0_ptr->sigh >> 11) & 0xfffff);
+      /* See if we can get a valid NaN from the FPU_REG */
+      l[0] = (FPU_st0_ptr->sigl >> 11) | (FPU_st0_ptr->sigh << 21);
+      l[1] = ((FPU_st0_ptr->sigh >> 11) & 0xfffff);
       if ( !(l[0] | l[1]) )
        {
          /* This case does not seem to be handled by the 80486 specs */
@@ -564,7 +610,7 @@ int reg_store_double(void)
        }
       l[1] |= 0x7ff00000;
     }
-  else if ( st0_ptr->tag == TW_Empty )
+  else if ( FPU_st0_tag == TW_Empty )
     {
       /* Empty register (stack underflow) */
       EXCEPTION(EX_StackUnder);
@@ -573,24 +619,30 @@ int reg_store_double(void)
          /* The masked response */
          /* Put out the QNaN indefinite */
 put_indefinite:
+         RE_ENTRANT_CHECK_OFF
+         verify_area((void *)dfloat,8);
          put_fs_long(0, (unsigned long *) dfloat);
          put_fs_long(0xfff80000, 1 + (unsigned long *) dfloat);
+         RE_ENTRANT_CHECK_ON
          return 1;
        }
       else
        return 0;
     }
-  else if (st0_ptr->tag == TW_Denormal)
+  else if (FPU_st0_tag == TW_Denormal)
     {
       /* Extended real -> double real will always underflow */
       l[0] = l[1] = 0;
       EXCEPTION(EX_Underflow);
     }
-  if (st0_ptr->sign)
+  if (FPU_st0_ptr->sign)
     l[1] |= 0x80000000;
-  
+
+  RE_ENTRANT_CHECK_OFF
+  verify_area((void *)dfloat,8);
   put_fs_long(l[0], (unsigned long *)dfloat);
   put_fs_long(l[1], 1 + (unsigned long *)dfloat);
+  RE_ENTRANT_CHECK_ON
 
   return 1;
 
@@ -602,12 +654,11 @@ int reg_store_single(void)
 {
   float *single = (float *)FPU_data_address;
   long templ;
-  int exp = st0_ptr->exp - EXP_BIAS;
-  unsigned long sigh = st0_ptr->sigh;
+  int exp = FPU_st0_ptr->exp - EXP_BIAS;
+  unsigned long sigh = FPU_st0_ptr->sigh;
 
-  verify_area((void *)single,4);
 
-  if (st0_ptr->tag == TW_Valid)
+  if (FPU_st0_tag == TW_Valid)
     {
       if ( ((sigh & 0xff) > 0x80)           /* more than half */
          || ((sigh & 0x180) == 0x180) )    /* round to even */
@@ -642,9 +693,9 @@ int reg_store_single(void)
          if ( exp > SINGLE_Emin-24 )
            {
              /* Make a de-normal */
-             REG tmp;
+             FPU_REG tmp;
              EXCEPTION(EX_Denormal);
-             reg_move(st0_ptr, &tmp);
+             reg_move(FPU_st0_ptr, &tmp);
              tmp.exp += -SINGLE_Emin + 23;  /* largest exp to be 22 */
              round_to_int(&tmp);
              templ = tmp.sigl;
@@ -665,18 +716,18 @@ int reg_store_single(void)
       else
        templ |= ((exp+SINGLE_Ebias) & 0xff) << 23;
     }
-  else if (st0_ptr->tag == TW_Zero)
+  else if (FPU_st0_tag == TW_Zero)
     {
       templ = 0;
     }
-  else if (st0_ptr->tag == TW_Infinity)
+  else if (FPU_st0_tag == TW_Infinity)
     {
       templ = 0x7f800000;
     }
-  else if (st0_ptr->tag == TW_NaN)
+  else if (FPU_st0_tag == TW_NaN)
     {
-      /* See if we can get a valid NaN from the REG */
-      templ = st0_ptr->sigh >> 8;
+      /* See if we can get a valid NaN from the FPU_REG */
+      templ = FPU_st0_ptr->sigh >> 8;
       if ( !(templ & 0x3fffff) )
        {
          /* This case does not seem to be handled by the 80486 specs */
@@ -686,7 +737,7 @@ int reg_store_single(void)
        }
       templ |= 0x7f800000;
     }
-  else if ( st0_ptr->tag == TW_Empty )
+  else if ( FPU_st0_tag == TW_Empty )
     {
       /* Empty register (stack underflow) */
       EXCEPTION(EX_StackUnder);
@@ -695,13 +746,16 @@ int reg_store_single(void)
          /* The masked response */
          /* Put out the QNaN indefinite */
 put_indefinite:
+         RE_ENTRANT_CHECK_OFF
+         verify_area((void *)single,4);
          put_fs_long(0xffc00000, (unsigned long *) single);
+         RE_ENTRANT_CHECK_ON
          return 1;
        }
       else
        return 0;
     }
-  else if (st0_ptr->tag == TW_Denormal)
+  else if (FPU_st0_tag == TW_Denormal)
     {
       /* Extended real -> real will always underflow */
       templ = 0;
@@ -714,10 +768,13 @@ put_indefinite:
       return 0;
     }
 #endif
-  if (st0_ptr->sign)
+  if (FPU_st0_ptr->sign)
     templ |= 0x80000000;
 
+  RE_ENTRANT_CHECK_OFF
+  verify_area((void *)single,4);
   put_fs_long(templ,(unsigned long *) single);
+  RE_ENTRANT_CHECK_ON
 
   return 1;
 }
@@ -727,11 +784,10 @@ put_indefinite:
 int reg_store_int64(void)
 {
   long long *d = (long long *)FPU_data_address;
-  REG t;
+  FPU_REG t;
   long long tll;
 
-  verify_area((void *)d,8);
-  if ( st0_ptr->tag == TW_Empty )
+  if ( FPU_st0_tag == TW_Empty )
     {
       /* Empty register (stack underflow) */
       EXCEPTION(EX_StackUnder);
@@ -745,7 +801,7 @@ int reg_store_int64(void)
        return 0;
     }
 
-  reg_move(st0_ptr, &t);
+  reg_move(FPU_st0_ptr, &t);
   round_to_int(&t);
   ((long *)&tll)[0] = t.sigl;
   ((long *)&tll)[1] = t.sigh;
@@ -766,8 +822,11 @@ put_indefinite:
   else if (t.sign)
     tll = - tll;
 
+  RE_ENTRANT_CHECK_OFF
+  verify_area((void *)d,8);
   put_fs_long(((long *)&tll)[0],(unsigned long *) d);
   put_fs_long(((long *)&tll)[1],1 + (unsigned long *) d);
+  RE_ENTRANT_CHECK_ON
 
   return 1;
 }
@@ -777,11 +836,10 @@ put_indefinite:
 int reg_store_int32(void)
 {
   long *d = (long *)FPU_data_address;
-  REG t;
+  FPU_REG t;
   long tl;
 
-  verify_area(d,4);
-  if ( st0_ptr->tag == TW_Empty )
+  if ( FPU_st0_tag == TW_Empty )
     {
       /* Empty register (stack underflow) */
       EXCEPTION(EX_StackUnder);
@@ -789,14 +847,17 @@ int reg_store_int32(void)
        {
          /* The masked response */
          /* Put out the QNaN indefinite */
+         RE_ENTRANT_CHECK_OFF
+         verify_area(d,4);
          put_fs_long(0x80000000, (unsigned long *) d);
+         RE_ENTRANT_CHECK_ON
          return 1;
        }
       else
        return 0;
     }
 
-  reg_move(st0_ptr, &t);
+  reg_move(FPU_st0_ptr, &t);
   round_to_int(&t);
   if (t.sigh || (t.sigl & 0x80000000))
     {
@@ -811,9 +872,12 @@ int reg_store_int32(void)
        return 0;
     }
   else
-    tl = st0_ptr->sign ? -t.sigl : t.sigl;
+    tl = FPU_st0_ptr->sign ? -t.sigl : t.sigl;
 
+  RE_ENTRANT_CHECK_OFF
+  verify_area(d,4);
   put_fs_long(tl, (unsigned long *) d);
+  RE_ENTRANT_CHECK_ON
 
   return 1;
 }
@@ -823,11 +887,10 @@ int reg_store_int32(void)
 int reg_store_int16(void)
 {
   short *d = (short *)FPU_data_address;
-  REG t;
+  FPU_REG t;
   short ts;
 
-  verify_area(d,2);
-  if ( st0_ptr->tag == TW_Empty )
+  if ( FPU_st0_tag == TW_Empty )
     {
       /* Empty register (stack underflow) */
       EXCEPTION(EX_StackUnder);
@@ -835,14 +898,17 @@ int reg_store_int16(void)
        {
          /* The masked response */
          /* Put out the QNaN indefinite */
+         RE_ENTRANT_CHECK_OFF
+         verify_area(d,2);
          put_fs_word(0x8000, (unsigned short *) d);
+         RE_ENTRANT_CHECK_ON
          return 1;
        }
       else
        return 0;
     }
 
-  reg_move(st0_ptr, &t);
+  reg_move(FPU_st0_ptr, &t);
   round_to_int(&t);
   if (t.sigh || (t.sigl & 0xFFFF8000))
     {
@@ -857,9 +923,12 @@ int reg_store_int16(void)
        return 0;
     }
   else
-    ts = st0_ptr->sign ? -t.sigl : t.sigl;
+    ts = FPU_st0_ptr->sign ? -t.sigl : t.sigl;
 
+  RE_ENTRANT_CHECK_OFF
+  verify_area(d,2);
   put_fs_word(ts,(short *) d);
+  RE_ENTRANT_CHECK_ON
 
   return 1;
 }
@@ -869,13 +938,13 @@ int reg_store_int16(void)
 int reg_store_bcd(void)
 {
   char *d = (char *)FPU_data_address;
-  REG t;
+  FPU_REG t;
   long long ll;
   unsigned char b;
   int i;
+  unsigned char sign = (FPU_st0_ptr->sign == SIGN_NEG) ? 0x80 : 0;
 
-  verify_area(d,10);
-  if ( st0_ptr->tag == TW_Empty )
+  if ( FPU_st0_tag == TW_Empty )
     {
       /* Empty register (stack underflow) */
       EXCEPTION(EX_StackUnder);
@@ -889,7 +958,7 @@ int reg_store_bcd(void)
        return 0;
     }
 
-  reg_move(st0_ptr, &t);
+  reg_move(FPU_st0_ptr, &t);
   round_to_int(&t);
   ll = *(long long *)(&t.sigl);
 
@@ -903,25 +972,30 @@ int reg_store_bcd(void)
        {
 put_indefinite:
          /* Produce "indefinite" */
+         RE_ENTRANT_CHECK_OFF
+         verify_area(d,10);
          put_fs_byte(0xff,(unsigned char *) d+7);
          put_fs_byte(0xff,(unsigned char *) d+8);
          put_fs_byte(0xff,(unsigned char *) d+9);
+         RE_ENTRANT_CHECK_ON
          return 1;
        }
       else
        return 0;
     }
 
+  verify_area(d,10);
   for ( i = 0; i < 9; i++)
     {
       b = div_small(&ll, 10);
       b |= (div_small(&ll, 10)) << 4;
+      RE_ENTRANT_CHECK_OFF
       put_fs_byte(b,(unsigned char *) d+i);
+      RE_ENTRANT_CHECK_ON
     }
-  if (st0_ptr->sign == SIGN_NEG)
-    put_fs_byte(0x80,(unsigned char *) d+9);
-  else
-    put_fs_byte(0,(unsigned char *) d+9);
+  RE_ENTRANT_CHECK_OFF
+  put_fs_byte(sign,(unsigned char *) d+9);
+  RE_ENTRANT_CHECK_ON
 
   return 1;
 }
@@ -934,7 +1008,7 @@ put_indefinite:
    In the case of overflow, the returned significand always has the
    the largest possible value */
 /* The value returned in eax is never actually needed :-) */
-int round_to_int(REG *r)
+int round_to_int(FPU_REG *r)
 {
   char     very_big;
   unsigned eax;
@@ -997,6 +1071,7 @@ char *fldenv(void)
   unsigned char tag;
   int i;
 
+  RE_ENTRANT_CHECK_OFF
   control_word = get_fs_word((unsigned short *) s);
   status_word = get_fs_word((unsigned short *) (s+4));
   tag_word = get_fs_word((unsigned short *) (s+8));
@@ -1004,6 +1079,7 @@ char *fldenv(void)
   cs_selector = get_fs_long((unsigned long *) (s+0x10));
   data_operand_offset = get_fs_long((unsigned long *) (s+0x14));
   operand_selector = get_fs_long((unsigned long *) (s+0x18));
+  RE_ENTRANT_CHECK_ON
 
 
   for ( i = 7; i >= 0; i-- )
@@ -1039,7 +1115,7 @@ void frstor(void)
 {
   int i;
   unsigned char tag;
-  REG *s = (REG *)fldenv();
+  FPU_REG *s = (FPU_REG *)fldenv();
 
   for ( i = 0; i < 8; i++ )
     {
@@ -1093,6 +1169,7 @@ char *fstenv(void)
   *(unsigned short *)&cs_selector = FPU_CS;
   *(unsigned short *)&operand_selector = FPU_DS;
 
+  RE_ENTRANT_CHECK_OFF
   put_fs_word(control_word, (unsigned short *) d);
   put_fs_word(status_word, (unsigned short *) (d+4));
   put_fs_word(tag_word, (unsigned short *) (d+8));
@@ -1100,6 +1177,7 @@ char *fstenv(void)
   put_fs_long(cs_selector, (unsigned long *) (d+0x10));
   put_fs_long(data_operand_offset, (unsigned long *) (d+0x14));
   put_fs_long(operand_selector, (unsigned long *) (d+0x18));
+  RE_ENTRANT_CHECK_ON
 
   return d + 0x1c;
 }
@@ -1108,7 +1186,7 @@ char *fstenv(void)
 void fsave(void)
 {
   char *d;
-  REG tmp, *rp;
+  FPU_REG tmp, *rp;
   int i;
   short e;
 
@@ -1121,13 +1199,15 @@ void fsave(void)
 
       e = rp->exp - EXP_BIAS + EXTENDED_Ebias;
 
-      if ( st0_ptr->tag == TW_Valid )
+      if ( rp->tag == TW_Valid )
        {
          if ( e >= 0x7fff )
            {
              /* Overflow to infinity */
+             RE_ENTRANT_CHECK_OFF
              put_fs_long(0, (unsigned long *) (d+i*10+2));
              put_fs_long(0x80000000, (unsigned long *) (d+i*10+6));
+             RE_ENTRANT_CHECK_ON
              e = 0x7fff;
            }
          else if ( e <= 0 )
@@ -1135,8 +1215,10 @@ void fsave(void)
              if ( e == 0 )
                {
                  /* Pseudo de-normal */
+                 RE_ENTRANT_CHECK_OFF
                  put_fs_long(rp->sigl, (unsigned long *) (d+i*10+2));
                  put_fs_long(rp->sigh, (unsigned long *) (d+i*10+6));
+                 RE_ENTRANT_CHECK_ON
                }
              else if ( e > -64 )
                {
@@ -1145,48 +1227,64 @@ void fsave(void)
                  tmp.exp += -EXTENDED_Emin + 64;  /* largest exp to be 63 */
                  round_to_int(&tmp);
                  e = 0;
+                 RE_ENTRANT_CHECK_OFF
                  put_fs_long(tmp.sigl, (unsigned long *) (d+i*10+2));
                  put_fs_long(tmp.sigh, (unsigned long *) (d+i*10+6));
+                 RE_ENTRANT_CHECK_ON
                }
              else
                {
                  /* Underflow to zero */
+                 RE_ENTRANT_CHECK_OFF
                  put_fs_long(0, (unsigned long *) (d+i*10+2));
                  put_fs_long(0, (unsigned long *) (d+i*10+6));
+                 RE_ENTRANT_CHECK_ON
                  e = 0;
                }
            }
          else
            {
+             RE_ENTRANT_CHECK_OFF
              put_fs_long(rp->sigl, (unsigned long *) (d+i*10+2));
              put_fs_long(rp->sigh, (unsigned long *) (d+i*10+6));
+             RE_ENTRANT_CHECK_ON
            }
        }
-      else if ( st0_ptr->tag == TW_Zero )
+      else if ( rp->tag == TW_Zero )
        {
+         RE_ENTRANT_CHECK_OFF
          put_fs_long(0, (unsigned long *) (d+i*10+2));
          put_fs_long(0, (unsigned long *) (d+i*10+6));
+         RE_ENTRANT_CHECK_ON
          e = 0;
        }
-      else if ( st0_ptr->tag == TW_Infinity )
+      else if ( rp->tag == TW_Infinity )
        {
+         RE_ENTRANT_CHECK_OFF
          put_fs_long(0, (unsigned long *) (d+i*10+2));
          put_fs_long(0x80000000, (unsigned long *) (d+i*10+6));
+         RE_ENTRANT_CHECK_ON
          e = 0x7fff;
        }
-      else if ( st0_ptr->tag == TW_NaN )
+      else if ( rp->tag == TW_NaN )
        {
+         RE_ENTRANT_CHECK_OFF
          put_fs_long(rp->sigl, (unsigned long *) (d+i*10+2));
          put_fs_long(rp->sigh, (unsigned long *) (d+i*10+6));
+         RE_ENTRANT_CHECK_ON
          e = 0x7fff;
        }
-      else if ( st0_ptr->tag == TW_Empty )
+      else if ( rp->tag == TW_Empty )
        {
          /* just copy the reg */
+         RE_ENTRANT_CHECK_OFF
          put_fs_long(rp->sigl, (unsigned long *) (d+i*10+2));
          put_fs_long(rp->sigh, (unsigned long *) (d+i*10+6));
+         RE_ENTRANT_CHECK_ON
        }
+      RE_ENTRANT_CHECK_OFF
       put_fs_word(e, (unsigned short *) (d+i*10));
+      RE_ENTRANT_CHECK_ON
     }
 
 }
index 3d339792ac9a14cbc0d56c2ce0c7fc5ebc022e72..d5992c3fb181d441f9b79b9503854fa5b77f02ee 100644 (file)
@@ -1,7 +1,7 @@
 /*---------------------------------------------------------------------------+
  |  reg_mul.c                                                                |
  |                                                                           |
- | Multiply one REG by another and put the result in a destination REG.      |
+ | Multiply one FPU_REG by another, put the result in a destination FPU_REG. |
  |                                                                           |
  | Copyright (C) 1992    W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
  |                       Australia.  E-mail apm233m@vaxc.cc.monash.edu.au    |
@@ -10,7 +10,7 @@
  +---------------------------------------------------------------------------*/
 
 /*---------------------------------------------------------------------------+
- | The destination may be any REG, including one of the source REGs.         |
+ | The destination may be any FPU_REG, including one of the source FPU_REGs. |
  +---------------------------------------------------------------------------*/
 
 #include "exception.h"
@@ -19,7 +19,7 @@
 
 
 /* This routine must be called with non-empty registers */
-void reg_mul(REG *a, REG *b, REG *dest)
+void reg_mul(FPU_REG *a, FPU_REG *b, FPU_REG *dest)
 {
   if (!(a->tag | b->tag))
     {
@@ -29,9 +29,9 @@ void reg_mul(REG *a, REG *b, REG *dest)
       dest->sign = (a->sign ^ b->sign);
       dest->tag = TW_Valid;
       if ( dest->exp <= EXP_UNDER )
-       { arith_underflow(st0_ptr); }
+       { arith_underflow(FPU_st0_ptr); }
       else if ( dest->exp >= EXP_OVER )
-       { arith_overflow(st0_ptr); }
+       { arith_overflow(FPU_st0_ptr); }
       return;
     }
   else if ((a->tag <= TW_Zero) && (b->tag <= TW_Zero))
index c7377c5e9fbdb3cb5d2a66ea590ed45a393c5afa..0a271da20609941558997e9fa3961d141ce7d176 100644 (file)
@@ -4,10 +4,10 @@
  | Copyright (C) 1992    W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
  |                       Australia.  E-mail apm233m@vaxc.cc.monash.edu.au    |
  |                                                                           |
- | Normalize the value in a REG.                                             |
+ | Normalize the value in a FPU_REG.                                         |
  |                                                                           |
  | Call from C as:                                                           |
- |   void normalize(REG *n)                                                  |
+ |   void normalize(FPU_REG *n)                                              |
  |                                                                           |
  +---------------------------------------------------------------------------*/
 
index 07e4f63d8c42ca878668bb4d6e57ee0840e2fb1a..1595e3e4b377891afc5d44ee37a11ee0f6bc506f 100644 (file)
@@ -2,8 +2,8 @@
 /*---------------------------------------------------------------------------+
  |  reg_u_add.S                                                              |
  |                                                                           |
- | Add two valid (TW_Valid) REG numbers, of the same sign, and put result in |
- | a destination REG.                                                        |
+ | Add two valid (TW_Valid) FPU_REG numbers, of the same sign, and put the   |
+ |   result in a destination FPU_REG.                                        |
  |                                                                           |
  | Copyright (C) 1992    W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
  |                       Australia.  E-mail apm233m@vaxc.cc.monash.edu.au    |
index 6599f7d344e195ed0fa7a829eb179aa336c5700f..a24059c1410695e00c9ca98e70ef561b2f5a0154 100644 (file)
@@ -13,7 +13,8 @@
 /*---------------------------------------------------------------------------+
  |  Kernel for the division routines.                                        |
  |                                                                           |
- |  void reg_u_div(unsigned long long *a, unsigned long long *a, REG *dest)  |
+ |  void reg_u_div(unsigned long long *a, unsigned long long *a,             |
+ |                 FPU_REG *dest)                                            |
  |                                                                           |
  |  Does not compute the destination exponent, but does adjust it.           |
  +---------------------------------------------------------------------------*/
index cd492ed2184fbab062cbb17bbfa3cc8a70027201..7d69a8552d810fe476dcbbda676d2d1d3c4c4e58 100644 (file)
@@ -8,5 +8,5 @@
  |                                                                           |
  +---------------------------------------------------------------------------*/
 
-#define FPU_VERSION "wm-FPU-emu version ALPHA 0.61"
+#define FPU_VERSION "wm-FPU-emu version ALPHA 0.7"
 
index 2ce3af6d9075ef47a763e932b7be7c27094c1ded..b3fb0c23bf8f0e133aee46f309bf0e25e6f39c55 100644 (file)
@@ -8,12 +8,12 @@
  |                       Australia.  E-mail apm233m@vaxc.cc.monash.edu.au    |
  |                                                                           |
  | Call from C as:                                                           |
- |   void wm_sqrt(REG *n)                                                    |
+ |   void wm_sqrt(FPU_REG *n)                                                |
  |                                                                           |
  +---------------------------------------------------------------------------*/
 
 /*---------------------------------------------------------------------------+
- |  wm_sqrt(REG *n)                                                          |
+ |  wm_sqrt(FPU_REG *n)                                                      |
  |    returns the square root of n in n.                                     |
  |                                                                           |
  |  Use Newton's method to compute the square root of a number, which must   |
index 0661a0bd208a510f8c00eb7747bc694b5625efb8..fa352d27a2a0afb818fbacaf815258f69baba641 100644 (file)
@@ -52,15 +52,18 @@ dep:
 dummy:
 
 ### Dependencies:
-exit.o : exit.c /usr/include/linux/wait.h /usr/include/linux/limits.h /usr/include/linux/errno.h \
-  /usr/include/linux/signal.h /usr/include/linux/sched.h /usr/include/linux/head.h \
-  /usr/include/linux/fs.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
+dma.o : dma.c /usr/include/linux/kernel.h /usr/include/linux/errno.h /usr/include/asm/dma.h \
+  /usr/include/asm/io.h 
+exit.o : exit.c /usr/include/linux/wait.h /usr/include/linux/errno.h /usr/include/linux/signal.h \
+  /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
+  /usr/include/linux/limits.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
   /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
   /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h \
   /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h \
   /usr/include/linux/kernel.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/tty.h \
-  /usr/include/linux/termios.h /usr/include/asm/system.h /usr/include/asm/segment.h 
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  /usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/asm/system.h \
+  /usr/include/asm/segment.h 
 fork.o : fork.c /usr/include/linux/errno.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
   /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
@@ -68,8 +71,8 @@ fork.o : fork.c /usr/include/linux/errno.h /usr/include/linux/sched.h /usr/inclu
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
   /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/stddef.h \
-  /usr/include/asm/segment.h /usr/include/asm/system.h 
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  /usr/include/linux/stddef.h /usr/include/asm/segment.h /usr/include/asm/system.h 
 ioport.o : ioport.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
   /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
   /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
@@ -77,7 +80,7 @@ ioport.o : ioport.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/in
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/errno.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/errno.h 
 irq.o : irq.c /usr/include/linux/ptrace.h /usr/include/linux/errno.h /usr/include/linux/signal.h \
   /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
   /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
@@ -86,7 +89,8 @@ irq.o : irq.c /usr/include/linux/ptrace.h /usr/include/linux/errno.h /usr/includ
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/time.h \
   /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
-  /usr/include/asm/system.h /usr/include/asm/io.h /usr/include/asm/irq.h 
+  /usr/include/linux/math_emu.h /usr/include/asm/system.h /usr/include/asm/io.h \
+  /usr/include/asm/irq.h 
 itimer.o : itimer.c /usr/include/linux/signal.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
   /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
@@ -94,8 +98,8 @@ itimer.o : itimer.c /usr/include/linux/signal.h /usr/include/linux/sched.h /usr/
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/string.h /usr/include/linux/errno.h \
-  /usr/include/asm/segment.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/string.h \
+  /usr/include/linux/errno.h /usr/include/asm/segment.h 
 mktime.o : mktime.c /usr/include/linux/mktime.h 
 panic.o : panic.c /usr/include/linux/kernel.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
@@ -104,7 +108,7 @@ panic.o : panic.c /usr/include/linux/kernel.h /usr/include/linux/sched.h /usr/in
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h 
 printk.o : printk.c /usr/lib/gcc-lib/i386-linux/2.2.2d/include/stdarg.h /usr/include/asm/segment.h \
   /usr/include/asm/system.h /usr/include/linux/errno.h /usr/include/linux/sched.h \
   /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
@@ -113,7 +117,8 @@ printk.o : printk.c /usr/lib/gcc-lib/i386-linux/2.2.2d/include/stdarg.h /usr/inc
   /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h \
   /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h \
   /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
-  /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h 
+  /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
+  /usr/include/linux/math_emu.h 
 ptrace.o : ptrace.c /usr/include/linux/head.h /usr/include/linux/kernel.h /usr/include/linux/sched.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
   /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
@@ -121,8 +126,8 @@ ptrace.o : ptrace.c /usr/include/linux/head.h /usr/include/linux/kernel.h /usr/i
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/errno.h /usr/include/linux/ptrace.h \
-  /usr/include/asm/segment.h /usr/include/asm/system.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/errno.h \
+  /usr/include/linux/ptrace.h /usr/include/asm/segment.h /usr/include/asm/system.h 
 sched.o : sched.c /usr/include/linux/signal.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
   /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
@@ -130,9 +135,10 @@ sched.o : sched.c /usr/include/linux/signal.h /usr/include/linux/sched.h /usr/in
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/timer.h /usr/include/linux/sys.h \
-  /usr/include/linux/fdreg.h /usr/include/linux/errno.h /usr/include/linux/ptrace.h \
-  /usr/include/asm/system.h /usr/include/asm/io.h /usr/include/asm/segment.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/timer.h \
+  /usr/include/linux/sys.h /usr/include/linux/fdreg.h /usr/include/linux/errno.h \
+  /usr/include/linux/ptrace.h /usr/include/asm/system.h /usr/include/asm/io.h \
+  /usr/include/asm/segment.h 
 signal.o : signal.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
   /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
   /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
@@ -140,8 +146,8 @@ signal.o : signal.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/in
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/errno.h /usr/include/linux/ptrace.h \
-  /usr/include/asm/segment.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/errno.h \
+  /usr/include/linux/ptrace.h /usr/include/asm/segment.h 
 sys.o : sys.c /usr/include/linux/errno.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
   /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
@@ -149,10 +155,11 @@ sys.o : sys.c /usr/include/linux/errno.h /usr/include/linux/sched.h /usr/include
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
   /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/tty.h \
-  /usr/include/linux/termios.h /usr/include/asm/system.h /usr/include/linux/config.h \
-  /usr/include/linux/config.dist.h /usr/include/linux/times.h /usr/include/linux/utsname.h \
-  /usr/include/linux/string.h /usr/include/linux/ptrace.h /usr/include/asm/segment.h 
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  /usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/asm/system.h \
+  /usr/include/linux/config.h /usr/include/linux/config.dist.h /usr/include/linux/times.h \
+  /usr/include/linux/utsname.h /usr/include/linux/string.h /usr/include/linux/ptrace.h \
+  /usr/include/asm/segment.h 
 traps.o : traps.c /usr/include/linux/head.h /usr/include/linux/sched.h /usr/include/linux/fs.h \
   /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
   /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
@@ -160,7 +167,8 @@ traps.o : traps.c /usr/include/linux/head.h /usr/include/linux/sched.h /usr/incl
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/string.h /usr/include/linux/errno.h \
-  /usr/include/asm/system.h /usr/include/asm/segment.h /usr/include/asm/io.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/string.h \
+  /usr/include/linux/errno.h /usr/include/asm/system.h /usr/include/asm/segment.h \
+  /usr/include/asm/io.h 
 vsprintf.o : vsprintf.c /usr/lib/gcc-lib/i386-linux/2.2.2d/include/stdarg.h \
-  /usr/include/linux/types.h /usr/include/linux/string.h 
+  /usr/include/linux/types.h /usr/include/linux/string.h /usr/include/linux/ctype.h 
index ccbe8edb035d5694e0eee315b93ac78943769a77..58b934029835cf2ebb06191b54014f652fc63b37 100644 (file)
@@ -51,9 +51,10 @@ floppy.o : floppy.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/in
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/timer.h /usr/include/linux/fdreg.h \
-  /usr/include/linux/fd.h /usr/include/linux/errno.h /usr/include/asm/system.h \
-  /usr/include/asm/io.h /usr/include/asm/segment.h blk.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/timer.h \
+  /usr/include/linux/fdreg.h /usr/include/linux/fd.h /usr/include/linux/errno.h \
+  /usr/include/asm/dma.h /usr/include/asm/io.h /usr/include/asm/system.h /usr/include/asm/segment.h \
+  blk.h 
 genhd.o : genhd.c /usr/include/linux/config.h /usr/include/linux/config.dist.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
   /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
@@ -68,9 +69,9 @@ hd.o : hd.c /usr/include/linux/config.h /usr/include/linux/config.dist.h /usr/in
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/timer.h /usr/include/linux/hdreg.h \
-  /usr/include/linux/genhd.h /usr/include/asm/system.h /usr/include/asm/io.h /usr/include/asm/segment.h \
-  blk.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/timer.h \
+  /usr/include/linux/hdreg.h /usr/include/linux/genhd.h /usr/include/asm/system.h \
+  /usr/include/asm/io.h /usr/include/asm/segment.h blk.h 
 ll_rw_blk.o : ll_rw_blk.c /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
   /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
@@ -78,7 +79,8 @@ ll_rw_blk.o : ll_rw_blk.c /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
   /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/errno.h \
-  /usr/include/linux/string.h /usr/include/linux/config.h /usr/include/linux/config.dist.h \
-  /usr/include/asm/system.h blk.h 
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  /usr/include/linux/errno.h /usr/include/linux/string.h /usr/include/linux/config.h \
+  /usr/include/linux/config.dist.h /usr/include/linux/locks.h /usr/include/asm/system.h \
+  blk.h 
 ramdisk.o : ramdisk.c /usr/include/linux/config.h /usr/include/linux/config.dist.h 
index 512500f6c0648139f411542519f37afa1839713a..7afaf53377af667e8a1b6649be63a333b89e70c2 100644 (file)
@@ -330,11 +330,11 @@ int floppy_change(struct buffer_head * bh)
        if (!bh)
                return 0;
        if (bh->b_dirt)
-               ll_rw_block(WRITE,bh);
+               ll_rw_block(WRITE, 1, &bh);
        else {
                buffer_track = -1;
                bh->b_uptodate = 0;
-               ll_rw_block(READ,bh);
+               ll_rw_block(READ, 1, &bh);
        }
        cli();
        while (bh->b_lock)
index 9b68aad47974d05faa750b38c0250d3d39db2d40..0973749d6a9562a1e0af22e2d58ace45c281c3d8 100644 (file)
@@ -75,7 +75,7 @@ struct hd_i_struct {
        };
 #ifdef HD_TYPE
 struct hd_i_struct hd_info[] = { HD_TYPE };
-#define NR_HD ((sizeof (hd_info))/(sizeof (struct hd_i_struct)))
+static int NR_HD = ((sizeof (hd_info))/(sizeof (struct hd_i_struct)));
 #else
 struct hd_i_struct hd_info[] = { {0,0,0,0,0,0},{0,0,0,0,0,0} };
 static int NR_HD = 0;
@@ -106,18 +106,6 @@ unsigned long read_timer(void)
 }
 #endif
 
-static int controller_ready(void)
-{
-       int retries = 100000;
-
-       while (--retries && (inb_p(HD_STATUS)&0x80))
-               /* nothing */;
-       if (!retries)
-               printk("controller_ready: status = %02x\n\r",
-                       (unsigned char) inb_p(HD_STATUS));
-       return (retries);
-}
-
 static int win_result(void)
 {
        int i=inb_p(HD_STATUS);
@@ -133,6 +121,49 @@ static int win_result(void)
        return 1;
 }
 
+static int controller_busy(void);
+static int status_ok(void);
+
+static int controller_ready(unsigned int drive, unsigned int head)
+{
+       int retry = 100;
+
+       do {
+               if (controller_busy() & BUSY_STAT)
+                       return 0;
+               outb_p(0xA0 | (drive<<4) | head, HD_CURRENT);
+               if (status_ok())
+                       return 1;
+       } while (--retry);
+       return 0;
+}
+
+static int status_ok(void)
+{
+       unsigned char status = controller_busy();
+
+       if (status & BUSY_STAT)
+               return 0;
+       if (status & WRERR_STAT)
+               return 0;
+       if (!(status & READY_STAT))
+               return 0;
+       if (!(status & SEEK_STAT))
+               return 0;
+       return 1;
+}
+
+static int controller_busy(void)
+{
+       int retries = 100000;
+       unsigned char status;
+
+       do {
+               status = inb_p(HD_STATUS);
+       } while ((status & BUSY_STAT) && --retries);
+       return status;
+}
+
 static void hd_out(unsigned int drive,unsigned int nsect,unsigned int sect,
                unsigned int head,unsigned int cyl,unsigned int cmd,
                void (*intr_addr)(void))
@@ -145,7 +176,9 @@ static void hd_out(unsigned int drive,unsigned int nsect,unsigned int sect,
        while (read_timer() - last_req < HD_DELAY)
                /* nothing */;
 #endif
-       if (reset || !controller_ready()) {
+       if (reset)
+               return;
+       if (!controller_ready(drive, head)) {
                reset = 1;
                return;
        }
@@ -468,7 +501,7 @@ static int hd_ioctl(struct inode * inode, struct file * file,
        if (dev >= NR_HD)
                return -EINVAL;
        switch (cmd) {
-               case HDIO_REQ:
+               case HDIO_GETGEO:
                        if (!loc)  return -EINVAL;
                        verify_area(loc, sizeof(*loc));
                        put_fs_byte(hd_info[dev].head,
@@ -604,13 +637,13 @@ static void hd_geninit(void)
                        NR_HD = 1;
        else
                NR_HD = 0;
+#endif
        if (NR_HD) {
                if (irqaction(HD_IRQ,&hd_sigaction)) {
                        printk("Unable to get IRQ%d for the harddisk driver\n",HD_IRQ);
                        NR_HD = 0;
                }
        }
-#endif
        for (i = 0 ; i < NR_HD ; i++)
                hd[i<<6].nr_sects = hd_info[i].head*
                                hd_info[i].sect*hd_info[i].cyl;
index c6aef54e3ff63a12c01296941c21794d1f6c9f2b..590a376c2d6d7bac9037a0f49bb901a026bbdabc 100644 (file)
@@ -243,29 +243,30 @@ repeat:
        schedule();
 }
 
-void ll_rw_block(int rw, struct buffer_head * bh)
+void ll_rw_block(int rw, int nr, struct buffer_head * bh[])
 {
        unsigned int major;
 
-       if (!bh)
+       if (nr!=1) panic("ll_rw_block: only one block at a time implemented");
+       if (!bh[0])
                return;
-       if (bh->b_size != 1024) {
-               printk("ll_rw_block: only 1024-char blocks implemented (%d)\n",bh->b_size);
-               bh->b_dirt = bh->b_uptodate = 0;
+       if (bh[0]->b_size != 1024) {
+               printk("ll_rw_block: only 1024-char blocks implemented (%d)\n",bh[0]->b_size);
+               bh[0]->b_dirt = bh[0]->b_uptodate = 0;
                return;
        }
-       if ((major=MAJOR(bh->b_dev)) >= NR_BLK_DEV ||
+       if ((major=MAJOR(bh[0]->b_dev)) >= NR_BLK_DEV ||
        !(blk_dev[major].request_fn)) {
-               printk("ll_rw_block: Trying to read nonexistent block-device %04x (%d)\n",bh->b_dev,bh->b_blocknr);
-               bh->b_dirt = bh->b_uptodate = 0;
+               printk("ll_rw_block: Trying to read nonexistent block-device %04x (%d)\n",bh[0]->b_dev,bh[0]->b_blocknr);
+               bh[0]->b_dirt = bh[0]->b_uptodate = 0;
                return;
        }
-       if ((rw == WRITE || rw == WRITEA) && is_read_only(bh->b_dev)) {
-               printk("Can't write to read-only device 0x%X\n\r",bh->b_dev);
-               bh->b_dirt = bh->b_uptodate = 0;
+       if ((rw == WRITE || rw == WRITEA) && is_read_only(bh[0]->b_dev)) {
+               printk("Can't write to read-only device 0x%X\n\r",bh[0]->b_dev);
+               bh[0]->b_dirt = bh[0]->b_uptodate = 0;
                return;
        }
-       make_request(major,rw,bh);
+       make_request(major,rw,bh[0]);
 }
 
 void ll_rw_swap_file(int rw, int dev, unsigned int *b, int nb, char *buf)
index 226a8c033f068b1f1fc2582281192ce7e7a1a584..5765807fdc4fb8b9502ad2c33fe8c662839d2e58 100644 (file)
@@ -74,8 +74,8 @@ fdomain.o : fdomain.c /usr/include/linux/config.h /usr/include/linux/config.dist
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/asm/io.h fdomain.h scsi.h hosts.h max_hosts.h \
-  /usr/include/asm/system.h /usr/include/linux/errno.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/asm/io.h \
+  fdomain.h scsi.h hosts.h max_hosts.h /usr/include/asm/system.h /usr/include/linux/errno.h 
 hosts.o : hosts.c /usr/include/linux/config.h /usr/include/linux/config.dist.h \
   /usr/include/linux/kernel.h scsi.h hosts.h max_hosts.h aha1542.h /usr/include/linux/types.h \
   fdomain.h seagate.h ultrastor.h 7000fasst.h 
@@ -87,9 +87,9 @@ scsi.o : scsi.c /usr/include/linux/config.h /usr/include/linux/config.dist.h \
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
   /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/timer.h \
-  /usr/include/linux/string.h scsi.h hosts.h max_hosts.h sd.h /usr/include/linux/genhd.h \
-  st.h sr.h 
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  /usr/include/linux/timer.h /usr/include/linux/string.h scsi.h hosts.h max_hosts.h \
+  sd.h /usr/include/linux/genhd.h st.h sr.h 
 scsi_ioctl.o : scsi_ioctl.c /usr/include/linux/config.h /usr/include/linux/config.dist.h \
   /usr/include/asm/io.h /usr/include/asm/segment.h /usr/include/asm/system.h /usr/include/linux/errno.h \
   /usr/include/linux/kernel.h /usr/include/linux/sched.h /usr/include/linux/head.h \
@@ -99,8 +99,8 @@ scsi_ioctl.o : scsi_ioctl.c /usr/include/linux/config.h /usr/include/linux/confi
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/string.h scsi.h hosts.h max_hosts.h \
-  scsi_ioctl.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/string.h \
+  scsi.h hosts.h max_hosts.h scsi_ioctl.h 
 sd.o : sd.c /usr/include/linux/config.h /usr/include/linux/config.dist.h /usr/include/linux/fs.h \
   /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
   /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
@@ -109,8 +109,9 @@ sd.o : sd.c /usr/include/linux/config.h /usr/include/linux/config.dist.h /usr/in
   /usr/include/linux/kernel.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/mm.h /usr/include/linux/signal.h /usr/include/linux/time.h \
   /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
-  /usr/include/linux/string.h /usr/include/linux/errno.h /usr/include/asm/system.h \
-  scsi.h sd.h /usr/include/linux/genhd.h scsi_ioctl.h ../blk.h 
+  /usr/include/linux/math_emu.h /usr/include/linux/string.h /usr/include/linux/errno.h \
+  /usr/include/asm/system.h scsi.h hosts.h max_hosts.h sd.h /usr/include/linux/genhd.h \
+  scsi_ioctl.h ../blk.h 
 sd_ioctl.o : sd_ioctl.c /usr/include/linux/config.h /usr/include/linux/config.dist.h \
   /usr/include/linux/kernel.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
@@ -119,7 +120,7 @@ sd_ioctl.o : sd_ioctl.c /usr/include/linux/config.h /usr/include/linux/config.di
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h scsi.h sd.h /usr/include/linux/genhd.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h scsi.h sd.h /usr/include/linux/genhd.h 
 seagate.o : seagate.c /usr/include/linux/config.h /usr/include/linux/config.dist.h \
   /usr/include/asm/io.h /usr/include/asm/system.h /usr/include/linux/signal.h \
   /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
@@ -129,7 +130,7 @@ seagate.o : seagate.c /usr/include/linux/config.h /usr/include/linux/config.dist
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/time.h \
   /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
-  seagate.h scsi.h hosts.h max_hosts.h 
+  /usr/include/linux/math_emu.h seagate.h scsi.h hosts.h max_hosts.h 
 sr.o : sr.c /usr/include/linux/config.h /usr/include/linux/config.dist.h /usr/include/linux/fs.h \
   /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
   /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
@@ -138,7 +139,8 @@ sr.o : sr.c /usr/include/linux/config.h /usr/include/linux/config.dist.h /usr/in
   /usr/include/linux/kernel.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/mm.h /usr/include/linux/signal.h /usr/include/linux/time.h \
   /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
-  /usr/include/linux/string.h scsi.h sr.h scsi_ioctl.h ../blk.h 
+  /usr/include/linux/math_emu.h /usr/include/linux/string.h /usr/include/linux/errno.h \
+  scsi.h sr.h scsi_ioctl.h ../blk.h 
 sr_ioctl.o : sr_ioctl.c /usr/include/linux/config.h /usr/include/linux/config.dist.h \
   /usr/include/linux/kernel.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
@@ -147,8 +149,8 @@ sr_ioctl.o : sr_ioctl.c /usr/include/linux/config.h /usr/include/linux/config.di
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/asm/segment.h /usr/include/linux/errno.h \
-  ../blk.h scsi.h sr.h scsi_ioctl.h /usr/include/linux/cdrom.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/asm/segment.h \
+  /usr/include/linux/errno.h ../blk.h scsi.h sr.h scsi_ioctl.h /usr/include/linux/cdrom.h 
 st.o : st.c /usr/include/linux/config.h /usr/include/linux/config.dist.h scsi.h \
   st.h /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
   /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
@@ -157,7 +159,7 @@ st.o : st.c /usr/include/linux/config.h /usr/include/linux/config.dist.h scsi.h
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/kernel.h /usr/include/linux/sched.h \
   /usr/include/linux/head.h /usr/include/linux/mm.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h ../blk.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h ../blk.h 
 st_ioctl.o : st_ioctl.c /usr/include/linux/config.h /usr/include/linux/config.dist.h \
   /usr/include/linux/kernel.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
@@ -166,14 +168,15 @@ st_ioctl.o : st_ioctl.c /usr/include/linux/config.h /usr/include/linux/config.di
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h st.h scsi.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h st.h scsi.h 
 ultrastor.o : ultrastor.c /usr/include/linux/config.h /usr/include/linux/config.dist.h \
-  /usr/include/linux/stddef.h /usr/include/linux/string.h /usr/include/linux/sched.h \
-  /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
-  /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
+  /usr/include/linux/stddef.h /usr/include/linux/string.h /usr/include/linux/types.h \
+  /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
+  /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/dirent.h \
   /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
   /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h \
   /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h \
   /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
   /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
-  /usr/include/asm/io.h /usr/include/asm/system.h ultrastor.h scsi.h hosts.h max_hosts.h 
+  /usr/include/linux/math_emu.h /usr/include/asm/io.h /usr/include/asm/system.h \
+  ultrastor.h scsi.h hosts.h max_hosts.h 
index 39d3f519276fc1f20e97f221b600bc9e330ccee8..0c79e8c4dfac2fc6c6a2d2b3f679db4b31ac1290 100644 (file)
@@ -47,9 +47,10 @@ atixlmouse.o : atixlmouse.c /usr/include/linux/kernel.h /usr/include/linux/sched
   /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h \
   /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h \
   /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/tty.h \
-  /usr/include/linux/termios.h /usr/include/asm/system.h /usr/include/linux/errno.h \
-  /usr/include/asm/io.h /usr/include/asm/segment.h /usr/include/asm/irq.h 
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  /usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/asm/system.h \
+  /usr/include/linux/errno.h /usr/include/asm/io.h /usr/include/asm/segment.h \
+  /usr/include/asm/irq.h 
 busmouse.o : busmouse.c /usr/include/linux/kernel.h /usr/include/linux/sched.h \
   /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
   /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
@@ -57,9 +58,9 @@ busmouse.o : busmouse.c /usr/include/linux/kernel.h /usr/include/linux/sched.h \
   /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h \
   /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h \
   /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/busmouse.h \
-  /usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/asm/system.h \
-  /usr/include/linux/errno.h /usr/include/asm/io.h /usr/include/asm/segment.h \
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  /usr/include/linux/busmouse.h /usr/include/linux/tty.h /usr/include/linux/termios.h \
+  /usr/include/asm/system.h /usr/include/linux/errno.h /usr/include/asm/io.h /usr/include/asm/segment.h \
   /usr/include/asm/irq.h 
 console.o : console.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
   /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
@@ -68,10 +69,11 @@ console.o : console.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/timer.h /usr/include/linux/tty.h \
-  /usr/include/linux/termios.h /usr/include/asm/system.h /usr/include/linux/config.h \
-  /usr/include/linux/config.dist.h /usr/include/linux/string.h /usr/include/linux/errno.h \
-  /usr/include/linux/kd.h /usr/include/asm/io.h /usr/include/asm/segment.h vt_kern.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/timer.h \
+  /usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/asm/system.h \
+  /usr/include/linux/config.h /usr/include/linux/config.dist.h /usr/include/linux/string.h \
+  /usr/include/linux/errno.h /usr/include/linux/kd.h /usr/include/asm/io.h /usr/include/asm/segment.h \
+  vt_kern.h 
 keyboard.o : keyboard.c /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
   /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
@@ -79,18 +81,18 @@ keyboard.o : keyboard.c /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
   /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/ctype.h \
-  /usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/asm/system.h \
-  /usr/include/linux/ptrace.h /usr/include/asm/io.h 
-lp.o : lp.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  /usr/include/linux/ctype.h /usr/include/linux/tty.h /usr/include/linux/termios.h \
+  /usr/include/asm/system.h /usr/include/linux/ptrace.h /usr/include/asm/io.h 
+lp.o : lp.c /usr/include/linux/lp.h /usr/include/linux/errno.h /usr/include/linux/kernel.h \
+  /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
   /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
   /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
   /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
-  /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
-  /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/lp.h /usr/include/linux/errno.h \
-  /usr/include/asm/io.h /usr/include/asm/segment.h 
+  /usr/include/linux/mm.h /usr/include/linux/signal.h /usr/include/linux/time.h \
+  /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
+  /usr/include/linux/math_emu.h /usr/include/asm/io.h /usr/include/asm/segment.h 
 mem.o : mem.c /usr/include/linux/types.h /usr/include/linux/errno.h /usr/include/linux/sched.h \
   /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
   /usr/include/linux/wait.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
@@ -98,9 +100,11 @@ mem.o : mem.c /usr/include/linux/types.h /usr/include/linux/errno.h /usr/include
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
   /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/tty.h \
-  /usr/include/linux/termios.h /usr/include/asm/system.h /usr/include/linux/mouse.h \
-  /usr/include/asm/segment.h /usr/include/asm/io.h 
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  /usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/asm/system.h \
+  /usr/include/linux/mouse.h /usr/include/linux/user.h /usr/include/linux/ptrace.h \
+  /usr/include/linux/a.out.h /usr/include/linux/string.h /usr/include/asm/segment.h \
+  /usr/include/asm/io.h 
 mouse.o : mouse.c /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
   /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
   /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
@@ -113,9 +117,9 @@ msbusmouse.o : msbusmouse.c /usr/include/linux/kernel.h /usr/include/linux/sched
   /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h \
   /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h \
   /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/busmouse.h \
-  /usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/asm/system.h \
-  /usr/include/linux/errno.h /usr/include/asm/io.h /usr/include/asm/segment.h \
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  /usr/include/linux/busmouse.h /usr/include/linux/tty.h /usr/include/linux/termios.h \
+  /usr/include/asm/system.h /usr/include/linux/errno.h /usr/include/asm/io.h /usr/include/asm/segment.h \
   /usr/include/asm/irq.h 
 psaux.o : psaux.c /usr/include/linux/timer.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
@@ -124,9 +128,9 @@ psaux.o : psaux.c /usr/include/linux/timer.h /usr/include/linux/sched.h /usr/inc
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
   /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/fcntl.h \
-  /usr/include/linux/errno.h /usr/include/asm/io.h /usr/include/asm/segment.h \
-  /usr/include/asm/system.h 
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  /usr/include/linux/fcntl.h /usr/include/linux/errno.h /usr/include/asm/io.h \
+  /usr/include/asm/segment.h /usr/include/asm/system.h 
 pty.o : pty.c /usr/include/linux/errno.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
   /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
@@ -134,9 +138,9 @@ pty.o : pty.c /usr/include/linux/errno.h /usr/include/linux/sched.h /usr/include
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
   /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/tty.h \
-  /usr/include/linux/termios.h /usr/include/asm/system.h /usr/include/linux/fcntl.h \
-  /usr/include/asm/io.h 
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  /usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/asm/system.h \
+  /usr/include/linux/fcntl.h /usr/include/asm/io.h 
 serial.o : serial.c /usr/include/linux/errno.h /usr/include/linux/signal.h /usr/include/linux/sched.h \
   /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
   /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
@@ -144,10 +148,10 @@ serial.o : serial.c /usr/include/linux/errno.h /usr/include/linux/signal.h /usr/
   /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h \
   /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h \
   /usr/include/linux/kernel.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/timer.h \
-  /usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/asm/system.h \
-  /usr/include/linux/serial.h /usr/include/asm/io.h /usr/include/asm/segment.h \
-  /usr/include/asm/bitops.h 
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  /usr/include/linux/timer.h /usr/include/linux/tty.h /usr/include/linux/termios.h \
+  /usr/include/asm/system.h /usr/include/linux/serial.h /usr/include/asm/io.h \
+  /usr/include/asm/segment.h /usr/include/asm/bitops.h 
 tty_io.o : tty_io.c /usr/include/linux/types.h /usr/include/linux/errno.h /usr/include/linux/signal.h \
   /usr/include/linux/fcntl.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
@@ -156,9 +160,10 @@ tty_io.o : tty_io.c /usr/include/linux/types.h /usr/include/linux/errno.h /usr/i
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/time.h \
   /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
-  /usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/asm/system.h \
-  /usr/include/linux/ctype.h /usr/include/linux/kd.h /usr/include/linux/string.h \
-  /usr/include/asm/segment.h /usr/include/asm/bitops.h vt_kern.h 
+  /usr/include/linux/math_emu.h /usr/include/linux/tty.h /usr/include/linux/termios.h \
+  /usr/include/asm/system.h /usr/include/linux/ctype.h /usr/include/linux/kd.h \
+  /usr/include/linux/string.h /usr/include/asm/segment.h /usr/include/asm/bitops.h \
+  vt_kern.h 
 tty_ioctl.o : tty_ioctl.c /usr/include/linux/types.h /usr/include/linux/termios.h \
   /usr/include/linux/errno.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
@@ -167,8 +172,8 @@ tty_ioctl.o : tty_ioctl.c /usr/include/linux/types.h /usr/include/linux/termios.
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/tty.h /usr/include/asm/system.h \
-  /usr/include/linux/fcntl.h /usr/include/asm/io.h /usr/include/asm/segment.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/tty.h \
+  /usr/include/asm/system.h /usr/include/linux/fcntl.h /usr/include/asm/io.h /usr/include/asm/segment.h 
 vt.o : vt.c /usr/include/linux/types.h /usr/include/linux/errno.h /usr/include/linux/sched.h \
   /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
   /usr/include/linux/wait.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
@@ -176,7 +181,7 @@ vt.o : vt.c /usr/include/linux/types.h /usr/include/linux/errno.h /usr/include/l
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
   /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/tty.h \
-  /usr/include/linux/termios.h /usr/include/asm/system.h /usr/include/linux/timer.h \
-  /usr/include/linux/kd.h /usr/include/linux/vt.h /usr/include/asm/io.h /usr/include/asm/segment.h \
-  vt_kern.h 
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  /usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/asm/system.h \
+  /usr/include/linux/timer.h /usr/include/linux/kd.h /usr/include/linux/vt.h /usr/include/asm/io.h \
+  /usr/include/asm/segment.h vt_kern.h 
index ac24701065ff90692b0ba22b07f7ce44b7a1a34c..e7b49b77d93e4509db0399762c3b533ce00bf9b9 100644 (file)
@@ -1352,16 +1352,18 @@ long no_idt[2] = {0, 0};
  */
 void hard_reset_now(void)
 {
-       int i;
+       int i, j;
        extern unsigned long pg0[1024];
 
        sti();
 /* rebooting needs to touch the page at absolute addr 0 */
        pg0[0] = 7;
+       *((unsigned short *)0x472) = 0x1234;
        for (;;) {
                for (i=0; i<100; i++) {
                        kb_wait();
-                       *((unsigned short *)0x472) = 0x1234;
+                       for(j = 0; j < 100000 ; j++)
+                               /* nothing */;
                        outb(0xfe,0x64);         /* pulse reset low */
                }
                __asm__("\tlidt _no_idt"::);
index 3287d8dc29ee7e574bb5cdc0ee0d4034c233aa24..50b25d55c8cc0cf5d3f07f7d0aa8bf9116ff34a3 100644 (file)
@@ -227,7 +227,7 @@ static int read_aux(struct inode * inode, struct file * file, char * buffer, int
 
        if (queue_empty()) {
                if (file->f_flags & O_NONBLOCK)
-                       return -EWOULDBLOCK;
+                       return -EAGAIN;
                cli();
                interruptible_sleep_on(&queue->proc_list);
                sti();
@@ -277,13 +277,6 @@ unsigned long psaux_init(unsigned long kmem_start)
        if (aux_device_present != 0xaa) {
                return kmem_start;
        }
-       aux_write_ack(AUX_SET_RES);
-       aux_write_ack(0x03);            /* set resultion to 8 counts/mm */
-       aux_write_ack(AUX_SET_SCALE);
-       aux_write_ack(0x02);            /* set scaling to 2:1 */
-       aux_write_ack(AUX_SET_SAMPLE);
-       aux_write_ack(0x64);            /* set sampling rate to 100/sec */
-       aux_write_ack(AUX_SET_STREAM);  /* set stream mode */
        printk("PS/2 type pointing device detected and installed.\n");
        queue = (struct aux_queue *) kmem_start;
        kmem_start += sizeof (struct aux_queue);
index 62cf0b67c3c91dd840734f9c95bc0baf41a18fad..89b022072e302d8cf87f59dc3e255929ffb3fb46 100644 (file)
@@ -775,7 +775,7 @@ static int set_modem_info(struct async_struct * info, unsigned int cmd,
                default:
                        return -EINVAL;
        }
-       outb(UART_MCR + port,control);
+       outb(control, UART_MCR + port);
        return 0;
 }
 
index 2b25ca4391cd519ccb44057eafd3d0f8edfdfc72..b5a5e4ea16e76b279ac990636cfc583f66f40594 100644 (file)
@@ -270,31 +270,19 @@ int is_ignored(int sig)
                (current->sigaction[sig-1].sa_handler == SIG_IGN));
 }
 
+static int available_canon_input(struct tty_struct *);
+static void __wait_for_canon_input(struct tty_struct *);
+
 static void wait_for_canon_input(struct tty_struct * tty)
 {
-       while (1) {
-               TTY_READ_FLUSH(tty);
-               if (tty->link)
-                       if (tty->link->count)
-                               TTY_WRITE_FLUSH(tty->link);
-                       else
-                               return;
-               if (current->signal & ~current->blocked)
-                       return;
-               if (FULL(&tty->read_q))
-                       return;
-               if (tty->secondary.data)
-                       return;
-               cli();
-               if (!tty->secondary.data)
-                       interruptible_sleep_on(&tty->secondary.proc_list);
-               sti();
-       }
+       if (!available_canon_input(tty))
+               __wait_for_canon_input(tty);
 }
 
 static int read_chan(unsigned int channel, struct file * file, char * buf, int nr)
 {
        struct tty_struct * tty;
+       struct wait_queue wait = { current, NULL };
        int c;
        char * b=buf;
        int minimum,time;
@@ -329,9 +317,13 @@ static int read_chan(unsigned int channel, struct file * file, char * buf, int n
                        minimum = 1;
                }
        }
-       if (file->f_flags & O_NONBLOCK)
+       if (file->f_flags & O_NONBLOCK) {
                time = current->timeout = 0;
-       else if (L_CANON(tty)) {
+               if (L_CANON(tty)) {
+                       if (!available_canon_input(tty))
+                               return -EAGAIN;
+               }
+       } else if (L_CANON(tty)) {
                wait_for_canon_input(tty);
                if (current->signal & ~current->blocked)
                        return -ERESTARTSYS;
@@ -355,7 +347,7 @@ static int read_chan(unsigned int channel, struct file * file, char * buf, int n
                if (nr == 0)
                        return 1;
        }
-
+       add_wait_queue(&tty->secondary.proc_list, &wait);
        while (nr>0) {
                TTY_READ_FLUSH(tty);
                if (tty->link)
@@ -391,11 +383,14 @@ static int read_chan(unsigned int channel, struct file * file, char * buf, int n
                TTY_READ_FLUSH(tty);
                if (tty->link)
                        TTY_WRITE_FLUSH(tty->link);
-               cli();
+               if (!EMPTY(&tty->secondary))
+                       continue;
+               current->state = TASK_INTERRUPTIBLE;
                if (EMPTY(&tty->secondary))
-                       interruptible_sleep_on(&tty->secondary.proc_list);
-               sti();
+                       schedule();
+               current->state = TASK_RUNNING;
        }
+       remove_wait_queue(&tty->secondary.proc_list, &wait);
        TTY_READ_FLUSH(tty);
        if (tty->link && tty->link->write)
                TTY_WRITE_FLUSH(tty->link);
@@ -418,9 +413,42 @@ static int read_chan(unsigned int channel, struct file * file, char * buf, int n
        return 0;
 }
 
+static void __wait_for_canon_input(struct tty_struct * tty)
+{
+       struct wait_queue wait = { current, NULL };
+
+       add_wait_queue(&tty->secondary.proc_list, &wait);
+       while (1) {
+               current->state = TASK_INTERRUPTIBLE;
+               if (available_canon_input(tty))
+                       break;
+               schedule();
+       }
+       current->state = TASK_RUNNING;
+       remove_wait_queue(&tty->secondary.proc_list, &wait);
+}
+
+static int available_canon_input(struct tty_struct * tty)
+{
+       TTY_READ_FLUSH(tty);
+       if (tty->link)
+               if (tty->link->count)
+                       TTY_WRITE_FLUSH(tty->link);
+               else
+                       return 1;
+       if (current->signal & ~current->blocked)
+               return 1;
+       if (FULL(&tty->read_q))
+               return 1;
+       if (tty->secondary.data)
+               return 1;
+       return 0;
+}
+
 static int write_chan(unsigned int channel, struct file * file, char * buf, int nr)
 {
        struct tty_struct * tty;
+       struct wait_queue wait = { current, NULL };
        char c, *b=buf;
 
        if (channel > 255)
@@ -444,6 +472,7 @@ static int write_chan(unsigned int channel, struct file * file, char * buf, int
                return -EINVAL;
        if (!nr)
                return 0;
+       add_wait_queue(&tty->write_q.proc_list, &wait);
        while (nr>0) {
                if (current->signal & ~current->blocked)
                        break;
@@ -451,14 +480,15 @@ static int write_chan(unsigned int channel, struct file * file, char * buf, int
                        send_sig(SIGPIPE,current,0);
                        break;
                }
+               current->state = TASK_INTERRUPTIBLE;
                if (FULL(&tty->write_q)) {
                        TTY_WRITE_FLUSH(tty);
-                       cli();
                        if (FULL(&tty->write_q))
-                               interruptible_sleep_on(&tty->write_q.proc_list);
-                       sti();
+                               schedule();
+                       current->state = TASK_RUNNING;
                        continue;
                }
+               current->state = TASK_RUNNING;
                while (nr>0 && !FULL(&tty->write_q)) {
                        c=get_fs_byte(b);
                        if (O_POST(tty)) {
@@ -478,9 +508,10 @@ static int write_chan(unsigned int channel, struct file * file, char * buf, int
                        clear_bit(TTY_CR_PENDING,&tty->flags);
                        put_tty_queue(c,&tty->write_q);
                }
-               if (nr>0)
+               if (need_resched)
                        schedule();
        }
+       remove_wait_queue(&tty->write_q.proc_list, &wait);
        TTY_WRITE_FLUSH(tty);
        if (b-buf)
                return b-buf;
@@ -794,7 +825,8 @@ int initialize_tty_struct(struct tty_struct *tty, int line)
        tty->winsize.ws_row = 24;
        tty->winsize.ws_col = 80;
        if (!tty_termios[line]) {
-               tp = tty_termios[line] = malloc(sizeof(struct termios));
+               tp = tty_termios[line] = kmalloc(sizeof(struct termios),
+                                               GFP_KERNEL);
                if (!tp)
                        return -ENOMEM;
                memset(tp, 0, sizeof(struct termios));
index d7a0891808cac53f26d24079b7dbc49c54697415..30b14e0fbc61bd5c09d9256f9f8faef0e189fc58 100644 (file)
@@ -70,6 +70,7 @@ void release(struct task_struct * p)
                if (task[i] == p) {
                        task[i] = NULL;
                        REMOVE_LINKS(p);
+                       free_page(p->kernel_stack_page);
                        free_page((long) p);
                        return;
                }
@@ -98,7 +99,7 @@ int bad_task_ptr(struct task_struct *p)
  * holds.  Used for debugging only, since it's very slow....
  *
  * It looks a lot scarier than it really is.... we're doing Ã¦nothing more
- * than verifying the doubly-linked list foundæin p_ysptr and p_osptr, 
+ * than verifying the doubly-linked list found in p_ysptr and p_osptr, 
  * and checking it corresponds with the process tree defined by p_cptr and 
  * p_pptr;
  */
@@ -347,7 +348,7 @@ fake_volatile:
        while (p = current->p_cptr) {
                current->p_cptr = p->p_osptr;
                p->p_ysptr = NULL;
-               p->flags &= ~PF_PTRACED;
+               p->flags &= ~(PF_PTRACED|PF_TRACESYS);
                if (task[1])
                        p->p_pptr = task[1];
                else
index 8024f29b58a57e8630935e79dc0640f53213c821..8eb1a8747d980998b7d89d3940ee202bb14d0e56 100644 (file)
@@ -118,11 +118,10 @@ int sys_fork(long ebx,long ecx,long edx,
                return nr;
        }
        task[nr] = p;
-       *p = *current;  /* NOTE! this doesn't copy the supervisor stack */
-       p->wait.task = p;
-       p->wait.next = NULL;
+       *p = *current;
+       p->kernel_stack_page = 0;
        p->state = TASK_UNINTERRUPTIBLE;
-       p->flags &= ~PF_PTRACED;
+       p->flags &= ~(PF_PTRACED|PF_TRACESYS);
        p->pid = last_pid;
        if (p->pid > 1)
                p->swappable = 1;
@@ -140,7 +139,6 @@ int sys_fork(long ebx,long ecx,long edx,
        p->cmin_flt = p->cmaj_flt = 0;
        p->start_time = jiffies;
        p->tss.back_link = 0;
-       p->tss.esp0 = PAGE_SIZE + (long) p;
        p->tss.ss0 = 0x10;
        p->tss.eip = eip;
        p->tss.eflags = eflags & 0xffffcfff;    /* iopl is always 0 for a new process */
@@ -164,12 +162,15 @@ int sys_fork(long ebx,long ecx,long edx,
                p->tss.io_bitmap[i] = ~0;
        if (last_task_used_math == current)
                __asm__("clts ; fnsave %0 ; frstor %0"::"m" (p->tss.i387));
-       if (copy_mem(nr,p)) {
+       p->kernel_stack_page = get_free_page(GFP_KERNEL);
+       if (!p->kernel_stack_page || copy_mem(nr,p)) {
                task[nr] = NULL;
                REMOVE_LINKS(p);
+               free_page(p->kernel_stack_page);
                free_page((long) p);
                return -EAGAIN;
        }
+       p->tss.esp0 = PAGE_SIZE + p->kernel_stack_page;
        for (i=0; i<NR_OPEN;i++)
                if (f=p->filp[i])
                        f->f_count++;
index 73575abf94af98240c0571e95d2c88073a4b7544..52e0d41262560b41b7f081cebd7185d370939dc0 100644 (file)
@@ -122,6 +122,8 @@ repeat:
        if (page & PAGE_PRESENT) {
                page &= 0xfffff000;
                page += (addr >> 10) & 0xffc;
+/* we're bypassing pagetables, so we have to set the dirty bit ourselves */
+               *(unsigned long *) page |= PAGE_DIRTY;
                page = *((unsigned long *) page);
        }
        if (!(page & PAGE_PRESENT)) {
@@ -304,9 +306,14 @@ int sys_ptrace(long request, long pid, long addr, long data)
                                return -EIO;
                        return 0;
 
+               case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
                case PTRACE_CONT: { /* restart after signal. */
                        long tmp;
 
+                       if (request == PTRACE_SYSCALL)
+                               child->flags |= PF_TRACESYS;
+                       else
+                               child->flags &= ~PF_TRACESYS;
                        child->signal = 0;
                        if (data > 0 && data <= NSIG)
                                child->signal = 1<<(data-1);
@@ -336,6 +343,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
                case PTRACE_SINGLESTEP: {  /* set the trap flag. */
                        long tmp;
 
+                       child->flags &= ~PF_TRACESYS;
                        tmp = get_stack_long(child, 4*EFL-MAGICNUMBER) | TRAP_FLAG;
                        put_stack_long(child, 4*EFL-MAGICNUMBER,tmp);
                        child->state = TASK_RUNNING;
@@ -349,7 +357,7 @@ int sys_ptrace(long request, long pid, long addr, long data)
                case PTRACE_DETACH: { /* detach a process that was attached. */
                        long tmp;
 
-                       child->flags &= ~PF_PTRACED;
+                       child->flags &= ~(PF_PTRACED|PF_TRACESYS);
                        child->signal=0;
                        child->state = 0;
                        REMOVE_LINKS(child);
index dc7677d0c2c6b4884ae301cf2835242b7d216729..a45279da0789ad60311c9716dc91de1fd5a5dff6 100644 (file)
@@ -36,35 +36,6 @@ unsigned long prof_len = 0;
 #define _S(nr) (1<<((nr)-1))
 #define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
 
-static void show_task(int nr,struct task_struct * p)
-{
-       int i,j = 4096-sizeof(struct task_struct);
-
-       printk("%d: pid=%d, state=%d, father=%d, child=%d, ",(p == current)?-nr:nr,p->pid,
-               p->state, p->p_pptr->pid, p->p_cptr ? p->p_cptr->pid : -1);
-       i=0;
-       while (i<j && !((char *)(p+1))[i])
-               i++;
-       printk("%d/%d chars free in kstack\n\r",i,j);
-       printk("   PC=%08X.", *(1019 + (unsigned long *) p));
-       if (p->p_ysptr || p->p_osptr) 
-               printk("   Younger sib=%d, older sib=%d\n\r", 
-                       p->p_ysptr ? p->p_ysptr->pid : -1,
-                       p->p_osptr ? p->p_osptr->pid : -1);
-       else
-               printk("\n\r");
-}
-
-void show_state(void)
-{
-       int i;
-
-       printk("\rTask-info:\n\r");
-       for (i=0 ; i<NR_TASKS ; i++)
-               if (task[i])
-                       show_task(i,task[i]);
-}
-
 #define LATCH (1193180/HZ)
 
 extern void mem_use(void);
@@ -72,12 +43,8 @@ extern void mem_use(void);
 extern int timer_interrupt(void);
 extern int system_call(void);
 
-union task_union {
-       struct task_struct task;
-       char stack[PAGE_SIZE];
-};
-
-static union task_union init_task = {INIT_TASK, };
+static unsigned long init_kernel_stack[1024];
+static struct task_struct init_task = INIT_TASK;
 
 unsigned long volatile jiffies=0;
 unsigned long startup_time=0;
@@ -87,10 +54,10 @@ int jiffies_offset = 0;             /* # clock ticks to add to get "true
                                   who like to syncronize their machines
                                   to WWV :-) */
 
-struct task_struct *current = &(init_task.task);
+struct task_struct *current = &init_task;
 struct task_struct *last_task_used_math = NULL;
 
-struct task_struct * task[NR_TASKS] = {&(init_task.task), };
+struct task_struct * task[NR_TASKS] = {&init_task, };
 
 long user_stack [ PAGE_SIZE>>2 ] ;
 
@@ -220,15 +187,13 @@ void wake_up(struct wait_queue **q)
                                        need_resched = 1;
                        }
                }
-#ifdef DEBUG
                if (!tmp->next) {
-                       printk("wait_queue is bad\n");
+                       printk("wait_queue is bad (eip = %08x)\n",((unsigned long *) q)[-1]);
                        printk("        q = %08x\n",q);
                        printk("       *q = %08x\n",*q);
                        printk("      tmp = %08x\n",tmp);
                        break;
                }
-#endif
                tmp = tmp->next;
        } while (tmp != *q);
 }
@@ -236,17 +201,18 @@ void wake_up(struct wait_queue **q)
 static inline void __sleep_on(struct wait_queue **p, int state)
 {
        unsigned long flags;
+       struct wait_queue wait = { current, NULL };
 
        if (!p)
                return;
        if (current == task[0])
                panic("task[0] trying to sleep");
        current->state = state;
-       add_wait_queue(p,&current->wait);
+       add_wait_queue(p, &wait);
        save_flags(flags);
        sti();
        schedule();
-       remove_wait_queue(p,&current->wait);
+       remove_wait_queue(p, &wait);
        restore_flags(flags);
 }
 
@@ -529,6 +495,41 @@ int sys_nice(long increment)
        return 0;
 }
 
+static void show_task(int nr,struct task_struct * p)
+{
+       int i, j;
+       unsigned char * stack;
+
+       printk("%d: pid=%d, state=%d, father=%d, child=%d, ",(p == current)?-nr:nr,p->pid,
+               p->state, p->p_pptr->pid, p->p_cptr ? p->p_cptr->pid : -1);
+       i = 0;
+       j = 4096;
+       if (!(stack = (char *) p->kernel_stack_page)) {
+               stack = (char *) init_kernel_stack;
+               j = sizeof(init_kernel_stack);
+       }
+       while (i<j && !*(stack++))
+               i++;
+       printk("%d/%d chars free in kstack\n\r",i,j);
+       printk("   PC=%08X.", *(1019 + (unsigned long *) p));
+       if (p->p_ysptr || p->p_osptr) 
+               printk("   Younger sib=%d, older sib=%d\n\r", 
+                       p->p_ysptr ? p->p_ysptr->pid : -1,
+                       p->p_osptr ? p->p_osptr->pid : -1);
+       else
+               printk("\n\r");
+}
+
+void show_state(void)
+{
+       int i;
+
+       printk("\rTask-info:\n\r");
+       for (i=0 ; i<NR_TASKS ; i++)
+               if (task[i])
+                       show_task(i,task[i]);
+}
+
 void sched_init(void)
 {
        int i;
@@ -536,8 +537,8 @@ void sched_init(void)
 
        if (sizeof(struct sigaction) != 16)
                panic("Struct sigaction MUST be 16 bytes");
-       set_tss_desc(gdt+FIRST_TSS_ENTRY,&(init_task.task.tss));
-       set_ldt_desc(gdt+FIRST_LDT_ENTRY,&(init_task.task.ldt));
+       set_tss_desc(gdt+FIRST_TSS_ENTRY,&init_task.tss);
+       set_ldt_desc(gdt+FIRST_LDT_ENTRY,&init_task.ldt);
        set_system_gate(0x80,&system_call);
        p = gdt+2+FIRST_TSS_ENTRY;
        for(i=1 ; i<NR_TASKS ; i++) {
index 6de8470a077a6f31041983286a46dcdb76a318d4..3507ed3d232cb567948e900d046b84b839db5f79 100644 (file)
@@ -72,6 +72,8 @@ signal                = 12
 sigaction      = 16            # MUST be 16 (=len of sigaction)
 blocked                = (33*16)
 saved_kernel_stack = ((33*16)+4)
+kernel_stack_page = ((33*16)+8)
+flags          = ((33*16)+12)
 
 /*
  * offsets within sigaction
@@ -122,8 +124,29 @@ _system_call:
        movl $-ENOSYS,EAX(%esp)
        cmpl _NR_syscalls,%eax
        jae ret_from_sys_call
-       call _sys_call_table(,%eax,4)
+       movl _current,%ebx
+       testl $0x20,flags(%ebx)         # PF_TRACESYS
+       je 1f
+       pushl $0
+       pushl %ebx
+       pushl $5                        # SIGTRAP
+       call _send_sig
+       addl $12,%esp
+       call _schedule
+       movl ORIG_EAX(%esp),%eax
+1:     call _sys_call_table(,%eax,4)
        movl %eax,EAX(%esp)             # save the return value
+       movl _current,%eax
+       testl $0x20,flags(%eax)         # PF_TRACESYS
+       je ret_from_sys_call
+       cmpl $0,signal(%eax)
+       jne ret_from_sys_call           # ptrace would clear signal
+       pushl $0
+       pushl %eax
+       pushl $5                        # SIGTRAP
+       call _send_sig
+       addl $12,%esp
+       call _schedule
        .align 4,0x90
 ret_from_sys_call:
        movl EFLAGS(%esp),%eax          # check VM86 flag: CS/SS are
index 5a2157620d8780a058f81528a0a8017a6f76c080..fb6eaaeb3d560c77f8f6ee1e87d84dbc14b0e701 100644 (file)
@@ -41,7 +41,7 @@ malloc.o : malloc.c /usr/include/linux/kernel.h /usr/include/linux/mm.h /usr/inc
   /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
   /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
-  /usr/include/asm/system.h 
+  /usr/include/linux/string.h /usr/include/asm/system.h 
 open.o : open.c /usr/include/linux/unistd.h /usr/lib/gcc-lib/i386-linux/2.2.2d/include/stdarg.h 
 setsid.o : setsid.c /usr/include/linux/types.h /usr/include/linux/unistd.h 
 string.o : string.c /usr/include/linux/types.h /usr/include/linux/string.h 
index fe0a74ce40396450b972038ab54d19940bdb5438..d0e42c9ee659ebe8ed1a96b6fb4c55d6edf77963 100644 (file)
@@ -11,7 +11,7 @@
  *
  * The general game plan is that each page (called a bucket) will only hold
  * objects of a given size.  When all of the object on a page are released,
- * the page can be returned to the general free pool.  When malloc() is
+ * the page can be returned to the general free pool.  When kmalloc() is
  * called, it looks for the smallest bucket size which will fulfill its
  * request, and allocate a piece of memory from that bucket pool.
  *
  * corresponds to 1 megabyte worth of bucket pages.)  If the kernel is using
  * that much allocated memory, it's probably doing something wrong.  :-)
  *
- * Note: malloc() and free() both call get_free_page() and free_page()
+ * Note: kmalloc() and kfree() both call get_free_page() and free_page()
  *     in sections of code where interrupts are turned off, to allow
- *     malloc() and free() to be safely called from an interrupt routine.
+ *     kmalloc() and kfree() to be safely called from an interrupt routine.
  *     (We will probably need this functionality when networking code,
  *     particularily things like NFS, is added to Linux.)  However, this
  *     presumes that get_free_page() and free_page() are interrupt-level
  *     safe, which they may not be once paging is added.  If this is the
- *     case, we will need to modify malloc() to keep a few unused pages
+ *     case, we will need to modify kmalloc() to keep a few unused pages
  *     "pre-allocated" so that it can safely draw upon those pages if
  *     it is called from an interrupt routine.
  *
  *     Another concern is that get_free_page() should not sleep; if it
  *     does, the code is carefully ordered so as to avoid any race
- *     conditions.  The catch is that if malloc() is called re-entrantly,
+ *     conditions.  The catch is that if kmalloc() is called re-entrantly,
  *     there is a chance that unecessary pages will be grabbed from the
  *     system.  Except for the pages for the bucket descriptor page, the
  *     extra pages will eventually get released back to the system, though,
  */
 
 /* I'm going to modify it to keep some free pages around.  Get free page
-   can sleep, and tcp/ip needs to call malloc at interrupt time  (Or keep
+   can sleep, and tcp/ip needs to call kmalloc at interrupt time  (Or keep
    big buffers around for itself.)  I guess I'll have return from
    syscall fill up the free page descriptors. -RAB */
 
-/* since the advent of GFP_ATOMIC, I've changed the malloc code to
-   use it and return NULL if it can't get a page. -RAB */
+/* since the advent of GFP_ATOMIC, I've changed the kmalloc code to
+   use it and return NULL if it can't get a page. -RAB  */
+/* (mostly just undid the previous changes -RAB) */
+
+/* I've added the priority argument to kmalloc so routines can
+   sleep on memory if they want. - RAB */
+
+/* I've also got to make sure that kmalloc is reentrant now. */
 
 #include <linux/kernel.h>
 #include <linux/mm.h>
@@ -104,14 +110,23 @@ static struct bucket_desc *free_bucket_desc = (struct bucket_desc *) 0;
 /*
  * This routine initializes a bucket description page.
  */
-static inline int init_bucket_desc()
+
+/* It assumes it is called with interrupts on. and will
+   return that way.  It also can sleep if priority != GFP_ATOMIC. */
+static inline int init_bucket_desc(int priority)
 {
        struct bucket_desc *bdesc, *first;
        int i;
        /* this turns interrupt on, so we should be carefull. */
-       first = bdesc = (struct bucket_desc *) get_free_page(GFP_ATOMIC);
+       first = bdesc = (struct bucket_desc *) get_free_page(priority);
        if (!bdesc)
                return 1;
+
+       /* At this point it is possible that we have slept and 
+          free has been called etc.  So we might not actually need
+          this page anymore. */
+
        for (i = PAGE_SIZE/sizeof(struct bucket_desc); i > 1; i--) {
                bdesc->next = bdesc+1;
                bdesc++;
@@ -120,13 +135,16 @@ static inline int init_bucket_desc()
         * This is done last, to avoid race conditions in case
         * get_free_page() sleeps and this routine gets called again....
         */
-       /* Get free page will not sleep because of the GFP_ATOMIC */
+
+       cli();
        bdesc->next = free_bucket_desc;
        free_bucket_desc = first;
+       sti();
        return (0);
 }
 
-void *malloc(unsigned int len)
+void *
+kmalloc(unsigned int len, int priority)
 {
        struct _bucket_dir      *bdir;
        struct bucket_desc      *bdesc;
@@ -136,70 +154,108 @@ void *malloc(unsigned int len)
         * First we search the bucket_dir to find the right bucket change
         * for this request.
         */
+
+       /* The sizes are static so there is no reentry problem here. */
        for (bdir = bucket_dir; bdir->size; bdir++)
                if (bdir->size >= len)
                        break;
 
        if (!bdir->size) {
-               printk("malloc called with impossibly large argument (%d)\n", len);
+              /* This should be changed for sizes > 1 page. */
+               printk("kmalloc called with impossibly large argument (%d)\n", len);
                return NULL;
        }
-       len = bdir->size;
+
        /*
         * Now we search for a bucket descriptor which has free space
         */
        cli();  /* Avoid race conditions */
-       for (bdesc = bdir->chain; bdesc; bdesc = bdesc->next)
-               if (bdesc->freeptr)
+       for (bdesc = bdir->chain; bdesc != NULL; bdesc = bdesc->next)
+               if (bdesc->freeptr != NULL || bdesc->page == NULL)
                        break;
        /*
         * If we didn't find a bucket with free space, then we'll
         * allocate a new one.
         */
-       if (!bdesc) {
-               char *cp;
-               int i;
-
-               if (!free_bucket_desc)
-                       if (init_bucket_desc()) {
-                               sti();
-                               return NULL;
-                       }
-               bdesc = free_bucket_desc;
+       if (!bdesc)
+         {
+           char *cp;
+           int i;
+           
+           /* This must be a while because it is possible
+              to get interrupted after init_bucket_desc
+              and before cli.  The interrupt could steal
+              our free_desc. */
+           
+           while (!free_bucket_desc)
+             {
+               sti();  /* This might happen anyway, so we
+                          might as well make it explicit. */
+               if (init_bucket_desc(priority))
+                 {
+                   return NULL;
+                 }
+               cli(); /* Turn them back off. */
+             }
+           
+           bdesc = free_bucket_desc;
+           free_bucket_desc = bdesc->next;
+
+           /* get_free_page will turn interrupts back
+              on.  So we might as well do it
+              ourselves. */
+
+           sti();
+           bdesc->refcnt = 0;
+           bdesc->bucket_size = bdir->size;
+           bdesc->page = bdesc->freeptr =
+             (void *)cp = get_free_page(priority);
+           
+           if (!cp)
+             {
+
+               /* put bdesc back on the free list. */
+               cli();
+               bdesc->next = free_bucket_desc;
                free_bucket_desc = bdesc->next;
-               bdesc->refcnt = 0;
-               bdesc->bucket_size = len;
-               bdesc->page = bdesc->freeptr =
-                 (void *) cp = get_free_page(GFP_ATOMIC);
-               if (!cp) {
-                       sti();
-                       return NULL;
-               }
-               /* Set up the chain of free objects */
-               for (i=PAGE_SIZE/len; i > 1; i--) {
-                       *((char **) cp) = cp + len;
-                       cp += len;
-               }
-               *((char **) cp) = 0;
-               bdesc->next = bdir->chain; /* OK, link it in! */
-               bdir->chain = bdesc;
-       }
+               sti();
+
+               return NULL;
+             }
+           
+           /* Set up the chain of free objects */
+           for (i=PAGE_SIZE/bdir->size; i > 1; i--)
+             {
+               *((char **) cp) = cp + bdir->size;
+               cp += bdir->size;
+             }
+           
+           *((char **) cp) = 0;
+
+           /* turn interrupts back off for putting the
+              thing onto the chain. */
+           cli();
+           /* remember bdir is not changed. */
+           bdesc->next = bdir->chain; /* OK, link it in! */
+           bdir->chain = bdesc;
+
+         }
+
        retval = (void *) bdesc->freeptr;
        bdesc->freeptr = *((void **) retval);
        bdesc->refcnt++;
        sti();  /* OK, we're safe again */
-       memset(retval, 0, len);
        return retval;
 }
 
 /*
- * Here is the free routine.  If you know the size of the object that you
- * are freeing, then free_s() will use that information to speed up the
+ * Here is the kfree routine.  If you know the size of the object that you
+ * are freeing, then kfree_s() will use that information to speed up the
  * search for the bucket descriptor.
  *
- * We will #define a macro so that "free(x)" is becomes "free_s(x, 0)"
+ * We will #define a macro so that "kfree(x)" is becomes "kfree_s(x, 0)"
  */
-void free_s(void *obj, int size)
+void kfree_s(void *obj, int size)
 {
        void            *page;
        struct _bucket_dir      *bdir;
@@ -207,22 +263,35 @@ void free_s(void *obj, int size)
 
        /* Calculate what page this object lives in */
        page = (void *)  ((unsigned long) obj & 0xfffff000);
+
        /* Now search the buckets looking for that page */
-       for (bdir = bucket_dir; bdir->size; bdir++) {
-               prev = 0;
-               /* If size is zero then this conditional is always false */
-               if (bdir->size < size)
-                       continue;
-               for (bdesc = bdir->chain; bdesc; bdesc = bdesc->next) {
-                       if (bdesc->page == page)
-                               goto found;
-                       prev = bdesc;
-               }
-       }
-       printk("Bad address passed to kernel free_s()");
+       for (bdir = bucket_dir; bdir->size; bdir++)
+         {
+           prev = 0;
+           /* If size is zero then this conditional is always true */
+           if (bdir->size >= size)
+             {
+               /* We have to turn off interrupts here because
+                  we are descending the chain.  If something
+                  changes it in the middle we could suddenly
+                  find ourselves descending the free list.
+                  I think this would only cause a memory
+                  leak, but better safe than sorry. */
+               cli(); /* To avoid race conditions */
+               for (bdesc = bdir->chain; bdesc; bdesc = bdesc->next)
+                 {
+                   if (bdesc->page == page)
+                     goto found;
+                   prev = bdesc;
+                 }
+             }
+         }
+
+       printk("Bad address passed to kernel kfree_s(%X, %d)\n",obj, size);
+       sti();
        return;
 found:
-       cli(); /* To avoid race conditions */
+       /* interrupts are off here. */
        *((void **)obj) = bdesc->freeptr;
        bdesc->freeptr = obj;
        bdesc->refcnt--;
@@ -240,12 +309,12 @@ found:
                        prev->next = bdesc->next;
                else {
                        if (bdir->chain != bdesc)
-                               panic("malloc bucket chains corrupted");
+                               panic("kmalloc bucket chains corrupted");
                        bdir->chain = bdesc->next;
                }
-               free_page((unsigned long) bdesc->page);
                bdesc->next = free_bucket_desc;
                free_bucket_desc = bdesc;
+               free_page((unsigned long) bdesc->page);
        }
        sti();
        return;
index 62300136b7a4ad5405553a943c38334002fbd2d7..7e9e19a15ff38c42ff921dac4c9a9ea07c0b849b 100644 (file)
@@ -36,8 +36,8 @@ memory.o : memory.c /usr/include/asm/system.h /usr/include/linux/signal.h /usr/i
   /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h \
   /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h \
   /usr/include/linux/kernel.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/errno.h \
-  /usr/include/linux/string.h 
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  /usr/include/linux/errno.h /usr/include/linux/string.h 
 mmap.o : mmap.c /usr/include/linux/stat.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
   /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
@@ -45,9 +45,9 @@ mmap.o : mmap.c /usr/include/linux/stat.h /usr/include/linux/sched.h /usr/includ
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
   /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/errno.h \
-  /usr/include/linux/mman.h /usr/include/linux/string.h /usr/include/asm/segment.h \
-  /usr/include/asm/system.h 
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  /usr/include/linux/errno.h /usr/include/linux/mman.h /usr/include/linux/string.h \
+  /usr/include/asm/segment.h /usr/include/asm/system.h 
 swap.o : swap.c /usr/include/linux/mm.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
   /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
   /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
@@ -55,5 +55,5 @@ swap.o : swap.c /usr/include/linux/mm.h /usr/include/linux/fs.h /usr/include/lin
   /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/kernel.h \
   /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/errno.h /usr/include/linux/string.h \
-  /usr/include/linux/stat.h /usr/include/asm/system.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/errno.h \
+  /usr/include/linux/string.h /usr/include/linux/stat.h /usr/include/asm/system.h 
index 6512d7fd6fdc6485b954e3d036d1cbf6e403ade2..07f074b6fa32cda62e9d7bebed31905fb72c7a1c 100644 (file)
@@ -62,9 +62,9 @@ unsigned short * mem_map = NULL;
 void oom(struct task_struct * task)
 {
        printk("\nout of memory\n");
-       task->sigaction[SIGSEGV-1].sa_handler = NULL;
-       task->blocked &= ~(1<<(SIGSEGV-1));
-       send_sig(SIGSEGV,task,1);
+       task->sigaction[SIGKILL-1].sa_handler = NULL;
+       task->blocked &= ~(1<<(SIGKILL-1));
+       send_sig(SIGKILL,task,1);
 }
 
 static void free_one_table(unsigned long * page_dir)
@@ -446,31 +446,62 @@ unsigned long put_dirty_page(struct task_struct * tsk, unsigned long page, unsig
        return page;
 }
 
-static void un_wp_page(unsigned long * table_entry, struct task_struct * task)
+/*
+ * This routine handles present pages, when users try to write
+ * to a shared page. It is done by copying the page to a new address
+ * and decrementing the shared-page counter for the old page.
+ *
+ * Fixed the routine to repeat a bit more: this is slightly slower,
+ * but there were race-conditions in the old code..
+ */
+void do_wp_page(unsigned long error_code, unsigned long address,
+       struct task_struct * tsk, unsigned long user_esp)
 {
-       unsigned long old_page;
+       unsigned long pde, pte, old_page, dirty;
        unsigned long new_page = 0;
-       unsigned long dirty;
 
 repeat:
-       old_page = *table_entry;
-       if (!(old_page & 1)) {
+       pde = tsk->tss.cr3 + ((address>>20) & 0xffc);
+       pte = *(unsigned long *) pde;
+       if (!(pte & PAGE_PRESENT)) {
+               if (new_page)
+                       free_page(new_page);
+               return;
+       }
+       if ((pte & 7) != 7 || pte >= high_memory) {
+               printk("do_wp_page: bogus page-table at address %08x (%08x)\n",address,pte);
+               *(unsigned long *) pde = BAD_PAGETABLE | 7;
+               send_sig(SIGKILL, tsk, 1);
+               if (new_page)
+                       free_page(new_page);
+               return;
+       }
+       pte &= 0xfffff000;
+       pte += (address>>10) & 0xffc;
+       old_page = *(unsigned long *) pte;
+       if (!(old_page & PAGE_PRESENT)) {
                if (new_page)
                        free_page(new_page);
                return;
        }
-       dirty = old_page & PAGE_DIRTY;
-       old_page &= 0xfffff000;
        if (old_page >= high_memory) {
+               printk("do_wp_page: bogus page at address %08x (%08x)\n",address,old_page);
+               *(unsigned long *) pte = BAD_PAGE | 7;
+               send_sig(SIGKILL, tsk, 1);
+               if (new_page)
+                       free_page(new_page);
+               return;
+       }
+       if (old_page & PAGE_RW) {
                if (new_page)
                        free_page(new_page);
-               printk("bad page address\n\r");
-               send_sig(SIGSEGV, task, 1);
-               *table_entry = BAD_PAGE | 7;
                return;
        }
+       tsk->min_flt++;
+       dirty = old_page & PAGE_DIRTY;
+       old_page &= 0xfffff000;
        if (mem_map[MAP_NR(old_page)]==1) {
-               *table_entry |= 2;
+               *(unsigned long *) pte |= 2;
                invalidate();
                if (new_page)
                        free_page(new_page);
@@ -482,58 +513,17 @@ repeat:
                copy_page(old_page,new_page);
        else {
                new_page = BAD_PAGE;
-               oom(task);
+               oom(tsk);
        }
-       *table_entry = new_page | dirty | PAGE_ACCESSED | 7;
+       *(unsigned long *) pte = new_page | dirty | PAGE_ACCESSED | 7;
        free_page(old_page);
        invalidate();
-}      
-
-/*
- * This routine handles present pages, when users try to write
- * to a shared page. It is done by copying the page to a new address
- * and decrementing the shared-page counter for the old page.
- *
- * If it's in code space we exit with a segment error.
- */
-void do_wp_page(unsigned long error_code, unsigned long address,
-       struct task_struct * tsk, unsigned long user_esp)
-{
-       unsigned long pde, pte, page;
-
-       pde = tsk->tss.cr3 + ((address>>20) & 0xffc);
-       pte = *(unsigned long *) pde;
-       if ((pte & 3) != 3) {
-               printk("do_wp_page: bogus page-table at address %08x (%08x)\n",address,pte);
-               *(unsigned long *) pde = BAD_PAGETABLE | 7;
-               send_sig(SIGSEGV, tsk, 1);
-               return;
-       }
-       pte &= 0xfffff000;
-       pte += (address>>10) & 0xffc;
-       page = *(unsigned long *) pte;
-       if ((page & 3) != 1) {
-               printk("do_wp_page: bogus page at address %08x (%08x)\n",address,page);
-               *(unsigned long *) pte = BAD_PAGE | 7;
-               send_sig(SIGSEGV, tsk, 1);
-               return;
-       }
-       tsk->min_flt++;
-       un_wp_page((unsigned long *) pte, tsk);
 }
 
 void write_verify(unsigned long address)
 {
-       unsigned long page;
-
-       page = *(unsigned long *) (current->tss.cr3 + ((address>>20) & 0xffc));
-       if (!(page & PAGE_PRESENT))
-               return;
-       page &= 0xfffff000;
-       page += ((address>>10) & 0xffc);
-       if ((3 & *(unsigned long *) page) == 1)  /* non-writeable, present */
-               un_wp_page((unsigned long *) page, current);
-       return;
+       if (address < TASK_SIZE)
+               do_wp_page(1,address,current,0);
 }
 
 static void get_empty_page(struct task_struct * tsk, unsigned long address)
@@ -679,10 +669,8 @@ void do_no_page(unsigned long error_code, unsigned long address,
        page &= 0xfffff000;
        page += (address >> 10) & 0xffc;
        tmp = *(unsigned long *) page;
-       if (tmp & 1) {
-               printk("bogus do_no_page\n");
+       if (tmp & 1)
                return;
-       }
        ++tsk->rss;
        if (tmp) {
                ++tsk->maj_flt;
@@ -757,6 +745,74 @@ void do_no_page(unsigned long error_code, unsigned long address,
        oom(current);
 }
 
+/*
+ * This routine handles page faults.  It determines the address,
+ * and the problem, and then passes it off to one of the appropriate
+ * routines.
+ */
+void do_page_fault(unsigned long *esp, unsigned long error_code)
+{
+       unsigned long address;
+       unsigned long user_esp = 0;
+       unsigned int bit;
+       extern void die_if_kernel();
+
+       /* get the address */
+       __asm__("movl %%cr2,%0":"=r" (address));
+       if (address < TASK_SIZE) {
+               if (error_code & 4) {   /* user mode access? */
+                       if (esp[2] & VM_MASK) {
+                               bit = (address - 0xA0000) >> PAGE_SHIFT;
+                               if (bit < 32)
+                                       current->screen_bitmap |= 1 << bit;
+                       } else 
+                               user_esp = esp[3];
+               }
+               if (error_code & 1)
+                       do_wp_page(error_code, address, current, user_esp);
+               else
+                       do_no_page(error_code, address, current, user_esp);
+               return;
+       }
+       printk("Unable to handle kernel paging request at address %08x\n",address);
+       die_if_kernel("Oops",esp,error_code);
+       do_exit(SIGKILL);
+}
+
+/*
+ * BAD_PAGE is the page that is used for page faults when linux
+ * is out-of-memory. Older versions of linux just did a
+ * do_exit(), but using this instead means there is less risk
+ * for a process dying in kernel mode, possibly leaving a inode
+ * unused etc..
+ *
+ * BAD_PAGETABLE is the accompanying page-table: it is initialized
+ * to point to BAD_PAGE entries.
+ */
+unsigned long __bad_pagetable(void)
+{
+       extern char empty_bad_page_table[PAGE_SIZE];
+
+       __asm__ __volatile__("cld ; rep ; stosl"
+               ::"a" (7+BAD_PAGE),
+                 "D" ((long) empty_bad_page_table),
+                 "c" (1024)
+               :"di","cx");
+       return (unsigned long) empty_bad_page_table;
+}
+
+unsigned long __bad_page(void)
+{
+       extern char empty_bad_page[PAGE_SIZE];
+
+       __asm__ __volatile__("cld ; rep ; stosl"
+               ::"a" (0),
+                 "D" ((long) empty_bad_page),
+                 "c" (1024)
+               :"di","cx");
+       return (unsigned long) empty_bad_page;
+}
+
 void show_mem(void)
 {
        int i,free = 0,total = 0,reserved = 0;
@@ -783,40 +839,6 @@ void show_mem(void)
        printk("%d pages shared\n",shared);
 }
 
-
-/*
- * This routine handles page faults.  It determines the address,
- * and the problem, and then passes it off to one of the appropriate
- * routines.
- */
-void do_page_fault(unsigned long *esp, unsigned long error_code)
-{
-       unsigned long address;
-       unsigned long user_esp = 0;
-       extern void die_if_kernel();
-
-       /* get the address */
-       __asm__("movl %%cr2,%0":"=r" (address));
-       if (address >= TASK_SIZE) {
-               printk("Unable to handle kernel paging request at address %08x\n",address);
-               die_if_kernel("Oops",esp,error_code);
-               do_exit(SIGSEGV);
-       }
-       if (esp[2] & VM_MASK) {
-               unsigned int bit;
-
-               bit = (address - 0xA0000) >> PAGE_SHIFT;
-               if (bit < 32)
-                       current->screen_bitmap |= 1 << bit;
-       } else
-               if ((0xffff & esp[1]) == 0xf)
-                       user_esp = esp[3];
-       if (!(error_code & 1))
-               do_no_page(error_code, address, current, user_esp);
-       else
-               do_wp_page(error_code, address, current, user_esp);
-}
-
 /*
  * paging_init() sets up the page tables - note that the first 4MB are
  * already mapped by head.S.
@@ -831,6 +853,12 @@ unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
        unsigned long tmp;
        unsigned long address;
 
+/*
+ * Physical page 0 is special: it's a "zero-page", and is guaranteed to
+ * stay that way - it's write-protected and when there is a c-o-w, the
+ * mm handler treats it specially.
+ */
+       memset((void *) 0, 0, 4096);
        start_mem += 4095;
        start_mem &= 0xfffff000;
        address = 0;
index f69daf052ea3c55d6afc8479712d7738ea9363fb..b29a4d8ffb55ced76c682e482b4202cf58f21f78 100644 (file)
@@ -10,8 +10,8 @@
 # only these two lines should need to be changed to remove inet sockets.
 # (and the tcp/tcpip.o in net.o)
 
-SUBDIRS                =# tcp
-SOCK_FLAGS     =# -DINET_SOCKETS
+SUBDIRS                = tcp
+SOCK_FLAGS     = -DINET_SOCKETS
 
 .c.o:
        $(CC) $(CFLAGS) $(SOCK_FLAGS) -c $<
@@ -23,7 +23,7 @@ SOCK_FLAGS    =# -DINET_SOCKETS
 OBJS   =  socket.o unix.o 
 
 net.o: $(OBJS) subdirs
-       $(LD) -r -o net.o $(OBJS)# tcp/tcpip.o
+       $(LD) -r -o net.o $(OBJS) tcp/tcpip.o
 
 
 subdirs: dummy
@@ -50,9 +50,10 @@ socket.o : socket.c /usr/include/linux/signal.h /usr/include/linux/errno.h /usr/
   /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h \
   /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h \
   /usr/include/linux/kernel.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/stat.h \
-  /usr/include/linux/socket.h /usr/include/linux/fcntl.h /usr/include/linux/termios.h \
-  /usr/include/asm/system.h /usr/include/asm/segment.h kern_sock.h socketcall.h 
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  /usr/include/linux/stat.h /usr/include/linux/socket.h /usr/include/linux/fcntl.h \
+  /usr/include/linux/termios.h /usr/include/asm/system.h /usr/include/asm/segment.h \
+  kern_sock.h socketcall.h 
 unix.o : unix.c /usr/include/linux/signal.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
   /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
@@ -60,7 +61,7 @@ unix.o : unix.c /usr/include/linux/signal.h /usr/include/linux/sched.h /usr/incl
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/errno.h /usr/include/linux/string.h \
-  /usr/include/linux/stat.h /usr/include/linux/socket.h /usr/include/linux/un.h \
-  /usr/include/linux/fcntl.h /usr/include/linux/termios.h /usr/include/asm/system.h \
-  /usr/include/asm/segment.h kern_sock.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/errno.h \
+  /usr/include/linux/string.h /usr/include/linux/stat.h /usr/include/linux/socket.h \
+  /usr/include/linux/un.h /usr/include/linux/fcntl.h /usr/include/linux/termios.h \
+  /usr/include/asm/system.h /usr/include/asm/segment.h kern_sock.h 
index 3928a698f6de73fd88c8c5745cf6227abf4fc7bc..e8c3ab6856bd144dadacbc53772741470e214ac9 100644 (file)
@@ -81,29 +81,31 @@ static struct wait_queue *socket_wait_free = NULL;
 static int
 get_fd(struct inode *inode)
 {
-       int fd, i;
+       int fd;
        struct file *file;
 
        /*
         * find a file descriptor suitable for return to the user.
         */
+       file = get_empty_filp();
+       if (!file)
+               return -1;
        for (fd = 0; fd < NR_OPEN; ++fd)
                if (!current->filp[fd])
                        break;
-       if (fd == NR_OPEN)
-               return -1;
-       current->close_on_exec &= ~(1 << fd);
-       for (file = file_table, i = 0; i < NR_FILE; ++i, ++file)
-               if (!file->f_count)
-                       break;
-       if (i == NR_FILE)
+       if (fd == NR_OPEN) {
+               file->f_count = 0;
                return -1;
+       }
+       FD_CLR(fd, &current->close_on_exec);
        current->filp[fd] = file;
        file->f_op = &socket_file_ops;
        file->f_mode = 3;
        file->f_flags = 0;
        file->f_count = 1;
        file->f_inode = inode;
+       if (inode)
+               inode->i_count++;
        file->f_pos = 0;
        return fd;
 }
@@ -116,11 +118,11 @@ get_fd(struct inode *inode)
 static inline void
 toss_fd(int fd)
 {
-       current->filp[fd]->f_inode = NULL;      /* safe from iput */
+  /* the count protects us from iput. */
        sys_close(fd);
 }
 
-static inline struct socket *
+struct socket *
 socki_lookup(struct inode *inode)
 {
        struct socket *sock;
@@ -227,6 +229,8 @@ sock_release(struct socket *sock)
                sock_release_peer(peersock);
        sock->state = SS_FREE;          /* this really releases us */
        wake_up(&socket_wait_free);
+       iput(SOCK_INODE(sock)); /* we need to do this.  If sock alloc was
+                                  called we already have an inode. */
 }
 
 static int
@@ -576,18 +580,19 @@ sock_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_addrlen)
                return i;
        }
 
-       if ((fd = get_fd(SOCK_INODE(newsock))) < 0) {
-               sock_release(newsock);
-               return -EINVAL;
-       }
        i = newsock->ops->accept(sock, newsock, file->f_flags);
 
        if ( i < 0)
          {
-            sys_close (fd);
-            return (i);
+           sock_release(newsock);
+           return (i);
          }
 
+       if ((fd = get_fd(SOCK_INODE(newsock))) < 0) {
+               sock_release(newsock);
+               return -EINVAL;
+       }
+
        PRINTK("sys_accept: connected socket 0x%x via 0x%x\n",
               sock, newsock);
 
index fe99baf8d70a4afa6cc489572632f3f521cb860e..e4f7131572269282a5ce3a112af8b8348252ab8c 100644 (file)
@@ -47,10 +47,10 @@ arp.o : arp.c /usr/include/linux/types.h /usr/include/linux/string.h /usr/includ
   /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h \
   /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h \
   /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
-  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/socket.h \
-  /usr/include/netinet/in.h /usr/include/features.h /usr/include/sys/socket.h \
-  /usr/include/traditional.h /usr/include/asm/system.h timer.h ip.h dev.h /usr/include/linux/sock_ioctl.h \
-  eth.h tcp.h sock.h arp.h 
+  /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
+  /usr/include/linux/socket.h /usr/include/netinet/in.h /usr/include/features.h \
+  /usr/include/sys/socket.h /usr/include/traditional.h /usr/include/asm/system.h \
+  timer.h ip.h dev.h /usr/include/linux/sock_ioctl.h eth.h tcp.h sock.h arp.h 
 dev.o : dev.c /usr/include/asm/segment.h /usr/include/asm/system.h /usr/include/linux/types.h \
   /usr/include/linux/kernel.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
@@ -59,9 +59,9 @@ dev.o : dev.c /usr/include/asm/segment.h /usr/include/asm/system.h /usr/include/
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/signal.h /usr/include/linux/time.h \
   /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
-  /usr/include/linux/string.h /usr/include/linux/socket.h /usr/include/netinet/in.h \
-  /usr/include/features.h /usr/include/sys/socket.h /usr/include/traditional.h \
-  /usr/include/asm/memory.h dev.h eth.h timer.h ip.h /usr/include/linux/sock_ioctl.h \
+  /usr/include/linux/math_emu.h /usr/include/linux/string.h /usr/include/linux/socket.h \
+  /usr/include/netinet/in.h /usr/include/features.h /usr/include/sys/socket.h \
+  /usr/include/traditional.h dev.h eth.h timer.h ip.h /usr/include/linux/sock_ioctl.h \
   tcp.h sock.h /usr/include/linux/errno.h arp.h 
 eth.o : eth.c /usr/include/asm/segment.h /usr/include/asm/system.h /usr/include/linux/types.h \
   /usr/include/linux/kernel.h /usr/include/linux/sched.h /usr/include/linux/head.h \
@@ -71,9 +71,9 @@ eth.o : eth.c /usr/include/asm/segment.h /usr/include/asm/system.h /usr/include/
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/signal.h /usr/include/linux/time.h \
   /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
-  /usr/include/linux/string.h /usr/include/linux/socket.h /usr/include/netinet/in.h \
-  /usr/include/features.h /usr/include/sys/socket.h /usr/include/traditional.h \
-  /usr/include/asm/memory.h dev.h eth.h timer.h ip.h /usr/include/linux/sock_ioctl.h \
+  /usr/include/linux/math_emu.h /usr/include/linux/string.h /usr/include/linux/socket.h \
+  /usr/include/netinet/in.h /usr/include/features.h /usr/include/sys/socket.h \
+  /usr/include/traditional.h dev.h eth.h timer.h ip.h /usr/include/linux/sock_ioctl.h \
   tcp.h sock.h /usr/include/linux/errno.h arp.h 
 icmp.o : icmp.c /usr/include/linux/types.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
@@ -82,9 +82,9 @@ icmp.o : icmp.c /usr/include/linux/types.h /usr/include/linux/sched.h /usr/inclu
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/fcntl.h /usr/include/linux/socket.h \
-  /usr/include/netinet/in.h /usr/include/features.h /usr/include/sys/socket.h \
-  /usr/include/traditional.h timer.h ip.h dev.h /usr/include/linux/sock_ioctl.h \
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/fcntl.h \
+  /usr/include/linux/socket.h /usr/include/netinet/in.h /usr/include/features.h \
+  /usr/include/sys/socket.h /usr/include/traditional.h timer.h ip.h dev.h /usr/include/linux/sock_ioctl.h \
   eth.h tcp.h sock.h /usr/include/linux/errno.h /usr/include/linux/timer.h /usr/include/asm/system.h \
   /usr/include/asm/segment.h ../kern_sock.h icmp.h 
 ip.o : ip.c /usr/include/asm/segment.h /usr/include/asm/system.h /usr/include/linux/types.h \
@@ -95,10 +95,10 @@ ip.o : ip.c /usr/include/asm/segment.h /usr/include/asm/system.h /usr/include/li
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/signal.h /usr/include/linux/time.h \
   /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
-  /usr/include/linux/string.h /usr/include/linux/socket.h /usr/include/netinet/in.h \
-  /usr/include/features.h /usr/include/sys/socket.h /usr/include/traditional.h \
-  timer.h ip.h dev.h /usr/include/linux/sock_ioctl.h eth.h tcp.h sock.h /usr/include/linux/errno.h \
-  arp.h icmp.h 
+  /usr/include/linux/math_emu.h /usr/include/linux/string.h /usr/include/linux/socket.h \
+  /usr/include/netinet/in.h /usr/include/features.h /usr/include/sys/socket.h \
+  /usr/include/traditional.h timer.h ip.h dev.h /usr/include/linux/sock_ioctl.h \
+  eth.h tcp.h sock.h /usr/include/linux/errno.h arp.h icmp.h 
 loopback.o : loopback.c /usr/include/linux/config.h /usr/include/linux/config.dist.h \
   /usr/include/linux/kernel.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
@@ -107,13 +107,13 @@ loopback.o : loopback.c /usr/include/linux/config.h /usr/include/linux/config.di
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/tty.h /usr/include/linux/termios.h \
-  /usr/include/asm/system.h /usr/include/linux/ptrace.h /usr/include/asm/segment.h \
-  /usr/include/asm/io.h /usr/include/asm/memory.h /usr/include/errno.h /usr/include/traditional.h \
-  /usr/include/linux/errno.h /usr/include/linux/fcntl.h /usr/include/netinet/in.h \
-  /usr/include/features.h /usr/include/sys/socket.h /usr/include/linux/socket.h \
-  dev.h eth.h timer.h ip.h /usr/include/linux/sock_ioctl.h tcp.h sock.h arp.h \
-  ../kern_sock.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/tty.h \
+  /usr/include/linux/termios.h /usr/include/asm/system.h /usr/include/linux/ptrace.h \
+  /usr/include/linux/string.h /usr/include/asm/segment.h /usr/include/asm/io.h \
+  /usr/include/errno.h /usr/include/traditional.h /usr/include/linux/errno.h /usr/include/linux/fcntl.h \
+  /usr/include/netinet/in.h /usr/include/features.h /usr/include/sys/socket.h \
+  /usr/include/linux/socket.h dev.h eth.h timer.h ip.h /usr/include/linux/sock_ioctl.h \
+  tcp.h sock.h arp.h ../kern_sock.h 
 pack_type.o : pack_type.c /usr/include/linux/stddef.h dev.h eth.h 
 packet.o : packet.c /usr/include/linux/types.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
@@ -122,9 +122,9 @@ packet.o : packet.c /usr/include/linux/types.h /usr/include/linux/sched.h /usr/i
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/fcntl.h /usr/include/linux/socket.h \
-  /usr/include/netinet/in.h /usr/include/features.h /usr/include/sys/socket.h \
-  /usr/include/traditional.h timer.h ip.h dev.h /usr/include/linux/sock_ioctl.h \
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/fcntl.h \
+  /usr/include/linux/socket.h /usr/include/netinet/in.h /usr/include/features.h \
+  /usr/include/sys/socket.h /usr/include/traditional.h timer.h ip.h dev.h /usr/include/linux/sock_ioctl.h \
   eth.h tcp.h sock.h /usr/include/linux/errno.h /usr/include/linux/timer.h /usr/include/asm/system.h \
   /usr/include/asm/segment.h ../kern_sock.h 
 protocols.o : protocols.c /usr/include/asm/segment.h /usr/include/asm/system.h \
@@ -135,9 +135,9 @@ protocols.o : protocols.c /usr/include/asm/segment.h /usr/include/asm/system.h \
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/string.h /usr/include/linux/socket.h \
-  /usr/include/netinet/in.h /usr/include/features.h /usr/include/sys/socket.h \
-  /usr/include/traditional.h timer.h ip.h dev.h /usr/include/linux/sock_ioctl.h \
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/string.h \
+  /usr/include/linux/socket.h /usr/include/netinet/in.h /usr/include/features.h \
+  /usr/include/sys/socket.h /usr/include/traditional.h timer.h ip.h dev.h /usr/include/linux/sock_ioctl.h \
   eth.h tcp.h sock.h icmp.h 
 raw.o : raw.c /usr/include/linux/types.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
@@ -146,9 +146,9 @@ raw.o : raw.c /usr/include/linux/types.h /usr/include/linux/sched.h /usr/include
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/fcntl.h /usr/include/linux/socket.h \
-  /usr/include/netinet/in.h /usr/include/features.h /usr/include/sys/socket.h \
-  /usr/include/traditional.h timer.h ip.h dev.h /usr/include/linux/sock_ioctl.h \
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/fcntl.h \
+  /usr/include/linux/socket.h /usr/include/netinet/in.h /usr/include/features.h \
+  /usr/include/sys/socket.h /usr/include/traditional.h timer.h ip.h dev.h /usr/include/linux/sock_ioctl.h \
   eth.h tcp.h sock.h /usr/include/linux/errno.h /usr/include/linux/timer.h /usr/include/asm/system.h \
   /usr/include/asm/segment.h ../kern_sock.h 
 sock.o : sock.c /usr/include/linux/errno.h /usr/include/linux/types.h /usr/include/linux/socket.h \
@@ -160,9 +160,10 @@ sock.o : sock.c /usr/include/linux/errno.h /usr/include/linux/types.h /usr/inclu
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/timer.h /usr/include/linux/sock_ioctl.h \
-  /usr/include/asm/memory.h ../kern_sock.h timer.h ip.h dev.h eth.h tcp.h udp.h \
-  sock.h /usr/include/asm/segment.h /usr/include/asm/system.h /usr/include/linux/fcntl.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/timer.h \
+  /usr/include/linux/string.h /usr/include/linux/sock_ioctl.h ../kern_sock.h timer.h \
+  ip.h dev.h eth.h tcp.h udp.h sock.h /usr/include/asm/segment.h /usr/include/asm/system.h \
+  /usr/include/linux/fcntl.h 
 tcp.o : tcp.c /usr/include/linux/types.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
   /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
@@ -170,12 +171,12 @@ tcp.o : tcp.c /usr/include/linux/types.h /usr/include/linux/sched.h /usr/include
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/asm/memory.h /usr/include/linux/socket.h \
-  /usr/include/netinet/in.h /usr/include/features.h /usr/include/sys/socket.h \
-  /usr/include/traditional.h /usr/include/linux/fcntl.h timer.h ip.h dev.h /usr/include/linux/sock_ioctl.h \
-  eth.h icmp.h tcp.h sock.h /usr/include/linux/errno.h /usr/include/linux/timer.h \
-  /usr/include/asm/system.h /usr/include/asm/segment.h /usr/include/linux/termios.h \
-  ../kern_sock.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/string.h \
+  /usr/include/linux/socket.h /usr/include/netinet/in.h /usr/include/features.h \
+  /usr/include/sys/socket.h /usr/include/traditional.h /usr/include/linux/fcntl.h \
+  timer.h ip.h dev.h /usr/include/linux/sock_ioctl.h eth.h icmp.h tcp.h sock.h \
+  /usr/include/linux/errno.h /usr/include/linux/timer.h /usr/include/asm/system.h \
+  /usr/include/asm/segment.h /usr/include/linux/termios.h ../kern_sock.h 
 timer.o : timer.c /usr/include/linux/types.h /usr/include/linux/errno.h /usr/include/linux/socket.h \
   /usr/include/netinet/in.h /usr/include/features.h /usr/include/sys/socket.h \
   /usr/include/traditional.h /usr/include/linux/kernel.h /usr/include/linux/sched.h \
@@ -185,9 +186,9 @@ timer.o : timer.c /usr/include/linux/types.h /usr/include/linux/errno.h /usr/inc
   /usr/include/linux/msdos_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
   /usr/include/linux/msdos_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/timer.h /usr/include/asm/system.h \
-  timer.h ip.h dev.h /usr/include/linux/sock_ioctl.h eth.h tcp.h sock.h arp.h \
-  ../kern_sock.h 
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/timer.h \
+  /usr/include/asm/system.h timer.h ip.h dev.h /usr/include/linux/sock_ioctl.h \
+  eth.h tcp.h sock.h arp.h ../kern_sock.h 
 udp.o : udp.c /usr/include/linux/types.h /usr/include/linux/sched.h /usr/include/linux/head.h \
   /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
   /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
@@ -195,9 +196,9 @@ udp.o : udp.c /usr/include/linux/types.h /usr/include/linux/sched.h /usr/include
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
   /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
-  /usr/include/linux/vm86.h /usr/include/linux/fcntl.h /usr/include/linux/socket.h \
-  /usr/include/netinet/in.h /usr/include/features.h /usr/include/sys/socket.h \
-  /usr/include/traditional.h timer.h ip.h dev.h /usr/include/linux/sock_ioctl.h \
+  /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/fcntl.h \
+  /usr/include/linux/socket.h /usr/include/netinet/in.h /usr/include/features.h \
+  /usr/include/sys/socket.h /usr/include/traditional.h timer.h ip.h dev.h /usr/include/linux/sock_ioctl.h \
   eth.h tcp.h sock.h /usr/include/linux/errno.h /usr/include/linux/timer.h /usr/include/linux/termios.h \
   /usr/include/asm/system.h /usr/include/asm/segment.h ../kern_sock.h udp.h icmp.h 
 we.o : we.c /usr/include/linux/config.h /usr/include/linux/config.dist.h /usr/include/linux/kernel.h \
@@ -208,9 +209,10 @@ we.o : we.c /usr/include/linux/config.h /usr/include/linux/config.dist.h /usr/in
   /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
   /usr/include/linux/mm.h /usr/include/linux/signal.h /usr/include/linux/time.h \
   /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
-  /usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/asm/system.h \
-  /usr/include/linux/ptrace.h /usr/include/asm/segment.h /usr/include/asm/io.h \
-  /usr/include/asm/memory.h /usr/include/errno.h /usr/include/traditional.h /usr/include/linux/errno.h \
-  /usr/include/linux/fcntl.h /usr/include/netinet/in.h /usr/include/features.h \
-  /usr/include/sys/socket.h /usr/include/linux/socket.h dev.h eth.h timer.h ip.h \
-  /usr/include/linux/sock_ioctl.h tcp.h sock.h arp.h wereg.h 
+  /usr/include/linux/math_emu.h /usr/include/linux/tty.h /usr/include/linux/termios.h \
+  /usr/include/asm/system.h /usr/include/linux/ptrace.h /usr/include/linux/string.h \
+  /usr/include/asm/segment.h /usr/include/asm/io.h /usr/include/errno.h /usr/include/traditional.h \
+  /usr/include/linux/errno.h /usr/include/linux/fcntl.h /usr/include/netinet/in.h \
+  /usr/include/features.h /usr/include/sys/socket.h /usr/include/linux/socket.h \
+  dev.h eth.h timer.h ip.h /usr/include/linux/sock_ioctl.h tcp.h sock.h arp.h \
+  wereg.h 
index 1b2578ffd9ed01acadd1fe6a5eca12f0554837a2..33edff09dd966581bb6b707c20e02d84f5fe29bc 100644 (file)
@@ -152,13 +152,13 @@ arp_targetp(struct arp *arp)
 static  void
 arp_free (void *ptr, unsigned long len)
 {
-  free_s(ptr, len);
+  kfree_s(ptr, len);
 }
 
 static  void *
-arp_malloc (unsigned long amount)
+arp_malloc (unsigned long amount, int priority)
 {
-  return (malloc (amount));
+  return (kmalloc (amount, priority));
 }
 
 static  int
@@ -170,7 +170,8 @@ arp_response (struct arp *arp1, struct device *dev)
 
   /* get some mem and initialize it for the return trip. */
   skb = arp_malloc (sizeof (*skb) + sizeof (*arp2) +
-                   2*arp1->hlen + 2*arp1->plen + dev->hard_header_len);
+                   2*arp1->hlen + 2*arp1->plen + dev->hard_header_len,
+                   GFP_ATOMIC);
   if (skb == NULL) return (1);
 
   skb->mem_addr = skb;
@@ -278,7 +279,7 @@ create_arp (unsigned long paddr, unsigned char *addr, int hlen)
 {
   struct arp_table *apt;
   unsigned long hash;
-  apt = arp_malloc (sizeof (*apt));
+  apt = arp_malloc (sizeof (*apt), GFP_ATOMIC);
   if (apt == NULL) return (NULL);
 
   hash = net32(paddr) & (ARP_TABLE_SIZE - 1);
@@ -365,7 +366,7 @@ arp_snd (unsigned long paddr, struct device *dev, unsigned long saddr)
   if (apt == NULL) return;
 
   skb = arp_malloc (sizeof (*arp) + sizeof (*skb) + dev->hard_header_len +
-                   2*dev->addr_len+8);
+                   2*dev->addr_len+8, GFP_ATOMIC);
   if (skb == NULL) return;
   
   skb->sk = NULL;
index 4c9607691fff6691b6c4c99a09b6c59ed1446728..b6c2cc219ac5d1f67c0f17851e7fc0630273b297 100644 (file)
@@ -121,6 +121,13 @@ dev_queue_xmit (struct sk_buff *skb, struct device *dev, int pri)
   struct sk_buff *skb2;
   PRINTK ("eth_queue_xmit (skb=%X, dev=%X, pri = %d)\n", skb, dev, pri);
   skb->dev = dev;
+
+  if (skb->next != NULL)
+    {
+/*      printk ("retransmitted packet still on queue. \n");*/
+       return;
+    }
+
   if (pri < 0 || pri >= DEV_NUMBUFFS)
     {
        printk ("bad priority in dev_queue_xmit.\n");
@@ -132,12 +139,6 @@ dev_queue_xmit (struct sk_buff *skb, struct device *dev, int pri)
        return;
     }
 
-  if (skb->next != NULL)
-    {
-       printk ("retransmitted packet still on queue. \n");
-       return;
-    }
-
   /* used to say it is not currently on a send list. */
   skb->next = NULL;
 
@@ -186,7 +187,7 @@ dev_rint(unsigned char *buff, unsigned long len, int flags,
    /* try to grab some memory. */
    if (len > 0 && buff != NULL)
      {
-       skb = malloc (sizeof (*skb) + len);
+       skb = kmalloc (sizeof (*skb) + len, GFP_ATOMIC);
        if (skb != NULL)
          {
            skb->mem_len = sizeof (*skb) + len;
@@ -214,7 +215,7 @@ dev_rint(unsigned char *buff, unsigned long len, int flags,
          }
        else
          {
-            free_s (skb->mem_addr, skb->mem_len);
+            kfree_s (skb->mem_addr, skb->mem_len);
             skb = (struct sk_buff *)buff;
          }
 
@@ -242,7 +243,7 @@ dev_rint(unsigned char *buff, unsigned long len, int flags,
      }
 
    if (skb != NULL) 
-     free_s (skb->mem_addr, skb->mem_len);
+     kfree_s (skb->mem_addr, skb->mem_len);
 
    /* anything left to process? */
 
@@ -295,7 +296,7 @@ dev_rint(unsigned char *buff, unsigned long len, int flags,
             /* copy the packet if we need to. */
             if (ptype->copy)
               {
-                 skb2 = malloc (skb->mem_len);
+                 skb2 = kmalloc (skb->mem_len, GFP_ATOMIC);
                  if (skb2 == NULL) continue;
                  memcpy (skb2, skb, skb->mem_len);
                  skb2->mem_addr = skb2;
index c48e96756b8435aedc385e1f674cf79f6cc1295f..8afa92a65e808be832a6f59d660439ea61607a46 100644 (file)
@@ -29,7 +29,7 @@
 
 #include <linux/types.h>
 #include <linux/sched.h>
-#include <linux/kernel.h>      /* free_s */
+#include <linux/kernel.h>      /* kfree_s */
 #include <linux/fcntl.h>
 #include <linux/socket.h>
 #include <netinet/in.h>
@@ -88,7 +88,7 @@ icmp_reply (struct sk_buff *skb_in,  int type, int code, struct device *dev)
         64 /* enough for an ip header. */ +
         dev->hard_header_len;
           
-   skb = malloc (len);
+   skb = kmalloc (len, GFP_ATOMIC);
    if (skb == NULL) return;
 
    skb->mem_addr = skb;
@@ -202,7 +202,7 @@ icmp_rcv(struct sk_buff *skb1, struct device *dev, struct options *opt,
           struct ip_header *iph;
 
           iph = (struct ip_header *)(icmph+1);
-          rt = malloc (sizeof (*rt));
+          rt = kmalloc (sizeof (*rt), GFP_ATOMIC);
           if (rt != NULL)
             {
                rt->net = iph->daddr;
@@ -223,7 +223,7 @@ icmp_rcv(struct sk_buff *skb1, struct device *dev, struct options *opt,
        /* Allocate an sk_buff response buffer (assume 64 byte IP header) */
 
        size = sizeof( struct sk_buff ) + dev->hard_header_len + 64 + len;
-       skb = malloc( size );
+       skb = kmalloc( size, GFP_ATOMIC );
        if (skb == NULL)
          {
             skb1->sk = NULL;
@@ -240,7 +240,7 @@ icmp_rcv(struct sk_buff *skb1, struct device *dev, struct options *opt,
          {
             /* Problems building header */
             PRINTK("\nCould not build IP Header for ICMP ECHO Response");
-            free_s (skb->mem_addr, skb->mem_len);
+            kfree_s (skb->mem_addr, skb->mem_len);
             skb1->sk = NULL;
             free_skb (skb1, FREE_READ);
             return( 0 ); /* just toss the received packet */
index 35d2a732315740c4d5cf7f3c5a3e367c4fb768e0..6c1249e0192ece5c2bea42cfb2af665cefa14bf9 100644 (file)
@@ -252,7 +252,7 @@ add_route (struct rtable *rt)
                 rt->next = r->next;
                 r1->next = rt;
              }
-           free_s (r, sizeof (*r));
+           kfree_s (r, sizeof (*r));
            return;
         }
 
@@ -300,7 +300,7 @@ ip_set_dev (struct ip_config *u_ipc)
   if (ipc.net != -1)
     {
        arp_add_broad (ipc.net, dev);
-       rt = malloc (sizeof (*rt));
+       rt = kmalloc (sizeof (*rt), GFP_KERNEL);
        if (rt == NULL) return (-ENOMEM);
 
        rt->net = ipc.net;
@@ -312,7 +312,7 @@ ip_set_dev (struct ip_config *u_ipc)
 
   if (ipc.router != -1)
     {
-       rt = malloc (sizeof (*rt));
+       rt = kmalloc (sizeof (*rt),GFP_KERNEL);
        if (rt == NULL) return (-ENOMEM);
        rt->net = 0;
        rt->dev = dev;
@@ -322,7 +322,7 @@ ip_set_dev (struct ip_config *u_ipc)
 
   if (dev->loopback)
     {
-       rt = malloc (sizeof (*rt));
+       rt = kmalloc (sizeof (*rt), GFP_KERNEL);
        if (rt == NULL) return (-ENOMEM);
        rt->net = ipc.paddr;
        rt->dev = dev;
@@ -729,7 +729,7 @@ ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
 
        if (ipprot->copy)
         {
-           skb2 = malloc (skb->mem_len);
+           skb2 = kmalloc (skb->mem_len, GFP_KERNEL);
            if (skb2 == NULL) continue;
            memcpy (skb2, skb, skb->mem_len);
            skb2->mem_addr = skb2;
index ffad5240702efd6ae46404b83d0ddcad325722f3..5b376778928289541ad2ef5eeaa24b12a6f5549c 100644 (file)
@@ -127,7 +127,8 @@ packet_sendto (volatile struct sock *sk, unsigned char *from, int len,
    else
      return (-EINVAL);
 
-   skb = sk->prot->wmalloc (sk, len+sizeof (*skb) + sk->prot->max_header, 0);
+   skb = sk->prot->wmalloc (sk, len+sizeof (*skb) + sk->prot->max_header, 0,
+                           GFP_KERNEL);
    /* this shouldn't happen, but it could. */
    if (skb == NULL)
      {
@@ -170,7 +171,7 @@ packet_close (volatile struct sock *sk, int timeout)
    sk->inuse = 1;
    sk->state = TCP_CLOSE;
    dev_remove_pack ((struct packet_type *)sk->pair);
-   free_s ((void *)sk->pair, sizeof (struct packet_type));
+   kfree_s ((void *)sk->pair, sizeof (struct packet_type));
    release_sock (sk);
 }
 
@@ -178,7 +179,7 @@ static int
 packet_init (volatile struct sock *sk)
 {
    struct packet_type *p;
-   p = malloc (sizeof (*p));
+   p = kmalloc (sizeof (*p), GFP_KERNEL);
    if (p == NULL) return (-ENOMEM);
 
    p->func = packet_rcv;
index 8cd116e0d20a391b36353c084692fea3a7638b04..41dacdce57fa45f35613d29edbfe86a9b99a2471 100644 (file)
@@ -33,6 +33,8 @@
 #include <linux/timer.h>
 #include <asm/system.h>
 #include <asm/segment.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
 #include "../kern_sock.h" /* for PRINTK */
 
 extern struct proto raw_prot;
@@ -127,7 +129,7 @@ raw_loopback (volatile struct sock *sk, int prot, char *from, int len,
    /* just pretend it just came in. */
    struct sk_buff *skb;
    int err;
-   skb = malloc (len+sizeof (*skb));
+   skb = kmalloc (len+sizeof (*skb), GFP_KERNEL);
    if (skb == NULL) return (-ENOMEM);
 
    skb->mem_addr = skb;
@@ -184,7 +186,8 @@ raw_sendto (volatile struct sock *sk, unsigned char *from, int len,
      }
 
    sk->inuse = 1;
-   skb = sk->prot->wmalloc (sk, len+sizeof (*skb) + sk->prot->max_header, 0);
+   skb = sk->prot->wmalloc (sk, len+sizeof (*skb) + sk->prot->max_header, 0,
+                           GFP_KERNEL);
    /* this shouldn't happen, but it could. */
    if (skb == NULL)
      {
@@ -227,7 +230,7 @@ raw_close (volatile struct sock *sk, int timeout)
    sk->inuse = 1;
    sk->state = TCP_CLOSE;
    delete_ip_protocol ((struct ip_protocol *)sk->pair);
-   free_s ((void *)sk->pair, sizeof (struct ip_protocol));
+   kfree_s ((void *)sk->pair, sizeof (struct ip_protocol));
    release_sock (sk);
 }
 
@@ -235,7 +238,7 @@ static int
 raw_init (volatile struct sock *sk)
 {
    struct ip_protocol *p;
-   p = malloc (sizeof (*p));
+   p = kmalloc (sizeof (*p), GFP_KERNEL);
    if (p == NULL) return (-ENOMEM);
 
    p->handler = raw_rcv;
index ad570f7c2196d1fd0cd470cc966eda8fbab97857..f01422cdaf45f5a420b4a769ff0ab2fe938e04b4 100644 (file)
@@ -37,6 +37,7 @@
 #include <asm/segment.h>
 #include <asm/system.h>
 #include <linux/fcntl.h>
+#include <linux/mm.h>
 
 #ifdef MEM_DEBUG
 #define MPRINTK printk
@@ -202,7 +203,7 @@ free_skb (struct sk_buff *skb, int rw)
      }
    else
      {
-       free_s (skb->mem_addr, skb->mem_len);
+       kfree_s (skb->mem_addr, skb->mem_len);
      }
 }
 
@@ -481,7 +482,7 @@ destroy_sock(volatile struct sock *sk)
      otherwise we need to keep it around until everything is gone. */
   if (sk->rmem_alloc == 0 && sk->wmem_alloc == 0)
     {
-       free_s ((void *)sk,sizeof (*sk));
+       kfree_s ((void *)sk,sizeof (*sk));
     }
   else
     {
@@ -728,7 +729,7 @@ ip_proto_create (struct socket *sock, int protocol)
   struct proto *prot;
   int err;
 
-  sk = malloc (sizeof (*sk));
+  sk = kmalloc (sizeof (*sk), GFP_KERNEL);
   if (sk == NULL)
     return (-ENOMEM);
   sk->num = 0;
@@ -740,7 +741,7 @@ ip_proto_create (struct socket *sock, int protocol)
     case SOCK_SEQPACKET:
        if (protocol && protocol != IPPROTO_TCP)
         {
-           free_s ((void *)sk, sizeof (*sk));
+           kfree_s ((void *)sk, sizeof (*sk));
            return (-EPROTONOSUPPORT);
         }
        sk->no_check = TCP_NO_CHECK;
@@ -750,7 +751,7 @@ ip_proto_create (struct socket *sock, int protocol)
     case SOCK_DGRAM:
        if (protocol && protocol != IPPROTO_UDP)
         {
-           free_s ((void *)sk, sizeof (*sk));
+           kfree_s ((void *)sk, sizeof (*sk));
            return (-EPROTONOSUPPORT);
         }
        sk->no_check = UDP_NO_CHECK;
@@ -760,13 +761,13 @@ ip_proto_create (struct socket *sock, int protocol)
      case SOCK_RAW:
        if (!suser())
         {
-           free_s ((void *)sk, sizeof (*sk));
+           kfree_s ((void *)sk, sizeof (*sk));
            return (-EPERM);
         }
 
        if (!protocol)
         {
-           free_s ((void *)sk, sizeof (*sk));
+           kfree_s ((void *)sk, sizeof (*sk));
            return (-EPROTONOSUPPORT);
         }
        prot = &raw_prot;
@@ -779,13 +780,13 @@ ip_proto_create (struct socket *sock, int protocol)
     case SOCK_PACKET:
        if (!suser())
         {
-           free_s ((void *)sk, sizeof (*sk));
+           kfree_s ((void *)sk, sizeof (*sk));
            return (-EPERM);
         }
 
        if (!protocol)
         {
-           free_s ((void *)sk, sizeof (*sk));
+           kfree_s ((void *)sk, sizeof (*sk));
            return (-EPROTONOSUPPORT);
         }
        prot = &packet_prot;
@@ -797,7 +798,7 @@ ip_proto_create (struct socket *sock, int protocol)
 
       
     default:
-       free_s ((void *)sk, sizeof (*sk));
+       kfree_s ((void *)sk, sizeof (*sk));
        return (-ESOCKTNOSUPPORT);
 
     }
@@ -1427,208 +1428,44 @@ ip_proto_ioctl (struct socket *sock, unsigned int cmd,
     }
 }
 
-#ifdef MEM_DEBUG
-
-struct mem
-{
-   unsigned long check;
-   struct mem *other;
-   unsigned long len;
-   unsigned short buff[10];
-};
-
-static void
-print_mem (struct mem *m)
-{
-   int i;
-   MPRINTK("mem:\n");
-   MPRINTK("  check=%X, other = %X\n", m->check, m->other);
-   MPRINTK("  len=%d buff:\n " , m->len);
-   for (i = 0; i < 10; i++)
-     {
-       MPRINTK ("0x%02X ",m->buff[i]);
-     }
-   MPRINTK ("\n");
-}
-
-static void *
-smalloc (unsigned long size)
-{
-   struct mem *head, *tail;
-   static unsigned short count;
-   int i;
-   int sum;
-   unsigned char *ptr;
-
-   MPRINTK ("smalloc (size = %d)\n",size);
-   head = malloc (size + 2*sizeof (*head));
-   if (head == NULL) return (NULL);
-   tail = (struct mem *)((unsigned char *)(head+1) + size); 
-
-   head->other = tail;
-   tail->other = head;
-
-   tail->len = size;
-   head->len = size;
-   for (i = 0; i < 10; i++)
-     {
-       tail->buff[i]=count++;
-       head->buff[i]=count;
-     }
-
-   ptr = (unsigned char *)head;
-   head->check = 0;
-   sum = 0;
-
-   for (i = 0; i < sizeof (*head); i ++)
-     {
-       sum+= ptr[i]; 
-     }
-
-   head->check = ~sum;
-   ptr = (unsigned char *)tail;
-   tail->check = 0;
-   sum = 0;
-
-   for (i = 0; i < sizeof (*head); i ++)
-     {
-       sum+= ptr[i]; 
-     }
-
-   tail->check = ~sum;
-   MPRINTK ("head = %X:\n", head);
-   print_mem(head);
-   MPRINTK ("tail = %X:\n", tail);
-   print_mem(tail);
-   return (head+1);
-}
-
-void
-sfree (void *data, unsigned long len)
-{
-   int i;
-   int sum;
-   int csum;
-   unsigned char *ptr;
-   int bad = 0;
-   struct mem *head, *tail;
-   MPRINTK ("sfree(data=%X, len = %d)\n", data, len);
-   head = data;
-   head--;
-   tail = (struct mem *)((unsigned char *)(head+1) + len);
-   print_mem (head);
-   print_mem (tail);
-   if (head->other != tail)
-     {
-       MPRINTK ("sfree: head->other != tail:\n");
-       bad = 1;
-     }
-   if (tail->other != head)
-     {
-       MPRINTK ("sfree: tail->other != head:\n");
-       bad =1 ;
-     }
-   if (head ->len != len)
-     {
-       MPRINTK ("sfree: head->len != len");
-       bad = 1;
-     }
-   if (tail ->len != len)
-     {
-       MPRINTK ("sfree: tail->len != len");
-       bad = 1;
-     }
-   csum = head->check;
-   ptr = (unsigned char *)head;
-   head->check = 0;
-   sum = 0;
-   for (i = 0; i < sizeof (*head); i ++)
-     {
-       sum+= ptr[i]; 
-     }
-   if (csum != ~sum)
-     {
-       MPRINTK ("sfree: head failed checksum\n");
-       bad = 1;
-     }
-   csum = tail->check;
-   ptr = (unsigned char *)tail;
-   tail->check = 0;
-   sum = 0;
-   for (i = 0; i < sizeof (*head); i ++)
-     {
-       sum+= ptr[i]; 
-     }
-   if (csum != ~sum)
-     {
-       MPRINTK ("sfree: tail failed checksum\n");
-       bad = 1;
-     }
-   if (!bad)
-     free_s (head, len+2*sizeof (*head));
-   else
-     schedule();
-}
-#else
-static  void *
-smalloc (unsigned long size)
-{
-   return (malloc (size));
-}
-static  void
-sfree(void *data, unsigned long len)
-{
-   free_s(data,len);
-}
-#endif
-
 void *
-sock_wmalloc(volatile struct sock *sk, unsigned long size, int force)
+sock_wmalloc(volatile struct sock *sk, unsigned long size, int force,
+            int priority)
 {
-  void *tmp;
   if (sk)
     {
-       if (sk->wmem_alloc + size >= SK_WMEM_MAX && !force)
+       if (sk->wmem_alloc + size < SK_WMEM_MAX || force)
         {
-           MPRINTK ("sock_wmalloc(%X,%d,%d) returning NULL\n",
-                    sk, size, force);
-           return (NULL);
+          cli();
+          sk->wmem_alloc+= size;
+          sti();
+          return (kmalloc (size, priority));
         }
-      cli();
-      sk->wmem_alloc+= size;
-      sti();
+       MPRINTK ("sock_wmalloc(%X,%d,%d,%d) returning NULL\n",
+               sk, size, force, priority);
+       return (NULL);
     }
-   if (sk)
-     tmp = smalloc (size);
-   else
-     tmp = malloc (size);
-
-  MPRINTK ("sock_wmalloc(%X,%d,%d) returning %X\n",sk, size, force, tmp);
-  return (tmp);
+  return (kmalloc(size, priority));
 }
 
 void *
-sock_rmalloc(volatile struct sock *sk, unsigned long size, int force)
+sock_rmalloc(volatile struct sock *sk, unsigned long size, int force,
+            int priority)
 {
-   struct mem *tmp;
    if (sk )
      {
-       if (sk->rmem_alloc + size >= SK_RMEM_MAX && !force)
+       if (sk->rmem_alloc + size < SK_RMEM_MAX || force)
          {
-            MPRINTK ("sock_rmalloc(%X,%d,%d) returning NULL\n",sk,size,force);
-            return (NULL);
+           cli();
+           sk->rmem_alloc+= size;
+           sti();
+           return (kmalloc (size, priority));
          }
-       cli();
-       sk->rmem_alloc+= size;
-       sti();
-     }
-   if (sk)
-     tmp = smalloc (size);
-   else
-     tmp = malloc (size);
-
-   MPRINTK ("sock_rmalloc(%X,%d,%d) returning %X\n",sk, size, force, tmp);
-   return (tmp);
+       MPRINTK ("sock_rmalloc(%X,%d,%d,%d) returning NULL\n",
+                sk,size,force, priority);
+       return (NULL);
+      }
+   return (kmalloc (size, priority));
 }
 
 
@@ -1663,22 +1500,19 @@ void
 sock_wfree (volatile struct sock *sk, void *mem, unsigned long size)
 {
    MPRINTK ("sock_wfree (sk=%X, mem=%X, size=%d)\n",sk, mem, size);
+   kfree_s (mem, size);
    if (sk)
      {
        sk->wmem_alloc -= size;
-       sfree(mem,size);
        /* in case it might be waiting for more memory. */
        if (!sk->dead && sk->wmem_alloc > SK_WMEM_MAX/2) wake_up(sk->sleep);
        if (sk->destroy && sk->wmem_alloc == 0 && sk->rmem_alloc == 0)
          {
             MPRINTK ("recovered lost memory, destroying sock = %X\n",sk);
             delete_timer ((struct timer *)&sk->time_wait);
-            free_s ((void *)sk, sizeof (*sk));
+            kfree_s ((void *)sk, sizeof (*sk));
          }
-     }
-   else
-     {
-       free_s (mem, size);
+       return;
      }
 }
 
@@ -1686,20 +1520,16 @@ void
 sock_rfree (volatile struct sock *sk, void *mem, unsigned long size)
 {
    MPRINTK ("sock_rfree (sk=%X, mem=%X, size=%d)\n",sk, mem, size);
+   kfree_s (mem, size);
    if (sk)
      {
        sk->rmem_alloc -= size;
-       sfree(mem,size);
        if (sk->destroy && sk->wmem_alloc == 0 && sk->rmem_alloc == 0)
          {
             delete_timer ((struct timer *)&sk->time_wait);
-            free_s ((void *)sk, sizeof (*sk));
+            kfree_s ((void *)sk, sizeof (*sk));
          }
      }
-   else
-     {
-       free_s (mem, size);
-     }
 }
 
 
index b2655e719243856085c89e34c7a025584be27431..be9f60ec49a095ef4faa381a8d4ef67c43b936c0 100644 (file)
@@ -76,8 +76,10 @@ struct sock
 
 struct proto 
 {
-  void *(*wmalloc)(volatile struct sock *sk, unsigned long size, int force);
-  void *(*rmalloc)(volatile struct sock *sk, unsigned long size, int force);
+  void *(*wmalloc)(volatile struct sock *sk, unsigned long size, int force,
+                  int priority);
+  void *(*rmalloc)(volatile struct sock *sk, unsigned long size, int force,
+                  int priority);
   void (*wfree)(volatile struct sock *sk, void *mem, unsigned long size);
   void (*rfree)(volatile struct sock *sk, void *mem, unsigned long size);
   unsigned long (*rspace)(volatile struct sock *sk);
@@ -167,8 +169,10 @@ volatile struct sock *get_sock(struct proto *, unsigned short, unsigned long,
                               unsigned short, unsigned long);
 void print_sk (volatile struct sock *);
 void print_skb (struct sk_buff *);
-void *sock_wmalloc(volatile struct sock *sk, unsigned long size, int force);
-void *sock_rmalloc(volatile struct sock *sk, unsigned long size, int force);
+void *sock_wmalloc(volatile struct sock *sk, unsigned long size, int force,
+                  int priority);
+void *sock_rmalloc(volatile struct sock *sk, unsigned long size, int force,
+                  int priority);
 void sock_wfree(volatile struct sock *sk, void *mem, unsigned long size);
 void sock_rfree(volatile struct sock *sk, void *mem, unsigned long size);
 unsigned long sock_rspace(volatile struct sock *sk);
index ef310118db9eee80cbe4164f67b8c7a9676c8c45..35f7317bbd62805e5bdeb8793b45e7242e0dfe3c 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/timer.h>
 #include <asm/system.h>
 #include <asm/segment.h>
+#include <linux/mm.h>
 /* #include <signal.h>*/
 #include <linux/termios.h> /* for ioctl's */
 #include "../kern_sock.h" /* for PRINTK */
@@ -376,7 +377,7 @@ tcp_send_check (struct tcp_header *th, unsigned long saddr,
    /* we need to grab some memory, and put together an ack, and then
       put it into the queue to be sent. */
 
-   buff=sk->prot->wmalloc(sk,MAX_ACK_SIZE,1);
+   buff=sk->prot->wmalloc(sk,MAX_ACK_SIZE,1, GFP_ATOMIC);
    if (buff == NULL) 
      {
        /* force it to send an ack. */
@@ -540,7 +541,8 @@ tcp_write(volatile struct sock *sk, unsigned char *from,
       if (copy < 200 || copy > sk->mtu) copy = sk->mtu;
       copy = min (copy, len);
 
-      skb=prot->wmalloc (sk, copy + prot->max_header+sizeof (*skb),0);
+      skb=prot->wmalloc (sk, copy + prot->max_header+sizeof (*skb),0,
+                        GFP_KERNEL);
 
       /* if we didn't get any memory, we need to sleep. */
       if (skb == NULL)
@@ -659,7 +661,7 @@ tcp_read_wakeup(volatile struct sock *sk)
   /* we need to grab some memory, and put together an ack, and then
      put it into the queue to be sent. */
 
-  buff=sk->prot->wmalloc(sk,MAX_ACK_SIZE,1);
+  buff=sk->prot->wmalloc(sk,MAX_ACK_SIZE,1, GFP_ATOMIC);
   if (buff == NULL) 
     {
        /* try again real soon. */
@@ -1002,7 +1004,7 @@ tcp_reset(unsigned long saddr, unsigned long daddr, struct tcp_header *th,
   struct sk_buff *buff;
   struct tcp_header *t1;
   int tmp;
-  buff=prot->wmalloc(NULL, MAX_RESET_SIZE,1);
+  buff=prot->wmalloc(NULL, MAX_RESET_SIZE,1, GFP_ATOMIC);
   if (buff == NULL) return;
 
   PRINTK("tcp_reset buff = %X\n", buff);
@@ -1084,7 +1086,7 @@ tcp_conn_request(volatile struct sock *sk, struct sk_buff *skb,
      and if the listening socket is destroyed before this is taken
      off of the queue, this will take care of it. */
 
-  newsk = malloc(sizeof (struct sock));
+  newsk = kmalloc(sizeof (struct sock), GFP_ATOMIC);
   if (newsk == NULL) 
     {
        /* just ignore the syn.  It will get retransmitted. */
@@ -1165,7 +1167,7 @@ tcp_conn_request(volatile struct sock *sk, struct sk_buff *skb,
     }
 
   print_sk (newsk);
-  buff=newsk->prot->wmalloc(newsk,MAX_SYN_SIZE,1);
+  buff=newsk->prot->wmalloc(newsk,MAX_SYN_SIZE,1, GFP_ATOMIC);
   if (buff == NULL)
     {
        sk->err = -ENOMEM;
@@ -1325,7 +1327,7 @@ tcp_close (volatile struct sock *sk, int timeout)
       prot = (struct proto *)sk->prot;
       th=(struct tcp_header *)&sk->dummy_th;
 
-       buff=prot->wmalloc(sk, MAX_FIN_SIZE,1);
+       buff=prot->wmalloc(sk, MAX_FIN_SIZE,1, GFP_ATOMIC);
        if (buff == NULL)
         {
            /* this will force it to try again later. */
@@ -1825,7 +1827,7 @@ tcp_fin (volatile struct sock *sk, struct tcp_header *th,
     }
 
   /* send an ack and our own fin. */
-  buff=sk->prot->wmalloc(sk,MAX_ACK_SIZE,1);
+  buff=sk->prot->wmalloc(sk,MAX_ACK_SIZE,1, GFP_ATOMIC);
   if (buff == NULL)
     {
        /* we will ignore the fin.  That way it will be sent again. */
@@ -1973,7 +1975,7 @@ tcp_connect (volatile struct sock *sk, struct sockaddr_in *usin, int addr_len)
   sk->err = 0;
   sk->dummy_th.dest = sin.sin_port;
 
-  buff=sk->prot->wmalloc(sk,MAX_SYN_SIZE,0);
+  buff=sk->prot->wmalloc(sk,MAX_SYN_SIZE,0, GFP_KERNEL);
   if (buff == NULL) 
     {
       return (-ENOMEM);
@@ -2530,7 +2532,7 @@ tcp_write_wakeup(volatile struct sock *sk)
   int tmp;
   if (sk -> state != TCP_ESTABLISHED) return;
 
-  buff=sk->prot->wmalloc(sk,MAX_ACK_SIZE,1);
+  buff=sk->prot->wmalloc(sk,MAX_ACK_SIZE,1, GFP_ATOMIC);
   /* no big loss. */
   if (buff == NULL) return;
 
index 99fc5d73c630c3f8d47e42ad6051f726a1454507..d73a141303587c6ed5e45e770af23a4e787f0a49 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/termios.h> /* for ioctl's */
 #include <asm/system.h>
 #include <asm/segment.h>
+#include <linux/mm.h>
 #include "../kern_sock.h" /* for PRINTK */
 #include "udp.h"
 #include "icmp.h"
@@ -207,7 +208,7 @@ udp_loopback (volatile struct sock *sk, unsigned short port,
 
        skb = pair->prot->rmalloc (pair,
                                   sizeof (*skb) + sizeof (*uh) + len + 4,
-                                  0);
+                                  0, GFP_KERNEL);
 
        /* if we didn't get the memory, just drop the packet. */
        if (skb == NULL) return (len);
@@ -315,7 +316,8 @@ udp_sendto (volatile struct sock *sk, unsigned char *from, int len,
          {
                  int tmp;
                  skb = sk->prot->wmalloc (sk, len + sizeof (*skb)
-                                              + sk->prot->max_header, 0);
+                                              + sk->prot->max_header, 0,
+                                          GFP_KERNEL);
                  /* this should never happen, but it is possible. */
 
                  if (skb == NULL)
index fc6e01fd00d274a4a1062950551fe5393029da9e..c9302bdefea105a6ab55529a93efc825ea0d0c4e 100644 (file)
@@ -1,5 +1,5 @@
-#define UTS_RELEASE "0.98.pl2-10"
-#define UTS_VERSION "10/18/92"
-#define LINUX_COMPILE_TIME "11:37:18"
+#define UTS_RELEASE "0.98.pl4-27"
+#define UTS_VERSION "11/01/92"
+#define LINUX_COMPILE_TIME "14:57:39"
 #define LINUX_COMPILE_BY "root"
 #define LINUX_COMPILE_HOST "home"