aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@klaava.Helsinki.FI>1992-11-09 11:22:01 +0000
committerNicolas Pitre <nico@cam.org>2007-08-19 14:19:09 -0400
commit1fd95ba642b4a2cdfc947bbc0bf02a05d1e4bef2 (patch)
tree86a779933756ecde8bdfd354f8cec4e24589f454
parent73795752dade564a88db44bdcfd7c5a946322de1 (diff)
downloadarchive-1fd95ba642b4a2cdfc947bbc0bf02a05d1e4bef2.tar.gz
Linux version 0.98-pl4v0.98-pl4
As the subject probably tells you, pl4 is out. It's currently available at least on nic.funet.fi: pub/OS/Linux/PEOPLE/Linus/, but will probably show up on the other major sites very soon. pl4 is available both as complete source (linux-0.98.4.tar.Z) and as patches against pl3 (linux-0.98.patch4.Z) and against the pre-version that was released for limited testing (pre-patch4.Z or something like that). Things that have changed: - 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
-rw-r--r--Makefile9
-rw-r--r--boot/head.S127
-rw-r--r--fs/Makefile87
-rw-r--r--fs/buffer.c27
-rw-r--r--fs/exec.c11
-rw-r--r--fs/ext/Makefile43
-rw-r--r--fs/ext/file.c4
-rw-r--r--fs/ext/freelists.c6
-rw-r--r--fs/ext/inode.c15
-rw-r--r--fs/fcntl.c8
-rw-r--r--fs/filesystems.c44
-rw-r--r--fs/inode.c200
-rw-r--r--fs/ioctl.c4
-rw-r--r--fs/minix/Makefile40
-rw-r--r--fs/minix/bitmap.c8
-rw-r--r--fs/minix/file.c4
-rw-r--r--fs/minix/inode.c27
-rw-r--r--fs/minix/namei.c25
-rw-r--r--fs/msdos/Makefile23
-rw-r--r--fs/msdos/inode.c3
-rw-r--r--fs/namei.c4
-rw-r--r--fs/open.c54
-rw-r--r--fs/proc/Makefile17
-rw-r--r--fs/proc/inode.c1
-rw-r--r--fs/select.c198
-rw-r--r--fs/stat.c11
-rw-r--r--fs/super.c257
-rw-r--r--include/asm/dma.h52
-rw-r--r--include/asm/memory.h39
-rw-r--r--include/linux/config.h10
-rw-r--r--include/linux/fs.h35
-rw-r--r--include/linux/hdreg.h3
-rw-r--r--include/linux/kernel.h7
-rw-r--r--include/linux/limits.h18
-rw-r--r--include/linux/math_emu.h145
-rw-r--r--include/linux/mm.h36
-rw-r--r--include/linux/ptrace.h2
-rw-r--r--include/linux/sched.h76
-rw-r--r--include/linux/time.h10
-rw-r--r--include/linux/timer.h1
-rw-r--r--include/linux/types.h36
-rw-r--r--include/linux/wait.h6
-rw-r--r--kernel/FPU-emu/Makefile146
-rw-r--r--kernel/FPU-emu/README30
-rw-r--r--kernel/FPU-emu/Reg_constant.h31
-rw-r--r--kernel/FPU-emu/errors.c45
-rw-r--r--kernel/FPU-emu/fpu_arith.c44
-rw-r--r--kernel/FPU-emu/fpu_aux.c20
-rw-r--r--kernel/FPU-emu/fpu_emu.h52
-rw-r--r--kernel/FPU-emu/fpu_entry.c102
-rw-r--r--kernel/FPU-emu/fpu_etc.c18
-rw-r--r--kernel/FPU-emu/fpu_proto.h38
-rw-r--r--kernel/FPU-emu/fpu_system.h13
-rw-r--r--kernel/FPU-emu/fpu_trig.c430
-rw-r--r--kernel/FPU-emu/get_address.c26
-rw-r--r--kernel/FPU-emu/load_store.c63
-rw-r--r--kernel/FPU-emu/poly_2xm1.c4
-rw-r--r--kernel/FPU-emu/poly_atan.c12
-rw-r--r--kernel/FPU-emu/poly_l2.c13
-rw-r--r--kernel/FPU-emu/poly_sin.c10
-rw-r--r--kernel/FPU-emu/poly_tan.c8
-rw-r--r--kernel/FPU-emu/reg_add_sub.c8
-rw-r--r--kernel/FPU-emu/reg_compare.c46
-rw-r--r--kernel/FPU-emu/reg_constant.c36
-rw-r--r--kernel/FPU-emu/reg_constant.h31
-rw-r--r--kernel/FPU-emu/reg_div.S4
-rw-r--r--kernel/FPU-emu/reg_ld_str.c336
-rw-r--r--kernel/FPU-emu/reg_mul.c10
-rw-r--r--kernel/FPU-emu/reg_norm.S4
-rw-r--r--kernel/FPU-emu/reg_u_add.S4
-rw-r--r--kernel/FPU-emu/reg_u_div.S3
-rw-r--r--kernel/FPU-emu/version.h2
-rw-r--r--kernel/FPU-emu/wm_sqrt.S4
-rw-r--r--kernel/Makefile62
-rw-r--r--kernel/blk_drv/Makefile20
-rw-r--r--kernel/blk_drv/floppy.c4
-rw-r--r--kernel/blk_drv/hd.c65
-rw-r--r--kernel/blk_drv/ll_rw_blk.c25
-rw-r--r--kernel/blk_drv/scsi/Makefile43
-rw-r--r--kernel/chr_drv/Makefile91
-rw-r--r--kernel/chr_drv/keyboard.c6
-rw-r--r--kernel/chr_drv/psaux.c9
-rw-r--r--kernel/chr_drv/serial.c2
-rw-r--r--kernel/chr_drv/tty_io.c90
-rw-r--r--kernel/exit.c5
-rw-r--r--kernel/fork.c13
-rw-r--r--kernel/ptrace.c10
-rw-r--r--kernel/sched.c89
-rw-r--r--kernel/sys_call.S25
-rw-r--r--lib/Makefile2
-rw-r--r--lib/malloc.c195
-rw-r--r--mm/Makefile14
-rw-r--r--mm/memory.c220
-rw-r--r--net/Makefile21
-rw-r--r--net/socket.c37
-rw-r--r--net/tcp/Makefile110
-rw-r--r--net/tcp/arp.c13
-rw-r--r--net/tcp/dev.c21
-rw-r--r--net/tcp/icmp.c10
-rw-r--r--net/tcp/ip.c10
-rw-r--r--net/tcp/packet.c7
-rw-r--r--net/tcp/raw.c11
-rw-r--r--net/tcp/sock.c248
-rw-r--r--net/tcp/sock.h12
-rw-r--r--net/tcp/tcp.c22
-rw-r--r--net/tcp/udp.c6
-rw-r--r--tools/version.h6
107 files changed, 2656 insertions, 2194 deletions
diff --git a/Makefile b/Makefile
index 723dd23..3eff03d 100644
--- 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
diff --git a/boot/head.S b/boot/head.S
index aef714a..63812b2 100644
--- a/boot/head.S
+++ b/boot/head.S
@@ -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
*/
diff --git a/fs/Makefile b/fs/Makefile
index ed1b330..d2a5900 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -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
diff --git a/fs/buffer.c b/fs/buffer.c
index d02e39f..bcdf5eb 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -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))
diff --git a/fs/exec.c b/fs/exec.c
index 32b8356..6397653 100644
--- 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;
diff --git a/fs/ext/Makefile b/fs/ext/Makefile
index 04dc41c..55cb096 100644
--- a/fs/ext/Makefile
+++ b/fs/ext/Makefile
@@ -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
diff --git a/fs/ext/file.c b/fs/ext/file.c
index fb7bb2b..ce8313c 100644
--- a/fs/ext/file.c
+++ b/fs/ext/file.c
@@ -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);
diff --git a/fs/ext/freelists.c b/fs/ext/freelists.c
index 81b54f1..e7801c8 100644
--- a/fs/ext/freelists.c
+++ b/fs/ext/freelists.c
@@ -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)
diff --git a/fs/ext/inode.c b/fs/ext/inode.c
index fe52dfb..3837002 100644
--- a/fs/ext/inode.c
+++ b/fs/ext/inode.c
@@ -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;
diff --git a/fs/fcntl.c b/fs/fcntl.c
index fa0d23b..e9d63d0 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -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
index 0000000..7844781
--- /dev/null
+++ b/fs/filesystems.c
@@ -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}
+};
diff --git a/fs/inode.c b/fs/inode.c
index 30e2e70..78a3907 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -13,12 +13,55 @@
#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);
}
@@ -104,6 +115,22 @@ static void read_inode(struct 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:
* executables cannot be run from the filesystem etc...
@@ -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;
+}
diff --git a/fs/ioctl.c b/fs/ioctl.c
index adc3af0..86f829d 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -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:
diff --git a/fs/minix/Makefile b/fs/minix/Makefile
index 3df9f7c..5f7d43a 100644
--- a/fs/minix/Makefile
+++ b/fs/minix/Makefile
@@ -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
diff --git a/fs/minix/bitmap.c b/fs/minix/bitmap.c
index c1cf6a1..3a9049e 100644
--- a/fs/minix/bitmap.c
+++ b/fs/minix/bitmap.c
@@ -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)
diff --git a/fs/minix/file.c b/fs/minix/file.c
index 57fb4d5..13b54f0 100644
--- a/fs/minix/file.c
+++ b/fs/minix/file.c
@@ -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);
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index 651f397..273187b 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -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);
}
diff --git a/fs/minix/namei.c b/fs/minix/namei.c
index a5e098d..1093294 100644
--- a/fs/minix/namei.c
+++ b/fs/minix/namei.c
@@ -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);
diff --git a/fs/msdos/Makefile b/fs/msdos/Makefile
index c3700df..6fd9644 100644
--- a/fs/msdos/Makefile
+++ b/fs/msdos/Makefile
@@ -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
diff --git a/fs/msdos/inode.c b/fs/msdos/inode.c
index 16e4d1e..dfba933 100644
--- a/fs/msdos/inode.c
+++ b/fs/msdos/inode.c
@@ -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,
diff --git a/fs/namei.c b/fs/namei.c
index 17c2185..930975b 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -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;
diff --git a/fs/open.c b/fs/open.c
index 1193e17..610316b 100644
--- 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);
}
}
diff --git a/fs/proc/Makefile b/fs/proc/Makefile
index aafb266..fd3ad65 100644
--- a/fs/proc/Makefile
+++ b/fs/proc/Makefile
@@ -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
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index e4303b4..5451bdb 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -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,
diff --git a/fs/select.c b/fs/select.c
index caac699..100e73b 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -22,14 +22,20 @@
* 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;
}
diff --git a/fs/stat.c b/fs/stat.c
index 1a5b92c..79dad57 100644
--- 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));
}
diff --git a/fs/super.c b/fs/super.c
index 1062eed..4c75b07 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -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");
}
diff --git a/include/asm/dma.h b/include/asm/dma.h
index 9ba767f..e04f196 100644
--- a/include/asm/dma.h
+++ b/include/asm/dma.h
@@ -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.
@@ -24,9 +23,16 @@
* 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)
*/
@@ -52,16 +59,18 @@
#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
index efef4f1..0000000
--- a/include/asm/memory.h
+++ /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
diff --git a/include/linux/config.h b/include/linux/config.h
index 4fe72bc..c08f507 100644
--- a/include/linux/config.h
+++ b/include/linux/config.h
@@ -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
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 87b76d7..cf725b9 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -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
@@ -27,8 +27,14 @@
* 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);
diff --git a/include/linux/hdreg.h b/include/linux/hdreg.h
index 28e3054..46b4245 100644
--- a/include/linux/hdreg.h
+++ b/include/linux/hdreg.h
@@ -51,7 +51,10 @@
#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;
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index a4ac54f..e80507f 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -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
diff --git a/include/linux/limits.h b/include/linux/limits.h
index f3912fa..adfdf8f 100644
--- a/include/linux/limits.h
+++ b/include/linux/limits.h
@@ -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 */
diff --git a/include/linux/math_emu.h b/include/linux/math_emu.h
index 827e9c9..ec8d6ba 100644
--- a/include/linux/math_emu.h
+++ b/include/linux/math_emu.h
@@ -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
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 4779b25..e250898 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -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. */
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
index ad26e03..dc4fb38 100644
--- a/include/linux/ptrace.h
+++ b/include/linux/ptrace.h
@@ -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. */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 5058896..87e5c5b 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -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
/*
@@ -55,10 +64,7 @@
#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;
diff --git a/include/linux/time.h b/include/linux/time.h
index f154e5d..f87412a 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -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
diff --git a/include/linux/timer.h b/include/linux/timer.h
index d131adb..03ee1d3 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -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;
diff --git a/include/linux/types.h b/include/linux/types.h
index a8c992a..eb17a36 100644
--- a/include/linux/types.h
+++ b/include/linux/types.h
@@ -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;
diff --git a/include/linux/wait.h b/include/linux/wait.h
index 0c13811..58dd088 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -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
diff --git a/kernel/FPU-emu/Makefile b/kernel/FPU-emu/Makefile
index d288ef7..d7db872 100644
--- a/kernel/FPU-emu/Makefile
+++ b/kernel/FPU-emu/Makefile
@@ -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
diff --git a/kernel/FPU-emu/README b/kernel/FPU-emu/README
index 07a0ccd..53cbea2 100644
--- a/kernel/FPU-emu/README
+++ b/kernel/FPU-emu/README
@@ -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
index 0000000..b6ee963
--- /dev/null
+++ b/kernel/FPU-emu/Reg_constant.h
@@ -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_
+
diff --git a/kernel/FPU-emu/errors.c b/kernel/FPU-emu/errors.c
index 078e860..3ab5287 100644
--- a/kernel/FPU-emu/errors.c
+++ b/kernel/FPU-emu/errors.c
@@ -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>
@@ -21,17 +28,17 @@
#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);
diff --git a/kernel/FPU-emu/fpu_arith.c b/kernel/FPU-emu/fpu_arith.c
index a1c73f7..fb86989 100644
--- a/kernel/FPU-emu/fpu_arith.c
+++ b/kernel/FPU-emu/fpu_arith.c
@@ -16,14 +16,14 @@
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();
}
diff --git a/kernel/FPU-emu/fpu_aux.c b/kernel/FPU-emu/fpu_aux.c
index 50d51d0..83b52e6 100644
--- a/kernel/FPU-emu/fpu_aux.c
+++ b/kernel/FPU-emu/fpu_aux.c
@@ -14,10 +14,6 @@
#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();
}
diff --git a/kernel/FPU-emu/fpu_emu.h b/kernel/FPU-emu/fpu_emu.h
index c80aaef..a984f45 100644
--- a/kernel/FPU-emu/fpu_emu.h
+++ b/kernel/FPU-emu/fpu_emu.h
@@ -40,41 +40,39 @@
#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);
diff --git a/kernel/FPU-emu/fpu_entry.c b/kernel/FPU-emu/fpu_entry.c
index 81362c6..0d02f87 100644
--- a/kernel/FPU-emu/fpu_entry.c
+++ b/kernel/FPU-emu/fpu_entry.c
@@ -12,6 +12,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. |
+ +---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------+
| 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
}
diff --git a/kernel/FPU-emu/fpu_etc.c b/kernel/FPU-emu/fpu_etc.c
index 10fbf6a..ce160a1 100644
--- a/kernel/FPU-emu/fpu_etc.c
+++ b/kernel/FPU-emu/fpu_etc.c
@@ -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);
}
diff --git a/kernel/FPU-emu/fpu_proto.h b/kernel/FPU-emu/fpu_proto.h
index e2fbbb1..78492f3 100644
--- a/kernel/FPU-emu/fpu_proto.h
+++ b/kernel/FPU-emu/fpu_proto.h
@@ -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);
diff --git a/kernel/FPU-emu/fpu_system.h b/kernel/FPU-emu/fpu_system.h
index c8998b8..3f0def7 100644
--- a/kernel/FPU-emu/fpu_system.h
+++ b/kernel/FPU-emu/fpu_system.h
@@ -11,18 +11,25 @@
/* 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
diff --git a/kernel/FPU-emu/fpu_trig.c b/kernel/FPU-emu/fpu_trig.c
index a298f2e..0def167 100644
--- a/kernel/FPU-emu/fpu_trig.c
+++ b/kernel/FPU-emu/fpu_trig.c
@@ -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;
diff --git a/kernel/FPU-emu/get_address.c b/kernel/FPU-emu/get_address.c
index e4e7046..75b149e 100644
--- a/kernel/FPU-emu/get_address.c
+++ b/kernel/FPU-emu/get_address.c
@@ -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:
diff --git a/kernel/FPU-emu/load_store.c b/kernel/FPU-emu/load_store.c
index 342f463..7e66a51 100644
--- a/kernel/FPU-emu/load_store.c
+++ b/kernel/FPU-emu/load_store.c
@@ -10,6 +10,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"
@@ -18,13 +25,14 @@
#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;
}
diff --git a/kernel/FPU-emu/poly_2xm1.c b/kernel/FPU-emu/poly_2xm1.c
index 266617f..749df16 100644
--- a/kernel/FPU-emu/poly_2xm1.c
+++ b/kernel/FPU-emu/poly_2xm1.c
@@ -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;
diff --git a/kernel/FPU-emu/poly_atan.c b/kernel/FPU-emu/poly_atan.c
index 06b45e2..b62b0e7 100644
--- a/kernel/FPU-emu/poly_atan.c
+++ b/kernel/FPU-emu/poly_atan.c
@@ -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
diff --git a/kernel/FPU-emu/poly_l2.c b/kernel/FPU-emu/poly_l2.c
index 3ca20c3..193c3e4 100644
--- a/kernel/FPU-emu/poly_l2.c
+++ b/kernel/FPU-emu/poly_l2.c
@@ -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;
diff --git a/kernel/FPU-emu/poly_sin.c b/kernel/FPU-emu/poly_sin.c
index 8ec1175..91a9cf3 100644
--- a/kernel/FPU-emu/poly_sin.c
+++ b/kernel/FPU-emu/poly_sin.c
@@ -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 */
}
}
diff --git a/kernel/FPU-emu/poly_tan.c b/kernel/FPU-emu/poly_tan.c
index 2f8fb41..0129f5b 100644
--- a/kernel/FPU-emu/poly_tan.c
+++ b/kernel/FPU-emu/poly_tan.c
@@ -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;
diff --git a/kernel/FPU-emu/reg_add_sub.c b/kernel/FPU-emu/reg_add_sub.c
index bd801bb..6167fe6 100644
--- a/kernel/FPU-emu/reg_add_sub.c
+++ b/kernel/FPU-emu/reg_add_sub.c
@@ -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;
diff --git a/kernel/FPU-emu/reg_compare.c b/kernel/FPU-emu/reg_compare.c
index 0cb557a..5a5172a 100644
--- a/kernel/FPU-emu/reg_compare.c
+++ b/kernel/FPU-emu/reg_compare.c
@@ -10,7 +10,7 @@
+---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------+
- | compare() is the core REG comparison function |
+ | compare() is the core FPU_REG comparison function |
+---------------------------------------------------------------------------*/
#include "fpu_system.h"
@@ -19,13 +19,13 @@
#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
diff --git a/kernel/FPU-emu/reg_constant.c b/kernel/FPU-emu/reg_constant.c
index e8b0350..aadf589 100644
--- a/kernel/FPU-emu/reg_constant.c
+++ b/kernel/FPU-emu/reg_constant.c
@@ -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 |
@@ -15,45 +15,45 @@
#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;
}
diff --git a/kernel/FPU-emu/reg_constant.h b/kernel/FPU-emu/reg_constant.h
index 4297588..a039bc6 100644
--- a/kernel/FPU-emu/reg_constant.h
+++ b/kernel/FPU-emu/reg_constant.h
@@ -11,21 +11,20 @@
#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_
-
diff --git a/kernel/FPU-emu/reg_div.S b/kernel/FPU-emu/reg_div.S
index 3d5a4aa..46979b5 100644
--- a/kernel/FPU-emu/reg_div.S
+++ b/kernel/FPU-emu/reg_div.S
@@ -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) |
| |
+---------------------------------------------------------------------------*/
diff --git a/kernel/FPU-emu/reg_ld_str.c b/kernel/FPU-emu/reg_ld_str.c
index 4809386..9028bd4 100644
--- a/kernel/FPU-emu/reg_ld_str.c
+++ b/kernel/FPU-emu/reg_ld_str.c
@@ -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"
@@ -31,16 +38,27 @@
#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
}
}
diff --git a/kernel/FPU-emu/reg_mul.c b/kernel/FPU-emu/reg_mul.c
index 3d33979..d5992c3 100644
--- a/kernel/FPU-emu/reg_mul.c
+++ b/kernel/FPU-emu/reg_mul.c
@@ -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))
diff --git a/kernel/FPU-emu/reg_norm.S b/kernel/FPU-emu/reg_norm.S
index c7377c5..0a271da 100644
--- a/kernel/FPU-emu/reg_norm.S
+++ b/kernel/FPU-emu/reg_norm.S
@@ -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) |
| |
+---------------------------------------------------------------------------*/
diff --git a/kernel/FPU-emu/reg_u_add.S b/kernel/FPU-emu/reg_u_add.S
index 07e4f63..1595e3e 100644
--- a/kernel/FPU-emu/reg_u_add.S
+++ b/kernel/FPU-emu/reg_u_add.S
@@ -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 |
diff --git a/kernel/FPU-emu/reg_u_div.S b/kernel/FPU-emu/reg_u_div.S
index 6599f7d..a24059c 100644
--- a/kernel/FPU-emu/reg_u_div.S
+++ b/kernel/FPU-emu/reg_u_div.S
@@ -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. |
+---------------------------------------------------------------------------*/
diff --git a/kernel/FPU-emu/version.h b/kernel/FPU-emu/version.h
index cd492ed..7d69a85 100644
--- a/kernel/FPU-emu/version.h
+++ b/kernel/FPU-emu/version.h
@@ -8,5 +8,5 @@
| |
+---------------------------------------------------------------------------*/
-#define FPU_VERSION "wm-FPU-emu version ALPHA 0.61"
+#define FPU_VERSION "wm-FPU-emu version ALPHA 0.7"
diff --git a/kernel/FPU-emu/wm_sqrt.S b/kernel/FPU-emu/wm_sqrt.S
index 2ce3af6..b3fb0c2 100644
--- a/kernel/FPU-emu/wm_sqrt.S
+++ b/kernel/FPU-emu/wm_sqrt.S
@@ -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 |
diff --git a/kernel/Makefile b/kernel/Makefile
index 0661a0b..fa352d2 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -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
diff --git a/kernel/blk_drv/Makefile b/kernel/blk_drv/Makefile
index ccbe8ed..58b9340 100644
--- a/kernel/blk_drv/Makefile
+++ b/kernel/blk_drv/Makefile
@@ -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
diff --git a/kernel/blk_drv/floppy.c b/kernel/blk_drv/floppy.c
index 512500f..7afaf53 100644
--- a/kernel/blk_drv/floppy.c
+++ b/kernel/blk_drv/floppy.c
@@ -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)
diff --git a/kernel/blk_drv/hd.c b/kernel/blk_drv/hd.c
index 9b68aad..0973749 100644
--- a/kernel/blk_drv/hd.c
+++ b/kernel/blk_drv/hd.c
@@ -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;
diff --git a/kernel/blk_drv/ll_rw_blk.c b/kernel/blk_drv/ll_rw_blk.c
index c6aef54..590a376 100644
--- a/kernel/blk_drv/ll_rw_blk.c
+++ b/kernel/blk_drv/ll_rw_blk.c
@@ -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)
diff --git a/kernel/blk_drv/scsi/Makefile b/kernel/blk_drv/scsi/Makefile
index 226a8c0..5765807 100644
--- a/kernel/blk_drv/scsi/Makefile
+++ b/kernel/blk_drv/scsi/Makefile
@@ -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
diff --git a/kernel/chr_drv/Makefile b/kernel/chr_drv/Makefile
index 39d3f51..0c79e8c 100644
--- a/kernel/chr_drv/Makefile
+++ b/kernel/chr_drv/Makefile
@@ -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
diff --git a/kernel/chr_drv/keyboard.c b/kernel/chr_drv/keyboard.c
index ac24701..e7b49b7 100644
--- a/kernel/chr_drv/keyboard.c
+++ b/kernel/chr_drv/keyboard.c
@@ -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"::);
diff --git a/kernel/chr_drv/psaux.c b/kernel/chr_drv/psaux.c
index 3287d8d..50b25d5 100644
--- a/kernel/chr_drv/psaux.c
+++ b/kernel/chr_drv/psaux.c
@@ -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);
diff --git a/kernel/chr_drv/serial.c b/kernel/chr_drv/serial.c
index 62cf0b6..89b0220 100644
--- a/kernel/chr_drv/serial.c
+++ b/kernel/chr_drv/serial.c
@@ -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;
}
diff --git a/kernel/chr_drv/tty_io.c b/kernel/chr_drv/tty_io.c
index 2b25ca4..b5a5e4e 100644
--- a/kernel/chr_drv/tty_io.c
+++ b/kernel/chr_drv/tty_io.c
@@ -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));
diff --git a/kernel/exit.c b/kernel/exit.c
index d7a0891..30b14e0 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -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
diff --git a/kernel/fork.c b/kernel/fork.c
index 8024f29..8eb1a87 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -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++;
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 73575ab..52e0d41 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -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);
diff --git a/kernel/sched.c b/kernel/sched.c
index dc7677d..a45279d 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -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++) {
diff --git a/kernel/sys_call.S b/kernel/sys_call.S
index 6de8470..3507ed3 100644
--- a/kernel/sys_call.S
+++ b/kernel/sys_call.S
@@ -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
diff --git a/lib/Makefile b/lib/Makefile
index 5a21576..fb6eaae 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -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
diff --git a/lib/malloc.c b/lib/malloc.c
index fe0a74c..d0e42c9 100644
--- a/lib/malloc.c
+++ b/lib/malloc.c
@@ -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.
*
@@ -25,20 +25,20 @@
* 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,
@@ -46,12 +46,18 @@
*/
/* 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;
diff --git a/mm/Makefile b/mm/Makefile
index 6230013..7e9e19a 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -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
diff --git a/mm/memory.c b/mm/memory.c
index 6512d7f..07f074b 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -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;
diff --git a/net/Makefile b/net/Makefile
index f69daf0..b29a4d8 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -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
diff --git a/net/socket.c b/net/socket.c
index 3928a69..e8c3ab6 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -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);
diff --git a/net/tcp/Makefile b/net/tcp/Makefile
index fe99baf..e4f7131 100644
--- a/net/tcp/Makefile
+++ b/net/tcp/Makefile
@@ -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
diff --git a/net/tcp/arp.c b/net/tcp/arp.c
index 1b2578f..33edff0 100644
--- a/net/tcp/arp.c
+++ b/net/tcp/arp.c
@@ -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;
diff --git a/net/tcp/dev.c b/net/tcp/dev.c
index 4c96076..b6c2cc2 100644
--- a/net/tcp/dev.c
+++ b/net/tcp/dev.c
@@ -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;
diff --git a/net/tcp/icmp.c b/net/tcp/icmp.c
index c48e967..8afa92a 100644
--- a/net/tcp/icmp.c
+++ b/net/tcp/icmp.c
@@ -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 */
diff --git a/net/tcp/ip.c b/net/tcp/ip.c
index 35d2a73..6c1249e 100644
--- a/net/tcp/ip.c
+++ b/net/tcp/ip.c
@@ -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;
diff --git a/net/tcp/packet.c b/net/tcp/packet.c
index ffad524..5b37677 100644
--- a/net/tcp/packet.c
+++ b/net/tcp/packet.c
@@ -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;
diff --git a/net/tcp/raw.c b/net/tcp/raw.c
index 8cd116e..41dacdc 100644
--- a/net/tcp/raw.c
+++ b/net/tcp/raw.c
@@ -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;
diff --git a/net/tcp/sock.c b/net/tcp/sock.c
index ad570f7..f01422c 100644
--- a/net/tcp/sock.c
+++ b/net/tcp/sock.c
@@ -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);
- }
}
diff --git a/net/tcp/sock.h b/net/tcp/sock.h
index b2655e7..be9f60e 100644
--- a/net/tcp/sock.h
+++ b/net/tcp/sock.h
@@ -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);
diff --git a/net/tcp/tcp.c b/net/tcp/tcp.c
index ef31011..35f7317 100644
--- a/net/tcp/tcp.c
+++ b/net/tcp/tcp.c
@@ -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;
diff --git a/net/tcp/udp.c b/net/tcp/udp.c
index 99fc5d7..d73a141 100644
--- a/net/tcp/udp.c
+++ b/net/tcp/udp.c
@@ -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)
diff --git a/tools/version.h b/tools/version.h
index fc6e01f..c9302bd 100644
--- a/tools/version.h
+++ b/tools/version.h
@@ -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"