aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Benedict Torvalds <torvalds@klaava.Helsinki.FI>1992-08-01 15:08:38 +0000
committerNicolas Pitre <nico@cam.org>2007-08-19 14:19:06 -0400
commit36c51b40b2a02f608b7214efd71cb1e0bbd17788 (patch)
treed98963643d94ad6edce0b75cc62ac162dca870ad
parent67406b341328a6503eaa3de23e553be903ed5891 (diff)
downloadarchive-36c51b40b2a02f608b7214efd71cb1e0bbd17788.tar.gz
Linux v. 0.97 is outv0.97
Linux version 0.97 is available as both a complete source-tree (linux-0.97.tar.Z) and a bootimage (bootimage-0.97.Z) on the normal ftp-sites. It's in incoming on tsx-11.mit.edu, so it will take a day or two to actually show up, but it's available right now on nic.funet.fi: pub/OS/Linux/testing/Linus/ banjo.concert.net: pub/Linux/Linus/ The nic.funet.fi-directory is under 'testing' not so much because this would be a testing-release, but because the directory-setup is in testing :-). I think 'testing' is unreadable, so you have to cd to the directory blindly. There is also a kernel-compilation README (written by Lars Wirzenius), as well as a COPYING (which is just a pointer to the GNU copyleft). The latter not because anything has changed, but because I got a few mails pointing out that the copyright of linux wasn't too clear. That also resulted in changing the '(C)'s in the source to 'Copyright'. Changes in 0.97: - The VESA-support was removed. I'd be happy to put it back once it works on all hardware. Instead of the VESA-code, I finally put in the automatic SVGA setup patches. See the top-level Makefile. - The IRQ code has solidified, and should work on all machines. Not all of the SCSI drivers use it yet, so I expect patches for that.. - Serial interrupts are handled slightly differently, and performance should be up. I've sent out a few alpha-releases, and testing seems to indicate that's actually true this time. Reactions have ranged from "nice" to "wonderful" :-) - The buffer-cache and memory management code has been edited quite a bit. ps/free etc programs that reads kernel memory directly no longer work, and even a recompilation won't be enough. They actually need editing before they work. The buffer-cache now grows and shrinks dynamically depending on how much free memory there is. Shift+PrintScreen will give some memory statistics. (Ctrl+PrSc gives task-info, ALT+PrSc gives current register values). The mm code changes removed some race-conditions in the VM code, and I also tried to make the Out-of-swapspace error less severe (better thrashing-detection etc). - The super-block code has been cleaned up. Especially the extended fs needs to be edited a bit to take advantage of the new setup, and I expect Remy Card will have a patch out eventually. - include-files have been moved around some more: there are still some names that clash with the standard headers, but not many. - Unswappable processes implemented: by default only 'init' is unswappable. This is a bit safer in low-memory conditions, as at least init won't die due to low memory. I also made killing init impossible: if init doesn't recognize a signal, it simply won't get it. Some other changes ("while (1) fork();" won't kill the machine for non-root users etc) - The new SCSI drivers are in. These make the kernel noticeably bigger, but you can leave them out if you don't want them. - The floppy- and hd-drivers print out more debugging-info in case of errors: this might be irritating if you have hardware that works, but often gives soft-errors. On the other hand, some old debugging-info was removed - notably for user-level protection errors etc. - Various minor fixes. I haven't made cdiffs (and I haven't gotten any requests for them, so I probably never will), but they would be pretty big. Things that I didn't have time for: - I wanted to rewrite the tty drivers to be more "streams-like" (ie not an actual streams-implementation, but some of the ideas from streams). I never got around to it: there was simply too much else to do. - I got a lot of patches, and some went in, others didn't. If you think your patch was important, please re-send it relative to the new version. I'd like comments on the new system: performance / clarity of code etc. 0.97 should correct all known bugs (at least the ones I know about), but I guess that's just wishful thinking. Note that the dynamic buffer-code also handles differently-sized buffers, but that the rest of the system (block device drivers, filesystem code etc) cannot yet take advantage of this - there is still some coding needed. Linus
-rw-r--r--Makefile47
-rw-r--r--boot/bootsect.S2
-rw-r--r--boot/head.s22
-rw-r--r--boot/setup.S279
-rw-r--r--fs/Makefile227
-rw-r--r--fs/block_dev.c7
-rw-r--r--fs/buffer.c303
-rw-r--r--fs/exec.c69
-rw-r--r--fs/ext/Makefile154
-rw-r--r--fs/ext/bitmap.c6
-rw-r--r--fs/ext/blkdev.c7
-rw-r--r--fs/ext/chrdev.c7
-rw-r--r--fs/ext/dir.c9
-rw-r--r--fs/ext/file.c17
-rw-r--r--fs/ext/freelists.c139
-rw-r--r--fs/ext/inode.c154
-rw-r--r--fs/ext/namei.c29
-rw-r--r--fs/ext/symlink.c11
-rw-r--r--fs/ext/truncate.c62
-rw-r--r--fs/fcntl.c9
-rw-r--r--fs/fifo.c7
-rw-r--r--fs/file_table.c17
-rw-r--r--fs/inode.c6
-rw-r--r--fs/ioctl.c8
-rw-r--r--fs/minix/Makefile146
-rw-r--r--fs/minix/bitmap.c36
-rw-r--r--fs/minix/blkdev.c5
-rw-r--r--fs/minix/chrdev.c5
-rw-r--r--fs/minix/dir.c7
-rw-r--r--fs/minix/file.c15
-rw-r--r--fs/minix/inode.c68
-rw-r--r--fs/minix/namei.c23
-rw-r--r--fs/minix/symlink.c9
-rw-r--r--fs/minix/truncate.c9
-rw-r--r--fs/msdos/Makefile94
-rw-r--r--fs/msdos/dir.c9
-rw-r--r--fs/msdos/fat.c6
-rw-r--r--fs/msdos/file.c10
-rw-r--r--fs/msdos/inode.c19
-rw-r--r--fs/msdos/misc.c27
-rw-r--r--fs/msdos/namei.c27
-rw-r--r--fs/namei.c4
-rw-r--r--fs/open.c32
-rw-r--r--fs/pipe.c36
-rw-r--r--fs/read_write.c9
-rw-r--r--fs/select.c39
-rw-r--r--fs/stat.c5
-rw-r--r--fs/super.c101
-rw-r--r--include/asm/irq.h63
-rw-r--r--include/errno.h64
-rw-r--r--include/limits.h62
-rw-r--r--include/linux/a.out.h (renamed from include/a.out.h)0
-rw-r--r--include/linux/config.dist.h4
-rw-r--r--include/linux/config.h26
-rw-r--r--include/linux/config_rel.h2
-rw-r--r--include/linux/config_ver.h2
-rw-r--r--include/linux/dirent.h (renamed from include/sys/dirent.h)7
-rw-r--r--include/linux/errno.h130
-rw-r--r--include/linux/ext_fs.h8
-rw-r--r--include/linux/ext_fs_sb.h19
-rw-r--r--include/linux/fcntl.h2
-rw-r--r--include/linux/fd.h20
-rw-r--r--include/linux/fdreg.h25
-rw-r--r--include/linux/fs.h71
-rw-r--r--include/linux/genhd.h52
-rw-r--r--include/linux/hdreg.h19
-rw-r--r--include/linux/head.h4
-rw-r--r--include/linux/kernel.h5
-rw-r--r--include/linux/limits.h13
-rw-r--r--include/linux/lp.h14
-rw-r--r--include/linux/math_emu.h5
-rw-r--r--include/linux/minix_fs.h11
-rw-r--r--include/linux/minix_fs_sb.h19
-rw-r--r--include/linux/mm.h76
-rw-r--r--include/linux/mouse.h6
-rw-r--r--include/linux/msdos_fs.h38
-rw-r--r--include/linux/msdos_fs_sb.h18
-rw-r--r--include/linux/param.h (renamed from include/sys/param.h)0
-rw-r--r--include/linux/ptrace.h (renamed from include/sys/ptrace.h)6
-rw-r--r--include/linux/resource.h (renamed from include/sys/resource.h)8
-rw-r--r--include/linux/sched.h17
-rw-r--r--include/linux/signal.h (renamed from include/signal.h)34
-rw-r--r--include/linux/socket.h (renamed from include/sys/socket.h)15
-rw-r--r--include/linux/stddef.h (renamed from include/stddef.h)11
-rw-r--r--include/linux/string.h10
-rw-r--r--include/linux/sys.h3
-rw-r--r--include/linux/termios.h (renamed from include/termios.h)37
-rw-r--r--include/linux/time.h33
-rw-r--r--include/linux/timer.h4
-rw-r--r--include/linux/times.h (renamed from include/sys/times.h)8
-rw-r--r--include/linux/tty.h42
-rw-r--r--include/linux/types.h (renamed from include/sys/types.h)6
-rw-r--r--include/linux/un.h (renamed from include/sys/un.h)4
-rw-r--r--include/linux/user.h (renamed from include/sys/user.h)7
-rw-r--r--include/linux/utime.h9
-rw-r--r--include/linux/vfs.h (renamed from include/sys/vfs.h)4
-rw-r--r--include/linux/wait.h3
-rw-r--r--[-rwxr-xr-x]include/stdarg.h0
-rw-r--r--include/sys/time.h67
-rw-r--r--include/sys/wait.h24
-rw-r--r--include/unistd.h164
-rw-r--r--include/utime.h21
-rw-r--r--init/main.c46
-rw-r--r--kernel/Makefile194
-rw-r--r--kernel/asm.s51
-rw-r--r--kernel/blk_drv/Makefile78
-rw-r--r--kernel/blk_drv/blk.h37
-rw-r--r--kernel/blk_drv/floppy.c362
-rw-r--r--kernel/blk_drv/genhd.c195
-rw-r--r--kernel/blk_drv/hd.c413
-rw-r--r--kernel/blk_drv/ll_rw_blk.c34
-rw-r--r--kernel/blk_drv/ramdisk.c9
-rw-r--r--kernel/blk_drv/scsi/7000fasst.c465
-rw-r--r--kernel/blk_drv/scsi/7000fasst.h137
-rw-r--r--kernel/blk_drv/scsi/Makefile217
-rw-r--r--kernel/blk_drv/scsi/aha1542.c92
-rw-r--r--kernel/blk_drv/scsi/aha1542.h33
-rw-r--r--kernel/blk_drv/scsi/config.out10
-rw-r--r--kernel/blk_drv/scsi/fdomain.c1234
-rw-r--r--kernel/blk_drv/scsi/fdomain.h45
-rw-r--r--kernel/blk_drv/scsi/hosts.c90
-rw-r--r--kernel/blk_drv/scsi/hosts.h2
-rw-r--r--kernel/blk_drv/scsi/scsi.c248
-rw-r--r--kernel/blk_drv/scsi/scsi.h17
-rw-r--r--kernel/blk_drv/scsi/scsi_ioctl.c55
-rw-r--r--kernel/blk_drv/scsi/sd.c244
-rw-r--r--kernel/blk_drv/scsi/sd.h33
-rw-r--r--kernel/blk_drv/scsi/sd_ioctl.c8
-rw-r--r--kernel/blk_drv/scsi/seagate.c872
-rw-r--r--kernel/blk_drv/scsi/seagate.h20
-rw-r--r--kernel/blk_drv/scsi/seagate2.s36
-rw-r--r--kernel/blk_drv/scsi/st.c4
-rw-r--r--kernel/blk_drv/scsi/st.h2
-rw-r--r--kernel/blk_drv/scsi/st_ioctl.c6
-rw-r--r--kernel/blk_drv/scsi/ultrastor.c132
-rw-r--r--kernel/blk_drv/scsi/ultrastor.h30
-rw-r--r--kernel/chr_drv/Makefile161
-rw-r--r--kernel/chr_drv/console.c36
-rw-r--r--kernel/chr_drv/keyboard.c81
-rw-r--r--kernel/chr_drv/lp.c1
-rw-r--r--kernel/chr_drv/mem.c52
-rw-r--r--kernel/chr_drv/mouse.c17
-rw-r--r--kernel/chr_drv/pty.c5
-rw-r--r--kernel/chr_drv/serial.c67
-rw-r--r--kernel/chr_drv/tty_io.c31
-rw-r--r--kernel/chr_drv/tty_ioctl.c27
-rw-r--r--kernel/chr_drv/vt.c18
-rw-r--r--kernel/exit.c10
-rw-r--r--kernel/fork.c38
-rw-r--r--kernel/ioport.c5
-rw-r--r--kernel/irq.c166
-rw-r--r--kernel/itimer.c10
-rw-r--r--kernel/math/Makefile113
-rw-r--r--kernel/math/add.c2
-rw-r--r--kernel/math/compare.c2
-rw-r--r--kernel/math/convert.c2
-rw-r--r--kernel/math/div.c2
-rw-r--r--kernel/math/ea.c6
-rw-r--r--kernel/math/emulate.c6
-rw-r--r--kernel/math/error.c16
-rw-r--r--kernel/math/get_put.c5
-rw-r--r--kernel/math/mul.c2
-rw-r--r--kernel/math/sqrt.c2
-rw-r--r--kernel/mktime.c2
-rw-r--r--kernel/panic.c2
-rw-r--r--kernel/printk.c7
-rw-r--r--kernel/ptrace.c10
-rw-r--r--kernel/sched.c36
-rw-r--r--kernel/signal.c19
-rw-r--r--kernel/sys.c17
-rw-r--r--kernel/sys_call.S45
-rw-r--r--kernel/traps.c76
-rw-r--r--kernel/vsprintf.c3
-rw-r--r--lib/Makefile20
-rw-r--r--lib/_exit.c2
-rw-r--r--lib/close.c2
-rw-r--r--lib/ctype.c2
-rw-r--r--lib/dup.c2
-rw-r--r--lib/errno.c2
-rw-r--r--lib/execve.c2
-rw-r--r--lib/itimer.c12
-rw-r--r--lib/malloc.c4
-rw-r--r--lib/open.c2
-rw-r--r--lib/setsid.c4
-rw-r--r--lib/string.c4
-rw-r--r--lib/wait.c4
-rw-r--r--lib/write.c4
-rw-r--r--mm/Makefile43
-rw-r--r--mm/memory.c287
-rw-r--r--mm/mmap.c8
-rw-r--r--mm/swap.c196
-rw-r--r--net/Makefile37
-rw-r--r--net/socket.c12
-rw-r--r--net/unix.c18
-rw-r--r--tools/build.c8
195 files changed, 7091 insertions, 3796 deletions
diff --git a/Makefile b/Makefile
index ec70574..39e87db 100644
--- a/Makefile
+++ b/Makefile
@@ -36,6 +36,7 @@ KEYBOARD = -DKBD_FINNISH -DKBDFLAGS=0
# KEYBOARD = -DKBD_DVORAK -DKBDFLAGS=0
# KEYBOARD = -DKBD_SG -DKBDFLAGS=0
# KEYBOARD = -DKBD_SG_LATIN1 -DKBDFLAGS=0x9F
+# KEYBOARD = -DKDB_NO
#
# comment this line if you don't want the emulation-code
@@ -59,6 +60,14 @@ CFLAGS =-Wall -O6 -fomit-frame-pointer
AS86 =as86 -0 -a
LD86 =ld86 -0
+#
+# If you want to preset the SVGA mode, uncomment the next line and
+# set SVGA_MODE to whatever number you want.
+# Set it to -DSVGA_MODE=NORMAL_VGA if you just want the EGA/VGA mode.
+# The number is the same as you would ordinarily press at bootup.
+#
+#SVGA_MODE= -DSVGA_MODE=1
+
AS =as
LD =ld
HOSTCC =gcc -static
@@ -86,12 +95,12 @@ KERNELHDRS =/usr/src/linux/include
all: Version Image
-subdirs: dummy
- for i in $(SUBDIRS); do (cd $$i; $(MAKE)); done
+linuxsubdirs: dummy
+ @for i in $(SUBDIRS); do (cd $$i; echo $$i; $(MAKE)) || exit; done
Version:
@./makever.sh
- @echo \#define UTS_RELEASE \"0.96c.pl2-`cat .version`\" > include/linux/config_rel.h
+ @echo \#define UTS_RELEASE \"0.97-`cat .version`\" > include/linux/config_rel.h
@echo \#define UTS_VERSION \"`date +%D`\" > include/linux/config_ver.h
touch include/linux/config.h
@@ -103,7 +112,7 @@ Image: boot/bootsect boot/setup tools/system tools/build
sync
disk: Image
- dd bs=8192 if=Image of=/dev/PS0
+ dd bs=8192 if=Image of=/dev/fd0
tools/build: tools/build.c
$(HOSTCC) $(CFLAGS) \
@@ -111,7 +120,7 @@ tools/build: tools/build.c
boot/head.o: boot/head.s
-tools/system: boot/head.o init/main.o subdirs
+tools/system: boot/head.o init/main.o linuxsubdirs
$(LD) $(LDFLAGS) -M boot/head.o init/main.o \
$(ARCHIVES) \
$(FILESYSTEMS) \
@@ -125,7 +134,7 @@ boot/setup: boot/setup.s
$(LD86) -s -o boot/setup boot/setup.o
boot/setup.s: boot/setup.S include/linux/config.h
- $(CPP) -traditional boot/setup.S -o boot/setup.s
+ $(CPP) -traditional $(SVGA_MODE) boot/setup.S -o boot/setup.s
boot/bootsect.s: boot/bootsect.S include/linux/config.h
$(CPP) -traditional boot/bootsect.S -o boot/bootsect.s
@@ -134,6 +143,9 @@ boot/bootsect: boot/bootsect.s
$(AS86) -o boot/bootsect.o boot/bootsect.s
$(LD86) -s -o boot/bootsect boot/bootsect.o
+fs: dummy
+ $(MAKE) linuxsubdirs SUBDIRS=fs
+
clean:
rm -f Image System.map tmp_make core boot/bootsect boot/setup \
boot/bootsect.s boot/setup.s init/main.s
@@ -148,18 +160,19 @@ depend dep:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
for i in init/*.c;do echo -n "init/";$(CPP) -M $$i;done >> tmp_make
cp tmp_make Makefile
- for i in $(SUBDIRS); do (cd $$i; $(MAKE) dep); done
+ for i in $(SUBDIRS); do (cd $$i; $(MAKE) dep) || exit; done
dummy:
### Dependencies:
-init/main.o : init/main.c /usr/src/linux/include/stddef.h /usr/src/linux/include/stdarg.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/asm/system.h \
- /usr/src/linux/include/asm/io.h /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/linux/config.h \
- /usr/src/linux/include/linux/config_rel.h /usr/src/linux/include/linux/config_ver.h \
- /usr/src/linux/include/linux/config.dist.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \
- /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
- /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \
- /usr/src/linux/include/sys/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/tty.h \
- /usr/src/linux/include/termios.h /usr/src/linux/include/linux/unistd.h
+init/main.o : init/main.c /usr/src/linux/include/stdarg.h /usr/src/linux/include/time.h \
+ /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/io.h /usr/src/linux/include/linux/types.h \
+ /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/linux/config.h /usr/src/linux/include/linux/config_rel.h \
+ /usr/src/linux/include/linux/config_ver.h /usr/src/linux/include/linux/config.dist.h \
+ /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
+ /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/tty.h /usr/src/linux/include/linux/termios.h /usr/src/linux/include/linux/unistd.h
diff --git a/boot/bootsect.S b/boot/bootsect.S
index 22ebdea..b69e95c 100644
--- a/boot/bootsect.S
+++ b/boot/bootsect.S
@@ -6,7 +6,7 @@
#include <linux/config.h>
SYSSIZE = DEF_SYSSIZE
!
-! bootsect.s (C) 1991 Linus Torvalds
+! bootsect.s Copyright (C) 1991, 1992 Linus Torvalds
! modified by Drew Eckhardt
! modified by Bruce Evans (bde)
!
diff --git a/boot/head.s b/boot/head.s
index 0377139..30ef2d8 100644
--- a/boot/head.s
+++ b/boot/head.s
@@ -1,7 +1,7 @@
/*
* linux/boot/head.s
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
@@ -13,6 +13,9 @@
*/
.text
.globl _idt,_gdt,_pg_dir,_tmp_floppy_area,_floppy_track_buffer
+/*
+ * pg_dir is the main page directory, address 0x00000000
+ */
_pg_dir:
startup_32:
cld
@@ -148,6 +151,23 @@ pg3:
.org 0x5000
/*
+ * empty_bad_page is a bogus page that will be used when out of memory,
+ * so that a process isn't accidentally killed due to a page fault when
+ * it is running in kernel mode..
+ */
+.globl _empty_bad_page
+_empty_bad_page:
+
+.org 0x6000
+/*
+ * empty_bad_page_table is similar to the above, but is used when the
+ * system needs a bogus page-table
+ */
+.globl _empty_bad_page_table
+_empty_bad_page_table:
+
+.org 0x7000
+/*
* tmp_floppy_area is used by the floppy-driver when DMA cannot
* reach to a buffer-block. It needs to be aligned, so that it isn't
* on a 64kB border.
diff --git a/boot/setup.S b/boot/setup.S
index 88c23cd..cf4ae0e 100644
--- a/boot/setup.S
+++ b/boot/setup.S
@@ -1,5 +1,5 @@
!
-! setup.s (C) 1991 Linus Torvalds
+! setup.s Copyright (C) 1991, 1992 Linus Torvalds
!
! setup.s is responsible for getting the system data from the BIOS,
! and putting them into the appropriate places in system memory.
@@ -14,6 +14,7 @@
! NOTE! These had better be the same as in bootsect.s!
#include <linux/config.h>
+#define NORMAL_VGA 0xffff
INITSEG = DEF_INITSEG ! we move boot here - out of the way
SYSSEG = DEF_SYSSEG ! system loaded at 0x10000 (65536).
@@ -242,75 +243,11 @@ chsvga: cld
push ds
push cs
pop ds
-
-! First try and execute a VESA BIOS call
-
- mov ax,#0x4f00 ! AX = VESA BIOS func RETURN SVGA Info
- push cs
- pop es
- lea di,vib ! ES:[DI] -> VESA Information Block Ptr
- int 0x10
-
- cmp ax,#0x004f ! Check result status
- jne novesa ! VESA BIOS not supported or failed
-
-! OK! We got a VESA BIOS, let's figure out what we can do!
-
-! Print out the VESA information from the VIB
-
- lea si,vib ! This should print out VESA
- lodsb
- call prnt1
- lodsb
- call prnt1
- lodsb
- call prnt1
- lodsb
- call prnt1
- call space
-
- mov al,vib+5 ! This is the version of VESA supported
- call dprnt
- mov al,#0x2e
- call prnt1
- mov al,vib+4
- call dprnt
- call space
-
- push ds
- lds si,vib+6 ! This prints out the OEM string
- call prtstr
- call space
- pop ds
-
- mov al,vib+10 ! This prints out the Vesa Capabilities
- call dprnt
- mov al,vib+11
- call dprnt
- mov al,vib+12
- call dprnt
- mov al,vib+13
- call dprnt
-
- push ds ! Finally, go through the list of modes
- lds si,vib+14
-model: lodsw ! Get mode number
- cmp ax,#0xFFFF
- je isvesa
- call addmod ! Check to see if this is a TEXT mode
- jmp model
-
-isvesa: call docr
- pop ds
- lea si,dscvesa
- lea di,movesa
- lea cx,selmod
- jmp cx
-
-novesa: mov ax,#0xc000
+ mov ax,#0xc000
mov es,ax
lea si,msg1
- call prtstr ! Press <RETURN> to see SVGA-modes ...
+ call prtstr
+#ifndef SVGA_MODE
flush: in al,#0x60 ! Flush the keyboard buffer
cmp al,#0x82
jb nokey
@@ -322,9 +259,12 @@ nokey: call getkey
ja nokey
cmp al,#0x9c
je svga
+#endif
+#if !defined(SVGA_MODE) || SVGA_MODE == NORMAL_VGA
mov ax,#0x5019
pop ds
ret
+#endif
svga: cld
lea si,idati ! Check ATI 'clues'
mov di,#0x31
@@ -529,38 +469,23 @@ even7: mov al,#0x0c
mov al,#0x55
xor al,#0xea
cmp al,bh
- je isvideo7
- lea cx,set8x8
- jmp cx
-isvideo7:
+ jne novid7
lea si,dscvideo7
lea di,movideo7
-
-! Upon Entry to SELMOD, SI -> list of Modes, DI -> List of Mode Numbers
-
selmod: push si
- lea si,msg2 ! Numb: Mode: COLSxROWS
+ lea si,msg2
call prtstr
- mov cx,(di) ! This gets Number of Modes in list
+ xor cx,cx
+ mov cl,(di)
pop si
push si
push cx
tbl: pop bx
push bx
- mov ax,bx
- sub ax,cx
- call hprntl ! Print out selection number
- push ax
- call spcing
- pop ax
- push di
- add ax,ax
- add ax,#2
- add di,ax
- mov ax,(di)
- call hprntl ! Print out MODE number
+ mov al,bl
+ sub al,cl
+ call dprnt
call spcing
- pop di
lodsw
xchg al,ah
call dprnt
@@ -574,10 +499,13 @@ tbl: pop bx
loop tbl
pop cx
call docr
- lea si,msg3 ! Choose Mode Number
+ lea si,msg3
call prtstr
pop si
add cl,#0x80
+#if defined(SVGA_MODE) && SVGA_MODE != NORMAL_VGA
+ mov al,#SVGA_MODE ! Preset SVGA mode
+#else
nonum: call getkey
cmp al,#0x82
jb nonum
@@ -589,39 +517,20 @@ nonum: call getkey
zero: sub al,#0x0a
nozero: sub al,#0x80
dec al
+#endif
xor ah,ah
- shl ax,#1
- push ax
add di,ax
inc di
- inc di
- mov ax,(di) ! AX = Mode
- cmp ah,#0
- jne setvesa
- int 0x10 ! Set OLD style mode
-
-retmode:
+ push ax
+ mov al,(di)
+ int 0x10
pop ax
+ shl ax,#1
add si,ax
- lodsw ! Get COLSxROWS
+ lodsw
pop ds
ret
-
-setvesa:
- pop bx
- cmp ah,#0xFF ! Special, mode FF, set 8x8 font
- je set8x8
-
- push bx
- mov bx,ax ! Mode to set
- mov ax,#0x4f02 ! Set VESA mode
- int 0x10
-
- jmp retmode
-
-! If we can't find the adapter in the table, at least set 80x50
-
-set8x8:
+novid7:
mov ax,#0x1112
mov bl,#0
int 0x10 ! use 8x8 font set (50 lines on VGA)
@@ -642,83 +551,17 @@ set8x8:
mov ax,#0x5032 ! return 80x50
ret
-! Routine to add mode in ax to VESA selection table
-
-addmod: push cx
- push ds
- push es
- push di
- push bx
- push dx
- push ax
-
- mov cx,ax ! CX = VESA mode number
- push cs
- pop es
- lea di,mib ! ES:[DI] -> Mode Information Block
- mov ax,#0x4f01 ! AX = Get VESA Mode Info
- int 0x10
-
- cmp ax,#0x004f ! If fails, assume it's not a TEXT mode
- jne adfail
-
- push cs
- pop ds ! Make DS contain something reasonable
-
- mov ax,mib ! Get Mode Attributes field
- and al,#0x12 ! Mask Text and Extended bits
- cmp al,#0x02 ! Text and Extended info available?
- jne adfail
-
- call space
-
- mov ax,mib+18 ! Horizontal Resolution
- mov bl,mib+22 ! X Char Size
- div bl
-! HACK: For some reason, my Diamond Stealth card returns 160 cols for its
-! 132 coloumn modes, so don't return any sizes > 132?
- sub al,#132
- jbe orgcol
- sub al,al
-orgcol: add al,#132 ! MIN(cols, 132)
- mov dh,al ! Put num cols in DH
- mov ax,mib+20 ! Vertical Resolution
- mov bl,mib+23 ! Y Char Size
- div bl
- mov dl,al ! Put num rows in DL
-
- mov bx,movesa ! Get current number of video modes
- lea di,movesa
- inc (di) ! This is a NEW mode
- add bx,bx
- add di,bx
- add di,#2
- pop ax ! Get Mode number back
- push ax
- mov (di),ax ! Mode number
- lea di,dscvesa
- add di,bx
- mov (di),dx ! Screen resolution
-
-adfail: pop ax
- pop dx
- pop bx
- pop di
- pop es
- pop ds
- pop cx
-
- ret
-
! Routine that 'tabs' to next col.
spcing: mov al,#0x2e
+ call prnt1
+ mov al,#0x20
call prnt1
-space3: mov al,#0x20
+ mov al,#0x20
call prnt1
-space2: mov al,#0x20
+ mov al,#0x20
call prnt1
-space: mov al,#0x20
+ mov al,#0x20
call prnt1
ret
@@ -731,39 +574,6 @@ prtstr: lodsb
jmp prtstr
fin: ret
-! Routine to print out HEX values on screen.
-! The value to be printed is in the AX register.
-
-hprntl: xchg ah,al
- call hprnt
- xchg ah,al
- call hprnt
- ret
-
-! Routine to print out HEX values on the screen
-! The valueto be printed is in the AL register. AH is preserved.
-
-hprnt: push ax
- shr al,4
- and al,#0xf
- call hprnt1
- pop ax
- push ax
- and al,#0xf
- call hprnt1
- pop ax
- ret
-
-! Routine to print out one HEX digit on the screen.
-! The value to be printed is in al (0-F)
-
-hprnt1: cmp al,#10
- jl hdec
- add al,#7 ! Convert 10-15 to A-F
-hdec: add al,#0x30 ! Convert to ASCII
- call prnt1 ! print it
- ret
-
! Routine to print a decimal value on screen, the value to be
! printed is put in al (i.e 0-255).
@@ -835,7 +645,7 @@ gdt_48:
msg1: .ascii "Press <RETURN> to see SVGA-modes available or any other key to continue."
db 0x0d, 0x0a, 0x0a, 0x00
-msg2: .ascii "Numb: Mode: COLSxROWS:"
+msg2: .ascii "Mode: COLSxROWS:"
db 0x0d, 0x0a, 0x0a, 0x00
msg3: .ascii "Choose mode by pressing the corresponding number."
db 0x0d, 0x0a, 0x00
@@ -847,17 +657,16 @@ idparadise: .ascii "VGA="
! Manufacturer: Numofmodes: Mode:
-moati: .word 0x02, 0x23, 0x33
-moahead: .word 0x05, 0x22, 0x23, 0x24, 0x2f, 0x34
-mocandt: .word 0x02, 0x60, 0x61
-mocirrus: .word 0x04, 0x1f, 0x20, 0x22, 0x31
-moeverex: .word 0x0a, 0x03, 0x04, 0x07, 0x08, 0x0a, 0x0b, 0x16, 0x18, 0x21, 0x40
-mogenoa: .word 0x0a, 0x58, 0x5a, 0x60, 0x61, 0x62, 0x63, 0x64, 0x72, 0x74, 0x78
-moparadise: .word 0x02, 0x55, 0x54
-motrident: .word 0x07, 0x50, 0x51, 0x52, 0x57, 0x58, 0x59, 0x5a
-motseng: .word 0x05, 0x26, 0x2a, 0x23, 0x24, 0x22
-movideo7: .word 0x06, 0x40, 0x43, 0x44, 0x41, 0x42, 0x45
-movesa: .word 0x02, 0x03, 0xFFFF, 254*0
+moati: .byte 0x02, 0x23, 0x33
+moahead: .byte 0x05, 0x22, 0x23, 0x24, 0x2f, 0x34
+mocandt: .byte 0x02, 0x60, 0x61
+mocirrus: .byte 0x04, 0x1f, 0x20, 0x22, 0x31
+moeverex: .byte 0x0a, 0x03, 0x04, 0x07, 0x08, 0x0a, 0x0b, 0x16, 0x18, 0x21, 0x40
+mogenoa: .byte 0x0a, 0x58, 0x5a, 0x60, 0x61, 0x62, 0x63, 0x64, 0x72, 0x74, 0x78
+moparadise: .byte 0x02, 0x55, 0x54
+motrident: .byte 0x07, 0x50, 0x51, 0x52, 0x57, 0x58, 0x59, 0x5a
+motseng: .byte 0x05, 0x26, 0x2a, 0x23, 0x24, 0x22
+movideo7: .byte 0x06, 0x40, 0x43, 0x44, 0x41, 0x42, 0x45
! msb = Cols lsb = Rows:
@@ -871,11 +680,7 @@ dscparadise: .word 0x8419, 0x842b
dsctrident: .word 0x501e, 0x502b, 0x503c, 0x8419, 0x841e, 0x842b, 0x843c
dsctseng: .word 0x503c, 0x6428, 0x8419, 0x841c, 0x842c
dscvideo7: .word 0x502b, 0x503c, 0x643c, 0x8419, 0x842c, 0x841c
-dscvesa: .word 0x5019, 0x5032, 254*0
-vib: .word 256*0
-mib: .word 256*0
-
.text
endtext:
.data
diff --git a/fs/Makefile b/fs/Makefile
index 6a8403d..bfe604b 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -20,13 +20,13 @@ 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
-all: fs.o subdirs
+all: fs.o fssubdirs
fs.o: $(OBJS)
$(LD) -r -o fs.o $(OBJS)
-subdirs: dummy
- for i in $(SUBDIRS); do (cd $$i; $(MAKE)); done
+fssubdirs: dummy
+ @for i in $(SUBDIRS); do (cd $$i; echo $$i; $(MAKE)) || exit; done
clean:
rm -f core *.o *.a tmp_make
@@ -37,118 +37,137 @@ depend dep:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
for i in *.c;do $(CPP) -M $$i;done >> tmp_make
cp tmp_make Makefile
- for i in $(SUBDIRS); do (cd $$i; $(MAKE) dep); done
+ for i in $(SUBDIRS); do (cd $$i; $(MAKE) dep) || exit; done
dummy:
### Dependencies:
-block_dev.o : block_dev.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
- /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/segment.h \
- /usr/src/linux/include/asm/system.h
+block_dev.o : block_dev.c /usr/src/linux/include/linux/errno.h /usr/src/linux/include/linux/sched.h \
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/asm/segment.h /usr/src/linux/include/asm/system.h
buffer.o : buffer.c /usr/src/linux/include/stdarg.h /usr/src/linux/include/linux/config.h \
/usr/src/linux/include/linux/config_rel.h /usr/src/linux/include/linux/config_ver.h \
/usr/src/linux/include/linux/config.dist.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
- /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/system.h \
- /usr/src/linux/include/asm/io.h
-exec.o : exec.c /usr/src/linux/include/signal.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/errno.h /usr/src/linux/include/sys/ptrace.h \
- /usr/src/linux/include/a.out.h /usr/src/linux/include/linux/string.h /usr/src/linux/include/linux/stat.h \
- /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \
- /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
- /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
- /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/segment.h /usr/src/linux/include/sys/user.h
-fcntl.o : fcntl.c /usr/src/linux/include/errno.h /usr/src/linux/include/asm/segment.h \
- /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/string.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \
- /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
- /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \
- /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h
-fifo.o : fifo.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/fcntl.h \
- /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \
- /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
- /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \
- /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h
-file_table.o : file_table.c /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/sys/vfs.h
-inode.o : inode.c /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \
- /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
- /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \
- /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \
- /usr/src/linux/include/asm/system.h
-ioctl.o : ioctl.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/string.h \
- /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/stat.h \
- /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
- /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
- /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
- /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
- /usr/src/linux/include/sys/resource.h
-namei.o : namei.c /usr/src/linux/include/errno.h /usr/src/linux/include/const.h \
- /usr/src/linux/include/asm/segment.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
- /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
- /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
- /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
- /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
- /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/string.h \
- /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/linux/stat.h
-open.o : open.c /usr/src/linux/include/errno.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/utime.h /usr/src/linux/include/sys/vfs.h \
- /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/string.h \
- /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
- /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/linux/mm.h \
- /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \
- /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/string.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/io.h
+exec.o : exec.c /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/mm.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/a.out.h /usr/src/linux/include/linux/errno.h /usr/src/linux/include/linux/string.h \
+ /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/linux/ptrace.h \
+ /usr/src/linux/include/linux/user.h /usr/src/linux/include/asm/segment.h
+fcntl.o : fcntl.c /usr/src/linux/include/asm/segment.h /usr/src/linux/include/linux/sched.h \
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/errno.h /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h \
+ /usr/src/linux/include/linux/string.h
+fifo.o : fifo.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/mm.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/errno.h /usr/src/linux/include/linux/fcntl.h
+file_table.o : file_table.c /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/string.h
+inode.o : inode.c /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/sched.h \
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/string.h /usr/src/linux/include/asm/system.h
+ioctl.o : ioctl.c /usr/src/linux/include/asm/segment.h /usr/src/linux/include/linux/sched.h \
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/errno.h /usr/src/linux/include/linux/string.h /usr/src/linux/include/linux/stat.h
+namei.o : namei.c /usr/src/linux/include/const.h /usr/src/linux/include/asm/segment.h \
+ /usr/src/linux/include/linux/errno.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/mm.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/string.h /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/linux/stat.h
+open.o : open.c /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/types.h \
+ /usr/src/linux/include/linux/utime.h /usr/src/linux/include/linux/errno.h /usr/src/linux/include/linux/fcntl.h \
+ /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/string.h /usr/src/linux/include/linux/sched.h \
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
/usr/src/linux/include/asm/segment.h
-pipe.o : pipe.c /usr/src/linux/include/signal.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/errno.h /usr/src/linux/include/termios.h \
- /usr/src/linux/include/asm/segment.h /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \
- /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
- /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h
-read_write.o : read_write.c /usr/src/linux/include/errno.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
+pipe.o : pipe.c /usr/src/linux/include/asm/segment.h /usr/src/linux/include/linux/sched.h \
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/errno.h /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/linux/termios.h
+read_write.o : read_write.c /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/errno.h \
/usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/vfs.h \
- /usr/src/linux/include/linux/mm.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \
- /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \
- /usr/src/linux/include/linux/minix_fs.h /usr/src/linux/include/asm/segment.h
-select.o : select.c /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/tty.h \
- /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/signal.h \
- /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
- /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/string.h \
- /usr/src/linux/include/linux/stat.h /usr/src/linux/include/asm/segment.h /usr/src/linux/include/const.h \
- /usr/src/linux/include/errno.h
-stat.o : stat.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/stat.h \
- /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
- /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
- /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/mm.h \
- /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \
- /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/mm.h \
+ /usr/src/linux/include/linux/signal.h /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h \
+ /usr/src/linux/include/linux/resource.h /usr/src/linux/include/linux/minix_fs.h \
/usr/src/linux/include/asm/segment.h
+select.o : select.c /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/time.h \
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/signal.h /usr/src/linux/include/linux/param.h \
+ /usr/src/linux/include/linux/resource.h /usr/src/linux/include/linux/string.h \
+ /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/errno.h /usr/src/linux/include/asm/segment.h \
+ /usr/src/linux/include/asm/system.h /usr/src/linux/include/const.h
+stat.o : stat.c /usr/src/linux/include/linux/errno.h /usr/src/linux/include/linux/stat.h \
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/sched.h \
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
+ /usr/src/linux/include/linux/signal.h /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h \
+ /usr/src/linux/include/linux/resource.h /usr/src/linux/include/asm/segment.h
super.o : super.c /usr/src/linux/include/linux/config.h /usr/src/linux/include/linux/config_rel.h \
/usr/src/linux/include/linux/config_ver.h /usr/src/linux/include/linux/config.dist.h \
/usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
- /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h \
- /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
- /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \
- /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \
+ /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h \
+ /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
/usr/src/linux/include/linux/minix_fs.h /usr/src/linux/include/linux/ext_fs.h \
- /usr/src/linux/include/linux/stat.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/segment.h \
- /usr/src/linux/include/errno.h
+ /usr/src/linux/include/linux/msdos_fs.h /usr/src/linux/include/linux/stat.h \
+ /usr/src/linux/include/linux/errno.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/segment.h
diff --git a/fs/block_dev.c b/fs/block_dev.c
index c102c94..8bb0add 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1,11 +1,10 @@
/*
* linux/fs/block_dev.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
-#include <errno.h>
-
+#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <asm/segment.h>
@@ -36,7 +35,7 @@ int block_write(struct inode * inode, struct file * filp, char * buf, int count)
if (chars > count)
chars=count;
if (chars == BLOCK_SIZE)
- bh = getblk(dev,block);
+ bh = getblk(dev, block, BLOCK_SIZE);
else
bh = breada(dev,block,block+1,block+2,-1);
block++;
diff --git a/fs/buffer.c b/fs/buffer.c
index 571c3b5..f8efd1f 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -1,7 +1,7 @@
/*
* linux/fs/buffer.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
@@ -23,15 +23,18 @@
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/kernel.h>
+#include <linux/string.h>
+
#include <asm/system.h>
#include <asm/io.h>
-extern int end;
-static struct buffer_head * start_buffer = (struct buffer_head *) &end;
static struct buffer_head * hash_table[NR_HASH];
-static struct buffer_head * free_list;
+static struct buffer_head * free_list = NULL;
+static struct buffer_head * unused_list = NULL;
static struct wait_queue * buffer_wait = NULL;
-int NR_BUFFERS = 0;
+
+int nr_buffers = 0;
+int nr_buffer_heads = 0;
static inline void wait_on_buffer(struct buffer_head * bh)
{
@@ -47,7 +50,7 @@ static void sync_buffers(int dev)
struct buffer_head * bh;
bh = free_list;
- for (i = NR_BUFFERS*2 ; i-- > 0 ; bh = bh->b_next_free) {
+ for (i = nr_buffers*2 ; i-- > 0 ; bh = bh->b_next_free) {
if (bh->b_lock)
continue;
if (!bh->b_dirt)
@@ -89,8 +92,8 @@ void inline invalidate_buffers(int dev)
int i;
struct buffer_head * bh;
- bh = start_buffer;
- for (i=0 ; i<NR_BUFFERS ; i++,bh++) {
+ bh = free_list;
+ for (i = nr_buffers*2 ; --i > 0 ; bh = bh->b_next_free) {
if (bh->b_dev != dev)
continue;
wait_on_buffer(bh);
@@ -120,7 +123,7 @@ void check_disk_change(int dev)
if (MAJOR(dev) != 2)
return;
- if (!(bh = getblk(dev,0)))
+ if (!(bh = getblk(dev,0,1024)))
return;
i = floppy_change(bh);
brelse(bh);
@@ -211,13 +214,18 @@ static inline void insert_into_queues(struct buffer_head * bh)
bh->b_next->b_prev = bh;
}
-static struct buffer_head * find_buffer(int dev, int block)
+static struct buffer_head * find_buffer(int dev, int block, int size)
{
struct buffer_head * tmp;
for (tmp = hash(dev,block) ; tmp != NULL ; tmp = tmp->b_next)
if (tmp->b_dev==dev && tmp->b_blocknr==block)
- return tmp;
+ if (tmp->b_size == size)
+ return tmp;
+ else {
+ printk("wrong block-size on device %04x\n",dev);
+ return NULL;
+ }
return NULL;
}
@@ -228,16 +236,16 @@ static struct buffer_head * find_buffer(int dev, int block)
* will force it bad). This shouldn't really happen currently, but
* the code is ready.
*/
-struct buffer_head * get_hash_table(int dev, int block)
+struct buffer_head * get_hash_table(int dev, int block, int size)
{
struct buffer_head * bh;
for (;;) {
- if (!(bh=find_buffer(dev,block)))
+ if (!(bh=find_buffer(dev,block,size)))
return NULL;
bh->b_count++;
wait_on_buffer(bh);
- if (bh->b_dev == dev && bh->b_blocknr == block) {
+ if (bh->b_dev == dev && bh->b_blocknr == block && bh->b_size == size) {
put_last_free(bh);
return bh;
}
@@ -256,17 +264,23 @@ struct buffer_head * get_hash_table(int dev, int block)
* when the filesystem starts to get full of dirty blocks (I hope).
*/
#define BADNESS(bh) (((bh)->b_dirt<<1)+(bh)->b_lock)
-struct buffer_head * getblk(int dev,int block)
+struct buffer_head * getblk(int dev, int block, int size)
{
struct buffer_head * bh, * tmp;
int buffers;
repeat:
- if (bh = get_hash_table(dev,block))
+ if (bh = get_hash_table(dev, block, size))
return bh;
- buffers = NR_BUFFERS;
- for (tmp = free_list ; buffers-- > 0 ; tmp = tmp->b_next_free) {
- if (tmp->b_count)
+
+ if (nr_free_pages > 30)
+ grow_buffers(size);
+
+ buffers = nr_buffers;
+ bh = NULL;
+
+ for (tmp = free_list; buffers-- > 0 ; tmp = tmp->b_next_free) {
+ if (tmp->b_count || tmp->b_size != size)
continue;
if (!bh || BADNESS(tmp)<BADNESS(bh)) {
bh = tmp;
@@ -278,13 +292,19 @@ repeat:
ll_rw_block(WRITEA,tmp);
#endif
}
+
+ if (!bh && nr_free_pages > 5) {
+ grow_buffers(size);
+ goto repeat;
+ }
+
/* and repeat until we find something good */
if (!bh) {
sleep_on(&buffer_wait);
goto repeat;
}
wait_on_buffer(bh);
- if (bh->b_count)
+ if (bh->b_count || bh->b_size != size)
goto repeat;
if (bh->b_dirt) {
sync_buffers(bh->b_dev);
@@ -292,7 +312,7 @@ repeat:
}
/* NOTE!! While we slept waiting for this block, somebody else might */
/* already have added "this" block to the cache. check it */
- if (find_buffer(dev,block))
+ if (find_buffer(dev,block,size))
goto repeat;
/* OK, FINALLY we know that this buffer is the only one of it's kind, */
/* and that it's unused (b_count=0), unlocked (b_lock=0), and clean */
@@ -320,12 +340,14 @@ void brelse(struct buffer_head * buf)
* bread() reads a specified block and returns the buffer that contains
* it. It returns NULL if the block was unreadable.
*/
-struct buffer_head * bread(int dev,int block)
+struct buffer_head * bread(int dev, int block, int size)
{
struct buffer_head * bh;
- if (!(bh=getblk(dev,block)))
- panic("bread: getblk returned NULL\n");
+ if (!(bh = getblk(dev, block, size))) {
+ printk("bread: getblk returned NULL\n");
+ return NULL;
+ }
if (bh->b_uptodate)
return bh;
ll_rw_block(READ,bh);
@@ -356,7 +378,7 @@ void bread_page(unsigned long address,int dev,int b[4])
for (i=0 ; i<4 ; i++)
if (b[i]) {
- if (bh[i] = getblk(dev,b[i]))
+ if (bh[i] = getblk(dev, b[i], 1024))
if (!bh[i]->b_uptodate)
ll_rw_block(READ,bh[i]);
} else
@@ -381,12 +403,14 @@ struct buffer_head * breada(int dev,int first, ...)
struct buffer_head * bh, *tmp;
va_start(args,first);
- if (!(bh=getblk(dev,first)))
- panic("bread: getblk returned NULL\n");
+ if (!(bh = getblk(dev, first, 1024))) {
+ printk("breada: getblk returned NULL\n");
+ return NULL;
+ }
if (!bh->b_uptodate)
ll_rw_block(READ,bh);
while ((first=va_arg(args,int))>=0) {
- tmp=getblk(dev,first);
+ tmp = getblk(dev, first, 1024);
if (tmp) {
if (!tmp->b_uptodate)
ll_rw_block(READA,tmp);
@@ -401,42 +425,201 @@ struct buffer_head * breada(int dev,int first, ...)
return (NULL);
}
-void buffer_init(long buffer_end)
+static void put_unused_buffer_head(struct buffer_head * bh)
+{
+ memset((void *) bh,0,sizeof(*bh));
+ bh->b_next_free = unused_list;
+ unused_list = bh;
+}
+
+static void get_more_buffer_heads(void)
{
- struct buffer_head * h = start_buffer;
- void * b;
+ unsigned long page;
+ struct buffer_head * bh;
+
+ if (unused_list)
+ return;
+ page = get_free_page(GFP_KERNEL);
+ if (!page)
+ return;
+ bh = (struct buffer_head *) page;
+ while ((unsigned long) (bh+1) <= page+4096) {
+ put_unused_buffer_head(bh);
+ bh++;
+ nr_buffer_heads++;
+ }
+}
+
+static struct buffer_head * get_unused_buffer_head(void)
+{
+ struct buffer_head * bh;
+
+ get_more_buffer_heads();
+ if (!unused_list)
+ return NULL;
+ bh = unused_list;
+ unused_list = bh->b_next_free;
+ bh->b_next_free = NULL;
+ bh->b_data = NULL;
+ bh->b_size = 0;
+ return bh;
+}
+
+/*
+ * Try to increase the number of buffers available: the size argument
+ * is used to determine what kind of buffers we want. Currently only
+ * 1024-byte buffers are supported by the rest of the system, but I
+ * think this will change eventually.
+ */
+void grow_buffers(int size)
+{
+ unsigned long page;
int i;
+ struct buffer_head *bh, *tmp;
- if (buffer_end == 1<<20)
- b = (void *) (640*1024);
- else
- b = (void *) buffer_end;
- while ( (b -= BLOCK_SIZE) >= ((void *) (h+1)) ) {
- if (((unsigned long) (h+1)) > 0xA0000) {
- printk("buffer-list doesn't fit in low meg - contact Linus\n");
+ if ((size & 511) || (size > 4096)) {
+ printk("grow_buffers: size = %d\n",size);
+ return;
+ }
+ page = get_free_page(GFP_BUFFER);
+ if (!page)
+ return;
+ tmp = NULL;
+ i = 0;
+ for (i = 0 ; i+size <= 4096 ; i += size) {
+ bh = get_unused_buffer_head();
+ if (!bh)
+ goto no_grow;
+ bh->b_this_page = tmp;
+ tmp = bh;
+ bh->b_data = (char * ) (page+i);
+ bh->b_size = size;
+ i += size;
+ }
+ tmp = bh;
+ while (1) {
+ tmp->b_next_free = free_list;
+ tmp->b_prev_free = free_list->b_prev_free;
+ free_list->b_prev_free->b_next_free = tmp;
+ free_list->b_prev_free = tmp;
+ free_list = tmp;
+ ++nr_buffers;
+ if (tmp->b_this_page)
+ tmp = tmp->b_this_page;
+ else
break;
+ }
+ tmp->b_this_page = bh;
+ return;
+/*
+ * In case anything failed, we just free everything we got.
+ */
+no_grow:
+ bh = tmp;
+ while (bh) {
+ tmp = bh;
+ bh = bh->b_this_page;
+ put_unused_buffer_head(tmp);
+ }
+ free_page(page);
+}
+
+/*
+ * try_to_free() checks if all the buffers on this particular page
+ * are unused, and free's the page if so.
+ */
+static int try_to_free(struct buffer_head * bh)
+{
+ unsigned long page;
+ struct buffer_head * tmp, * p;
+
+ tmp = bh;
+ do {
+ if (!tmp)
+ return 0;
+ if (tmp->b_count || tmp->b_dirt || tmp->b_lock)
+ return 0;
+ tmp = tmp->b_this_page;
+ } while (tmp != bh);
+ page = (unsigned long) bh->b_data;
+ page &= 0xfffff000;
+ tmp = bh;
+ do {
+ p = tmp;
+ tmp = tmp->b_this_page;
+ nr_buffers--;
+ remove_from_queues(p);
+ put_unused_buffer_head(p);
+ } while (tmp != bh);
+ free_page(page);
+ return 1;
+}
+
+/*
+ * Try to free up some pages by shrinking the buffer-cache
+ */
+int shrink_buffers(void)
+{
+ struct buffer_head *bh;
+ int i;
+
+ bh = free_list;
+ for (i = nr_buffers*2 ; i-- > 0 ; bh = bh->b_next_free) {
+ wait_on_buffer(bh);
+ if (bh->b_count || !bh->b_this_page)
+ continue;
+ if (bh->b_dirt) {
+ ll_rw_block(WRITEA,bh);
+ continue;
}
- h->b_dev = 0;
- h->b_dirt = 0;
- h->b_count = 0;
- h->b_lock = 0;
- h->b_uptodate = 0;
- h->b_wait = NULL;
- h->b_next = NULL;
- h->b_prev = NULL;
- h->b_data = (char *) b;
- h->b_reqnext = NULL;
- h->b_prev_free = h-1;
- h->b_next_free = h+1;
- h++;
- NR_BUFFERS++;
- if (b == (void *) 0x100000)
- b = (void *) 0xA0000;
+ if (try_to_free(bh))
+ return 1;
}
- h--;
- free_list = start_buffer;
- free_list->b_prev_free = h;
- h->b_next_free = free_list;
- for (i=0;i<NR_HASH;i++)
+ return 0;
+}
+
+/*
+ * This initializes the low 1M that isn't used by the kernel to buffer
+ * cache. It should really be used for paging memory, but it takes a lot
+ * of special-casing, which I don't want to do.
+ *
+ * The biggest problem with this approach is that all low-mem buffers
+ * have a fixed size of 1024 chars: not good if/when the other sizes
+ * are implemented.
+ */
+void buffer_init(void)
+{
+ struct buffer_head * bh;
+ extern int end;
+ unsigned long mem;
+ int i;
+
+ for (i = 0 ; i < NR_HASH ; i++)
hash_table[i] = NULL;
-}
+ mem = (unsigned long) & end;
+ mem += BLOCK_SIZE-1;
+ mem &= ~(BLOCK_SIZE-1);
+ free_list = get_unused_buffer_head();
+ if (!free_list)
+ panic("unable to get a single buffer-head");
+ free_list->b_prev_free = free_list;
+ free_list->b_next_free = free_list;
+ free_list->b_data = (char *) mem;
+ free_list->b_size = BLOCK_SIZE;
+ mem += BLOCK_SIZE;
+ while (mem + 1024 < 0xA0000) {
+ bh = get_unused_buffer_head();
+ if (!bh)
+ break;
+ bh->b_data = (char *) mem;
+ bh->b_size = BLOCK_SIZE;
+ mem += BLOCK_SIZE;
+ bh->b_next_free = free_list;
+ bh->b_prev_free = free_list->b_prev_free;
+ free_list->b_prev_free->b_next_free = bh;
+ free_list->b_prev_free = bh;
+ free_list = bh;
+ ++nr_buffers;
+ }
+ return;
+}
diff --git a/fs/exec.c b/fs/exec.c
index 8a5b0af..2be1aa3 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1,7 +1,7 @@
/*
* linux/fs/exec.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
@@ -17,20 +17,20 @@
* was less than 2 hours work to get demand-loading completely implemented.
*/
-#include <signal.h>
-#include <errno.h>
-#include <sys/ptrace.h>
-#include <a.out.h>
-
-#include <linux/string.h>
-#include <linux/stat.h>
-#include <linux/fcntl.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
+#include <linux/a.out.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/string.h>
+#include <linux/stat.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+
#include <asm/segment.h>
-#include <sys/user.h>
extern int sys_exit(int exit_code);
extern int sys_close(int fd);
@@ -169,8 +169,6 @@ int sys_uselib(const char * library)
struct inode * inode;
struct buffer_head * bh;
struct exec ex;
- int i;
- struct file * f;
if (get_limit(0x17) != TASK_SIZE)
return -EINVAL;
@@ -182,23 +180,18 @@ int sys_uselib(const char * library)
inode = NULL;
if (!inode)
return -ENOENT;
- if (!S_ISREG(inode->i_mode) || !permission(inode,MAY_READ)) {
+ if (!inode->i_sb || !S_ISREG(inode->i_mode) || !permission(inode,MAY_READ)) {
iput(inode);
return -EACCES;
}
- if (inode->i_count > 1) { /* check for writers */
- f=0+file_table;
- for (i=0 ; i<NR_FILE ; i++,f++ )
- if (f->f_count && (f->f_mode & 2))
- if (inode == f->f_inode) {
- iput(inode);
- return -ETXTBSY;
- }
- }
- if (!(bh = bread(inode->i_dev,bmap(inode,0)))) {
+ if (!(bh = bread(inode->i_dev,bmap(inode,0),inode->i_sb->s_blocksize))) {
iput(inode);
return -EACCES;
}
+ if (!IS_RDONLY(inode)) {
+ inode->i_atime = CURRENT_TIME;
+ inode->i_dirt = 1;
+ }
ex = *(struct exec *) bh->b_data;
brelse(bh);
if (N_MAGIC(ex) != ZMAGIC || ex.a_trsize || ex.a_drsize ||
@@ -320,7 +313,7 @@ static unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
set_fs(old_fs);
if (!(pag = (char *) page[p/PAGE_SIZE]) &&
!(pag = (char *) page[p/PAGE_SIZE] =
- (unsigned long *) get_free_page()))
+ (unsigned long *) get_free_page(GFP_USER)))
return 0;
if (from_kmem==2)
set_fs(new_fs);
@@ -363,13 +356,17 @@ static void read_omagic(struct inode *inode, int bytes)
struct buffer_head *bh;
int n, blkno, blk = 0;
char *dest = (char *) 0;
+ unsigned int block_size;
+ block_size = 1024;
+ if (inode->i_sb)
+ block_size = inode->i_sb->s_blocksize;
while (bytes > 0) {
if (!(blkno = bmap(inode, blk)))
sys_exit(-1);
- if (!(bh = bread(inode->i_dev, blkno)))
+ if (!(bh = bread(inode->i_dev, blkno, block_size)))
sys_exit(-1);
- n = (blk ? BLOCK_SIZE : BLOCK_SIZE - sizeof(struct exec));
+ n = (blk ? block_size : block_size - sizeof(struct exec));
if (bytes < n)
n = bytes;
@@ -403,7 +400,6 @@ int do_execve(unsigned long * eip,long tmp,char * filename,
int sh_bang = 0;
unsigned long p=PAGE_SIZE*MAX_ARG_PAGES-4;
int ch;
- struct file * f;
if ((0xffff & eip[1]) != 0x000f)
panic("execve called from supervisor mode");
@@ -411,15 +407,6 @@ int do_execve(unsigned long * eip,long tmp,char * filename,
page[i]=0;
if (!(inode=namei(filename))) /* get executables inode */
return -ENOENT;
- if (inode->i_count > 1) { /* check for writers */
- f=0+file_table;
- for (i=0 ; i<NR_FILE ; i++,f++ )
- if (f->f_count && (f->f_mode & 2))
- if (inode == f->f_inode) {
- retval = -ETXTBSY;
- goto exec_error2;
- }
- }
argc = count(argv);
envc = count(envp);
@@ -432,6 +419,10 @@ restart_interp:
retval = -EPERM;
goto exec_error2;
}
+ if (!inode->i_sb) {
+ retval = -EACCES;
+ goto exec_error2;
+ }
i = inode->i_mode;
if (IS_NOSUID(inode) && (((i & S_ISUID) && inode->i_uid != current->
euid) || ((i & S_ISGID) && inode->i_gid != current->egid)) &&
@@ -456,10 +447,14 @@ restart_interp:
retval = -EACCES;
goto exec_error2;
}
- if (!(bh = bread(inode->i_dev,bmap(inode,0)))) {
+ if (!(bh = bread(inode->i_dev,bmap(inode,0),inode->i_sb->s_blocksize))) {
retval = -EACCES;
goto exec_error2;
}
+ if (!IS_RDONLY(inode)) {
+ inode->i_atime = CURRENT_TIME;
+ inode->i_dirt = 1;
+ }
ex = *((struct exec *) bh->b_data); /* read exec-header */
if ((bh->b_data[0] == '#') && (bh->b_data[1] == '!') && (!sh_bang)) {
/*
diff --git a/fs/ext/Makefile b/fs/ext/Makefile
index d498dda..43fc4e1 100644
--- a/fs/ext/Makefile
+++ b/fs/ext/Makefile
@@ -30,79 +30,99 @@ dep:
cp tmp_make Makefile
### Dependencies:
-bitmap.o : bitmap.c /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
- /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
- /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ext_fs.h
+bitmap.o : bitmap.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/mm.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/ext_fs.h /usr/src/linux/include/linux/string.h
blkdev.o : blkdev.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
- /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
- /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
- /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
- /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
- /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ext_fs.h \
- /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h \
- /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/errno.h
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/mm.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/ext_fs.h /usr/src/linux/include/linux/tty.h /usr/src/linux/include/linux/termios.h \
+ /usr/src/linux/include/asm/system.h /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h \
+ /usr/src/linux/include/linux/errno.h
chrdev.o : chrdev.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
- /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
- /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
- /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
- /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
- /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ext_fs.h \
- /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h \
- /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/errno.h
-dir.o : dir.c /usr/src/linux/include/errno.h /usr/src/linux/include/asm/segment.h \
- /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
- /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
- /usr/src/linux/include/linux/ext_fs.h /usr/src/linux/include/linux/stat.h
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/mm.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/ext_fs.h /usr/src/linux/include/linux/tty.h /usr/src/linux/include/linux/termios.h \
+ /usr/src/linux/include/asm/system.h /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h \
+ /usr/src/linux/include/linux/errno.h
+dir.o : dir.c /usr/src/linux/include/asm/segment.h /usr/src/linux/include/linux/errno.h \
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/ext_fs.h \
+ /usr/src/linux/include/linux/stat.h
fifo.o : fifo.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
- /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
- /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
- /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
- /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
- /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ext_fs.h
-file.o : file.c /usr/src/linux/include/errno.h /usr/src/linux/include/sys/dirent.h \
- /usr/src/linux/include/limits.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
- /usr/src/linux/include/asm/segment.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/linux/fcntl.h \
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/mm.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/ext_fs.h
+file.o : file.c /usr/src/linux/include/asm/segment.h /usr/src/linux/include/asm/system.h \
/usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
- /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ext_fs.h \
+ /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h \
+ /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/ext_fs.h /usr/src/linux/include/linux/errno.h /usr/src/linux/include/linux/fcntl.h \
/usr/src/linux/include/linux/stat.h
-freelists.o : freelists.c /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
- /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
- /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ext_fs.h
-inode.o : inode.c /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \
- /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
- /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \
- /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \
- /usr/src/linux/include/linux/ext_fs.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/segment.h
+freelists.o : freelists.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/mm.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/ext_fs.h /usr/src/linux/include/linux/string.h
+inode.o : inode.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/mm.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/ext_fs.h /usr/src/linux/include/linux/string.h \
+ /usr/src/linux/include/linux/stat.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/segment.h
namei.o : namei.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
- /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
- /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
- /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
- /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
- /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ext_fs.h \
- /usr/src/linux/include/linux/string.h /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h \
- /usr/src/linux/include/asm/segment.h /usr/src/linux/include/errno.h /usr/src/linux/include/const.h
-symlink.o : symlink.c /usr/src/linux/include/errno.h /usr/src/linux/include/asm/segment.h \
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/mm.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/ext_fs.h /usr/src/linux/include/linux/string.h \
+ /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/linux/errno.h \
+ /usr/src/linux/include/asm/segment.h /usr/src/linux/include/const.h
+symlink.o : symlink.c /usr/src/linux/include/asm/segment.h /usr/src/linux/include/linux/errno.h \
/usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
- /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h \
- /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
- /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \
- /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \
+ /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h \
+ /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
/usr/src/linux/include/linux/ext_fs.h /usr/src/linux/include/linux/stat.h
truncate.o : truncate.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
- /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
- /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
- /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
- /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
- /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ext_fs.h \
- /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h \
- /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/errno.h
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/mm.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/ext_fs.h /usr/src/linux/include/linux/tty.h /usr/src/linux/include/linux/termios.h \
+ /usr/src/linux/include/asm/system.h /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h \
+ /usr/src/linux/include/linux/errno.h
diff --git a/fs/ext/bitmap.c b/fs/ext/bitmap.c
index f5bad9f..ee68e68 100644
--- a/fs/ext/bitmap.c
+++ b/fs/ext/bitmap.c
@@ -1,22 +1,22 @@
/*
* linux/fs/ext/bitmap.c
*
- * (C) 1992 Remy Card (card@masi.ibp.fr)
+ * Copyright (C) 1992 Remy Card (card@masi.ibp.fr)
*
* from
*
* linux/fs/minix/bitmap.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
/* bitmap.c contains the code that handles the inode and block bitmaps */
-#include <linux/string.h>
#include <linux/sched.h>
#include <linux/ext_fs.h>
#include <linux/kernel.h>
+#include <linux/string.h>
#ifdef EXTFS_BITMAP
diff --git a/fs/ext/blkdev.c b/fs/ext/blkdev.c
index 9931276..74dd9fe 100644
--- a/fs/ext/blkdev.c
+++ b/fs/ext/blkdev.c
@@ -1,13 +1,13 @@
/*
* linux/fs/ext/blkdev.c
*
- * (C) 1992 Remy Card (card@masi.ibp.fr)
+ * Copyright (C) 1992 Remy Card (card@masi.ibp.fr)
*
* from
*
* linux/fs/minix/blkdev.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
#include <linux/sched.h>
@@ -15,8 +15,7 @@
#include <linux/tty.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
-
-#include <errno.h>
+#include <linux/errno.h>
/*
* Called every time an ext block special file is opened
diff --git a/fs/ext/chrdev.c b/fs/ext/chrdev.c
index 537972e..b1b55ea 100644
--- a/fs/ext/chrdev.c
+++ b/fs/ext/chrdev.c
@@ -1,13 +1,13 @@
/*
* linux/fs/ext/chrdev.c
*
- * (C) 1992 Remy Card (card@masi.ibp.fr)
+ * Copyright (C) 1992 Remy Card (card@masi.ibp.fr)
*
* from
*
* linux/fs/minix/chrdev.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
#include <linux/sched.h>
@@ -15,8 +15,7 @@
#include <linux/tty.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
-
-#include <errno.h>
+#include <linux/errno.h>
/*
* Called every time an ext character special file is opened
diff --git a/fs/ext/dir.c b/fs/ext/dir.c
index 730d5a1..54bc7ad 100644
--- a/fs/ext/dir.c
+++ b/fs/ext/dir.c
@@ -1,21 +1,20 @@
/*
* linux/fs/ext/dir.c
*
- * (C) 1992 Remy Card (card@masi.ibp.fr)
+ * Copyright (C) 1992 Remy Card (card@masi.ibp.fr)
*
* from
*
* linux/fs/minix/dir.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*
* ext directory handling functions
*/
-#include <errno.h>
-
#include <asm/segment.h>
+#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/ext_fs.h>
#include <linux/stat.h>
@@ -68,7 +67,7 @@ static int ext_readdir(struct inode * inode, struct file * filp,
while (filp->f_pos < inode->i_size) {
offset = filp->f_pos & 1023;
block = ext_bmap(inode,(filp->f_pos)>>BLOCK_SIZE_BITS);
- if (!block || !(bh = bread(inode->i_dev,block))) {
+ if (!block || !(bh = bread(inode->i_dev, block, BLOCK_SIZE))) {
filp->f_pos += 1024-offset;
continue;
}
diff --git a/fs/ext/file.c b/fs/ext/file.c
index 3fe77d3..ec366aa 100644
--- a/fs/ext/file.c
+++ b/fs/ext/file.c
@@ -1,28 +1,25 @@
/*
* linux/fs/ext/file.c
*
- * (C) 1992 Remy Card (card@masi.ibp.fr)
+ * Copyright (C) 1992 Remy Card (card@masi.ibp.fr)
*
* from
*
* linux/fs/minix/file.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*
* ext regular file handling primitives
*/
-#include <errno.h>
-
-#include <sys/dirent.h>
-
#include <asm/segment.h>
#include <asm/system.h>
-#include <linux/fcntl.h>
#include <linux/sched.h>
#include <linux/ext_fs.h>
#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/fcntl.h>
#include <linux/stat.h>
#define NBUF 16
@@ -108,7 +105,7 @@ static int ext_file_read(struct inode * inode, struct file * filp, char * buf, i
if (blocks) {
--blocks;
if (nr = ext_bmap(inode,block++)) {
- *bhb = getblk(inode->i_dev,nr);
+ *bhb = getblk(inode->i_dev, nr, BLOCK_SIZE);
if (!(*bhb)->b_uptodate)
ll_rw_block(READ,*bhb);
} else
@@ -194,9 +191,9 @@ 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 = getblk(inode->i_dev, block);
+ bh = getblk(inode->i_dev, block, BLOCK_SIZE);
else
- bh = bread(inode->i_dev,block);
+ bh = bread(inode->i_dev, block, BLOCK_SIZE);
if (!bh) {
if (!written)
written = -EIO;
diff --git a/fs/ext/freelists.c b/fs/ext/freelists.c
index 118fe09..e39f442 100644
--- a/fs/ext/freelists.c
+++ b/fs/ext/freelists.c
@@ -1,7 +1,7 @@
/*
* linux/fs/ext/freelists.c
*
- * (C) 1992 Remy Card (card@masi.ibp.fr)
+ * Copyright (C) 1992 Remy Card (card@masi.ibp.fr)
*
*/
@@ -15,7 +15,7 @@
free blocks and the number of the next block in the list.
When an ext fs is mounted, the number of the first free block is stored
- in s->s_zmap[0] and the block header is stored in s->s_zmap[1]. s_zmap[2]
+ in s->u.ext_sb.s_zmap[0] and the block header is stored in s->u.ext_sb.s_zmap[1]. u.ext_sb.s_zmap[2]
contains the count of free blocks.
Currently, it is a hack to allow this kind of management with the super_block
@@ -27,17 +27,16 @@
super block contains the number of the first free inode. This inode contains
14 numbers of other free inodes and the number of the next inode in the list.
- The number of the first free inode is stored in s->s_imap[0] and the header
- of the block containing the inode is stored in s->s_imap[1]. s_imap[2] contains
+ The number of the first free inode is stored in s->u.ext_sb.s_imap[0] and the header
+ of the block containing the inode is stored in s->u.ext_sb.s_imap[1]. u.ext_sb.s_imap[2] contains
the count of free inodes.
*/
-#include <linux/string.h>
-
#include <linux/sched.h>
#include <linux/ext_fs.h>
#include <linux/kernel.h>
+#include <linux/string.h>
#ifdef EXTFS_FREELIST
@@ -56,9 +55,9 @@ int ext_free_block(int dev, int block)
if (!(sb = get_super(dev)))
panic("trying to free block on nonexistent device");
lock_super (sb);
- if (block < sb->s_firstdatazone || block >= sb->s_nzones)
+ if (block < sb->u.ext_sb.s_firstdatazone || block >= sb->u.ext_sb.s_nzones)
panic("trying to free block not in datazone");
- bh = get_hash_table(dev,block);
+ bh = get_hash_table(dev, block, sb->s_blocksize);
if (bh) {
if (bh->b_count > 1) {
brelse(bh);
@@ -70,26 +69,26 @@ int ext_free_block(int dev, int block)
if (bh->b_count)
brelse(bh);
}
- if (sb->s_zmap[1])
- efb = (struct ext_free_block *) sb->s_zmap[1]->b_data;
- if (!sb->s_zmap[1] || efb->count == 254) {
+ if (sb->u.ext_sb.s_zmap[1])
+ efb = (struct ext_free_block *) sb->u.ext_sb.s_zmap[1]->b_data;
+ if (!sb->u.ext_sb.s_zmap[1] || efb->count == 254) {
#ifdef EXTFS_DEBUG
printk("ext_free_block: block full, skipping to %d\n", block);
#endif
- if (sb->s_zmap[1])
- brelse (sb->s_zmap[1]);
- if (!(sb->s_zmap[1] = bread (dev, block)))
+ if (sb->u.ext_sb.s_zmap[1])
+ brelse (sb->u.ext_sb.s_zmap[1]);
+ if (!(sb->u.ext_sb.s_zmap[1] = bread (dev, block, sb->s_blocksize)))
panic ("ext_free_block: unable to read block to free\n");
- efb = (struct ext_free_block *) sb->s_zmap[1]->b_data;
- efb->next = (unsigned long) sb->s_zmap[0];
+ efb = (struct ext_free_block *) sb->u.ext_sb.s_zmap[1]->b_data;
+ efb->next = (unsigned long) sb->u.ext_sb.s_zmap[0];
efb->count = 0;
- sb->s_zmap[0] = (struct buffer_head *) block;
+ sb->u.ext_sb.s_zmap[0] = (struct buffer_head *) block;
} else {
efb->free[efb->count++] = block;
}
- sb->s_zmap[2] = (struct buffer_head *) (((unsigned long) sb->s_zmap[2]) + 1);
+ sb->u.ext_sb.s_zmap[2] = (struct buffer_head *) (((unsigned long) sb->u.ext_sb.s_zmap[2]) + 1);
sb->s_dirt = 1;
- sb->s_zmap[1]->b_dirt = 1;
+ sb->u.ext_sb.s_zmap[1]->b_dirt = 1;
free_super (sb);
return 1;
}
@@ -103,35 +102,35 @@ int ext_new_block(int dev)
if (!(sb = get_super(dev)))
panic("trying to get new block from nonexistant device");
- if (!sb->s_zmap[1])
+ if (!sb->u.ext_sb.s_zmap[1])
return 0;
lock_super (sb);
- efb = (struct ext_free_block *) sb->s_zmap[1]->b_data;
+ efb = (struct ext_free_block *) sb->u.ext_sb.s_zmap[1]->b_data;
if (efb->count) {
j = efb->free[--efb->count];
- sb->s_zmap[1]->b_dirt = 1;
+ sb->u.ext_sb.s_zmap[1]->b_dirt = 1;
} else {
#ifdef EXTFS_DEBUG
printk("ext_new_block: block empty, skipping to %d\n", efb->next);
#endif
- j = (unsigned long) sb->s_zmap[0];
- sb->s_zmap[0] = (struct buffer_head *) efb->next;
- brelse (sb->s_zmap[1]);
- if (!sb->s_zmap[0]) {
- sb->s_zmap[1] = NULL;
+ j = (unsigned long) sb->u.ext_sb.s_zmap[0];
+ sb->u.ext_sb.s_zmap[0] = (struct buffer_head *) efb->next;
+ brelse (sb->u.ext_sb.s_zmap[1]);
+ if (!sb->u.ext_sb.s_zmap[0]) {
+ sb->u.ext_sb.s_zmap[1] = NULL;
} else {
- if (!(sb->s_zmap[1] = bread (dev, (unsigned long) sb->s_zmap[0])))
+ if (!(sb->u.ext_sb.s_zmap[1] = bread (dev, (unsigned long) sb->u.ext_sb.s_zmap[0], sb->s_blocksize)))
panic ("ext_new_block: unable to read next free block\n");
}
}
- if (j < sb->s_firstdatazone || j > sb->s_nzones) {
+ if (j < sb->u.ext_sb.s_firstdatazone || j > sb->u.ext_sb.s_nzones) {
printk ("ext_new_block: blk = %d\n", j);
panic ("allocating block not in data zone\n");
}
- sb->s_zmap[2] = (struct buffer_head *) (((unsigned long) sb->s_zmap[2]) - 1);
+ sb->u.ext_sb.s_zmap[2] = (struct buffer_head *) (((unsigned long) sb->u.ext_sb.s_zmap[2]) - 1);
sb->s_dirt = 1;
- if (!(bh=getblk(dev,j)))
+ if (!(bh=getblk(dev, j, sb->s_blocksize)))
panic("new_block: cannot get block");
if (bh->b_count != 1)
panic("new block: count is != 1");
@@ -154,14 +153,14 @@ unsigned long ext_count_free_blocks(struct super_block *sb)
unsigned long count, block;
lock_super (sb);
- if (!sb->s_zmap[1])
+ if (!sb->u.ext_sb.s_zmap[1])
count = 0;
else {
- efb = (struct ext_free_block *) sb->s_zmap[1]->b_data;
+ efb = (struct ext_free_block *) sb->u.ext_sb.s_zmap[1]->b_data;
count = efb->count + 1;
block = efb->next;
while (block) {
- if (!(bh = bread (sb->s_dev, block))) {
+ if (!(bh = bread (sb->s_dev, block, sb->s_blocksize))) {
printk ("ext_count_free: error while reading free blocks list\n");
block = 0;
} else {
@@ -173,11 +172,11 @@ unsigned long ext_count_free_blocks(struct super_block *sb)
}
}
printk("ext_count_free_blocks: stored = %d, computed = %d\n",
- (unsigned long) sb->s_zmap[2], count);
+ (unsigned long) sb->u.ext_sb.s_zmap[2], count);
free_super (sb);
return count;
#else
- return (unsigned long) sb->s_zmap[2];
+ return (unsigned long) sb->u.ext_sb.s_zmap[2];
#endif
}
@@ -206,35 +205,35 @@ void ext_free_inode(struct inode * inode)
return;
}
lock_super (inode->i_sb);
- if (inode->i_ino < 1 || inode->i_ino > inode->i_sb->s_ninodes) {
+ if (inode->i_ino < 1 || inode->i_ino > inode->i_sb->u.ext_sb.s_ninodes) {
printk("free_inode: inode 0 or nonexistent inode\n");
free_super (inode->i_sb);
return;
}
- if (inode->i_sb->s_imap[1])
- efi = ((struct ext_free_inode *) inode->i_sb->s_imap[1]->b_data) +
- (((unsigned long) inode->i_sb->s_imap[0])-1)%EXT_INODES_PER_BLOCK;
- if (!inode->i_sb->s_imap[1] || efi->count == 14) {
+ if (inode->i_sb->u.ext_sb.s_imap[1])
+ efi = ((struct ext_free_inode *) inode->i_sb->u.ext_sb.s_imap[1]->b_data) +
+ (((unsigned long) inode->i_sb->u.ext_sb.s_imap[0])-1)%EXT_INODES_PER_BLOCK;
+ if (!inode->i_sb->u.ext_sb.s_imap[1] || efi->count == 14) {
#ifdef EXTFS_DEBUG
printk("ext_free_inode: inode full, skipping to %d\n", inode->i_ino);
#endif
- if (inode->i_sb->s_imap[1])
- brelse (inode->i_sb->s_imap[1]);
+ if (inode->i_sb->u.ext_sb.s_imap[1])
+ brelse (inode->i_sb->u.ext_sb.s_imap[1]);
block = 2 + (inode->i_ino - 1) / EXT_INODES_PER_BLOCK;
- if (!(bh = bread(inode->i_dev, block)))
+ if (!(bh = bread(inode->i_dev, block, inode->i_sb->s_blocksize)))
panic("ext_free_inode: unable to read inode block\n");
efi = ((struct ext_free_inode *) bh->b_data) +
(inode->i_ino - 1) % EXT_INODES_PER_BLOCK;
- efi->next = (unsigned long) inode->i_sb->s_imap[0];
+ efi->next = (unsigned long) inode->i_sb->u.ext_sb.s_imap[0];
efi->count = 0;
- inode->i_sb->s_imap[0] = (struct buffer_head *) inode->i_ino;
- inode->i_sb->s_imap[1] = bh;
+ inode->i_sb->u.ext_sb.s_imap[0] = (struct buffer_head *) inode->i_ino;
+ inode->i_sb->u.ext_sb.s_imap[1] = bh;
} else {
efi->free[efi->count++] = inode->i_ino;
}
- inode->i_sb->s_imap[2] = (struct buffer_head *) (((unsigned long) inode->i_sb->s_imap[2]) + 1);
+ inode->i_sb->u.ext_sb.s_imap[2] = (struct buffer_head *) (((unsigned long) inode->i_sb->u.ext_sb.s_imap[2]) + 1);
inode->i_sb->s_dirt = 1;
- inode->i_sb->s_imap[1]->b_dirt = 1;
+ inode->i_sb->u.ext_sb.s_imap[1]->b_dirt = 1;
free_super (inode->i_sb);
memset(inode,0,sizeof(*inode));
}
@@ -254,34 +253,34 @@ struct inode * ext_new_inode(int dev)
return NULL;
}
inode->i_flags = inode->i_sb->s_flags;
- if (!inode->i_sb->s_imap[1])
+ if (!inode->i_sb->u.ext_sb.s_imap[1])
return 0;
lock_super (inode->i_sb);
- efi = ((struct ext_free_inode *) inode->i_sb->s_imap[1]->b_data) +
- (((unsigned long) inode->i_sb->s_imap[0])-1)%EXT_INODES_PER_BLOCK;
+ efi = ((struct ext_free_inode *) inode->i_sb->u.ext_sb.s_imap[1]->b_data) +
+ (((unsigned long) inode->i_sb->u.ext_sb.s_imap[0])-1)%EXT_INODES_PER_BLOCK;
if (efi->count) {
j = efi->free[--efi->count];
- inode->i_sb->s_imap[1]->b_dirt = 1;
+ inode->i_sb->u.ext_sb.s_imap[1]->b_dirt = 1;
} else {
#ifdef EXTFS_DEBUG
printk("ext_free_inode: inode empty, skipping to %d\n", efi->next);
#endif
- j = (unsigned long) inode->i_sb->s_imap[0];
- if (efi->next < 1 || efi->next > inode->i_sb->s_ninodes) {
+ j = (unsigned long) inode->i_sb->u.ext_sb.s_imap[0];
+ if (efi->next > inode->i_sb->u.ext_sb.s_ninodes) {
printk ("efi->next = %d\n", efi->next);
panic ("ext_new_inode: bad inode number in free list\n");
}
- inode->i_sb->s_imap[0] = (struct buffer_head *) efi->next;
+ inode->i_sb->u.ext_sb.s_imap[0] = (struct buffer_head *) efi->next;
block = 2 + (((unsigned long) efi->next) - 1) / EXT_INODES_PER_BLOCK;
- brelse (inode->i_sb->s_imap[1]);
- if (!inode->i_sb->s_imap[0]) {
- inode->i_sb->s_imap[1] = NULL;
+ brelse (inode->i_sb->u.ext_sb.s_imap[1]);
+ if (!inode->i_sb->u.ext_sb.s_imap[0]) {
+ inode->i_sb->u.ext_sb.s_imap[1] = NULL;
} else {
- if (!(inode->i_sb->s_imap[1] = bread (dev, block)))
+ if (!(inode->i_sb->u.ext_sb.s_imap[1] = bread (dev, block, inode->i_sb->s_blocksize)))
panic ("ext_new_inode: unable to read next free inode block\n");
}
}
- inode->i_sb->s_imap[2] = (struct buffer_head *) (((unsigned long) inode->i_sb->s_imap[2]) - 1);
+ inode->i_sb->u.ext_sb.s_imap[2] = (struct buffer_head *) (((unsigned long) inode->i_sb->u.ext_sb.s_imap[2]) - 1);
inode->i_sb->s_dirt = 1;
inode->i_count = 1;
inode->i_nlink = 1;
@@ -307,21 +306,21 @@ unsigned long ext_count_free_inodes(struct super_block *sb)
unsigned long count, block, ino;
lock_super (sb);
- if (!sb->s_imap[1])
+ if (!sb->u.ext_sb.s_imap[1])
count = 0;
else {
- efi = ((struct ext_free_inode *) sb->s_imap[1]->b_data) +
- ((((unsigned long) sb->s_imap[0])-1)%EXT_INODES_PER_BLOCK);
+ efi = ((struct ext_free_inode *) sb->u.ext_sb.s_imap[1]->b_data) +
+ ((((unsigned long) sb->u.ext_sb.s_imap[0])-1)%EXT_INODES_PER_BLOCK);
count = efi->count + 1;
ino = efi->next;
while (ino) {
- if (ino < 1 || ino > sb->s_ninodes) {
- printk ("s_imap[0] = %d, ino = %d\n",
- (int) sb->s_imap[0],ino);
+ if (ino < 1 || ino > sb->u.ext_sb.s_ninodes) {
+ printk ("u.ext_sb.s_imap[0] = %d, ino = %d\n",
+ (int) sb->u.ext_sb.s_imap[0],ino);
panic ("ext_count_fre_inodes: bad inode number in free list\n");
}
block = 2 + ((ino - 1) / EXT_INODES_PER_BLOCK);
- if (!(bh = bread (sb->s_dev, block))) {
+ if (!(bh = bread (sb->s_dev, block, sb->s_blocksize))) {
printk ("ext_count_free_inodes: error while reading free inodes list\n");
block = 0;
} else {
@@ -334,11 +333,11 @@ unsigned long ext_count_free_inodes(struct super_block *sb)
}
}
printk("ext_count_free_inodes: stored = %d, computed = %d\n",
- (unsigned long) sb->s_imap[2], count);
+ (unsigned long) sb->u.ext_sb.s_imap[2], count);
free_super (sb);
return count;
#else
- return (unsigned long) sb->s_imap[2];
+ return (unsigned long) sb->u.ext_sb.s_imap[2];
#endif
}
diff --git a/fs/ext/inode.c b/fs/ext/inode.c
index 807f883..dae86ae 100644
--- a/fs/ext/inode.c
+++ b/fs/ext/inode.c
@@ -1,21 +1,22 @@
/*
* linux/fs/ext/inode.c
*
- * (C) 1992 Remy Card (card@masi.ibp.fr)
+ * Copyright (C) 1992 Remy Card (card@masi.ibp.fr)
*
* from
*
* linux/fs/minix/inode.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
-#include <linux/string.h>
-#include <linux/stat.h>
#include <linux/sched.h>
#include <linux/ext_fs.h>
#include <linux/kernel.h>
#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/stat.h>
+
#include <asm/system.h>
#include <asm/segment.h>
@@ -38,15 +39,15 @@ void ext_put_super(struct super_block *sb)
sb->s_dev = 0;
#ifdef EXTFS_BITMAP
for(i = 0 ; i < EXT_I_MAP_SLOTS ; i++)
- brelse(sb->s_imap[i]);
+ brelse(sb->u.ext_sb.s_imap[i]);
for(i = 0 ; i < EXT_Z_MAP_SLOTS ; i++)
- brelse(sb->s_zmap[i]);
+ brelse(sb->u.ext_sb.s_zmap[i]);
#endif
#ifdef EXTFS_FREELIST
- if (sb->s_imap[1])
- brelse (sb->s_imap[1]);
- if (sb->s_zmap[1])
- brelse (sb->s_zmap[1]);
+ if (sb->u.ext_sb.s_imap[1])
+ brelse (sb->u.ext_sb.s_imap[1]);
+ if (sb->u.ext_sb.s_zmap[1])
+ brelse (sb->u.ext_sb.s_zmap[1]);
#endif
free_super(sb);
return;
@@ -65,13 +66,13 @@ struct super_block *ext_read_super(struct super_block *s,void *data)
{
struct buffer_head *bh;
struct ext_super_block *es;
- int dev=s->s_dev,block;
+ int dev = s->s_dev,block;
#ifdef EXTFS_BITMAP
int i;
#endif
lock_super(s);
- if (!(bh = bread(dev,1))) {
+ if (!(bh = bread(dev, 1, BLOCK_SIZE))) {
s->s_dev=0;
free_super(s);
printk("bread failed\n");
@@ -80,21 +81,22 @@ struct super_block *ext_read_super(struct super_block *s,void *data)
/* *((struct ext_super_block *) s) =
*((struct ext_super_block *) bh->b_data); */
es = (struct ext_super_block *) bh->b_data;
- s->s_ninodes = es->s_ninodes;
- s->s_nzones = es->s_nzones;
+ s->s_blocksize = 1024;
+ s->u.ext_sb.s_ninodes = es->s_ninodes;
+ s->u.ext_sb.s_nzones = es->s_nzones;
#ifdef EXTFS_BITMAP
- s->s_imap_blocks = es->s_imap_blocks;
- s->s_zmap_blocks = es->s_zmap_blocks;
+ s->u.ext_sb.s_imap_blocks = es->s_imap_blocks;
+ s->u.ext_sb.s_zmap_blocks = es->s_zmap_blocks;
#endif
- s->s_firstdatazone = es->s_firstdatazone;
- s->s_log_zone_size = es->s_log_zone_size;
- s->s_max_size = es->s_max_size;
+ s->u.ext_sb.s_firstdatazone = es->s_firstdatazone;
+ s->u.ext_sb.s_log_zone_size = es->s_log_zone_size;
+ s->u.ext_sb.s_max_size = es->s_max_size;
s->s_magic = es->s_magic;
#ifdef EXTFS_FREELIST
- s->s_zmap[0] = (struct buffer_head *) es->s_firstfreeblock;
- s->s_zmap[2] = (struct buffer_head *) es->s_freeblockscount;
- s->s_imap[0] = (struct buffer_head *) es->s_firstfreeinode;
- s->s_imap[2] = (struct buffer_head *) es->s_freeinodescount;
+ s->u.ext_sb.s_zmap[0] = (struct buffer_head *) es->s_firstfreeblock;
+ s->u.ext_sb.s_zmap[2] = (struct buffer_head *) es->s_freeblockscount;
+ s->u.ext_sb.s_imap[0] = (struct buffer_head *) es->s_firstfreeinode;
+ s->u.ext_sb.s_imap[2] = (struct buffer_head *) es->s_freeinodescount;
#endif
brelse(bh);
if (s->s_magic != EXT_SUPER_MAGIC) {
@@ -105,50 +107,50 @@ struct super_block *ext_read_super(struct super_block *s,void *data)
}
#ifdef EXTFS_BITMAP
for (i=0;i < EXT_I_MAP_SLOTS;i++)
- s->s_imap[i] = NULL;
+ s->u.ext_sb.s_imap[i] = NULL;
for (i=0;i < EXT_Z_MAP_SLOTS;i++)
- s->s_zmap[i] = NULL;
+ s->u.ext_sb.s_zmap[i] = NULL;
block=2;
- for (i=0 ; i < s->s_imap_blocks ; i++)
- if (s->s_imap[i]=bread(dev,block))
+ for (i=0 ; i < s->u.ext_sb.s_imap_blocks ; i++)
+ if (s->u.ext_sb.s_imap[i]=bread(dev, block, BLOCK_SIZE))
block++;
else
break;
- for (i=0 ; i < s->s_zmap_blocks ; i++)
- if (s->s_zmap[i]=bread(dev,block))
+ for (i=0 ; i < s->u.ext_sb.s_zmap_blocks ; i++)
+ if (s->u.ext_sb.s_zmap[i]=bread(dev, block, BLOCK_SIZE))
block++;
else
break;
- if (block != 2+s->s_imap_blocks+s->s_zmap_blocks) {
+ if (block != 2+s->u.ext_sb.s_imap_blocks+s->u.ext_sb.s_zmap_blocks) {
for(i=0;i<EXT_I_MAP_SLOTS;i++)
- brelse(s->s_imap[i]);
+ brelse(s->u.ext_sb.s_imap[i]);
for(i=0;i<EXT_Z_MAP_SLOTS;i++)
- brelse(s->s_zmap[i]);
+ brelse(s->u.ext_sb.s_zmap[i]);
s->s_dev=0;
free_super(s);
printk("block failed\n");
return NULL;
}
- s->s_imap[0]->b_data[0] |= 1;
- s->s_zmap[0]->b_data[0] |= 1;
+ s->u.ext_sb.s_imap[0]->b_data[0] |= 1;
+ s->u.ext_sb.s_zmap[0]->b_data[0] |= 1;
#endif
#ifdef EXTFS_FREELIST
- if (!s->s_zmap[0])
- s->s_zmap[1] = NULL;
+ if (!s->u.ext_sb.s_zmap[0])
+ s->u.ext_sb.s_zmap[1] = NULL;
else
- if (!(s->s_zmap[1] = bread (dev, (unsigned long) s->s_zmap[0]))) {
+ if (!(s->u.ext_sb.s_zmap[1] = bread(dev, (unsigned long) s->u.ext_sb.s_zmap[0], BLOCK_SIZE))) {
printk ("ext_read_super: unable to read first free block\n");
s->s_dev = 0;
free_super(s);
return NULL;
}
- if (!s->s_imap[0])
- s->s_imap[1] = NULL;
+ if (!s->u.ext_sb.s_imap[0])
+ s->u.ext_sb.s_imap[1] = NULL;
else {
- block = 2 + (((unsigned long) s->s_imap[0]) - 1) / EXT_INODES_PER_BLOCK;
- if (!(s->s_imap[1] = bread (dev, block))) {
+ block = 2 + (((unsigned long) s->u.ext_sb.s_imap[0]) - 1) / EXT_INODES_PER_BLOCK;
+ if (!(s->u.ext_sb.s_imap[1] = bread(dev, block, BLOCK_SIZE))) {
printk ("ext_read_super: unable to read first free inode block\n");
- brelse(s->s_zmap[1]);
+ brelse(s->u.ext_sb.s_zmap[1]);
s->s_dev = 0;
free_super (s);
return NULL;
@@ -177,15 +179,15 @@ void ext_write_super (struct super_block *sb)
#ifdef EXTFS_DEBUG
printk ("ext_write_super called\n");
#endif
- if (!(bh = bread (sb->s_dev, 1))) {
+ if (!(bh = bread(sb->s_dev, 1, BLOCK_SIZE))) {
printk ("ext_write_super: bread failed\n");
return;
}
es = (struct ext_super_block *) bh->b_data;
- es->s_firstfreeblock = (unsigned long) sb->s_zmap[0];
- es->s_freeblockscount = (unsigned long) sb->s_zmap[2];
- es->s_firstfreeinode = (unsigned long) sb->s_imap[0];
- es->s_freeinodescount = (unsigned long) sb->s_imap[2];
+ es->s_firstfreeblock = (unsigned long) sb->u.ext_sb.s_zmap[0];
+ es->s_freeblockscount = (unsigned long) sb->u.ext_sb.s_zmap[2];
+ es->s_firstfreeinode = (unsigned long) sb->u.ext_sb.s_imap[0];
+ es->s_freeinodescount = (unsigned long) sb->u.ext_sb.s_imap[2];
bh->b_dirt = 1;
brelse (bh);
sb->s_dirt = 0;
@@ -198,11 +200,11 @@ void ext_statfs (struct super_block *sb, struct statfs *buf)
put_fs_long(EXT_SUPER_MAGIC, &buf->f_type);
put_fs_long(1024, &buf->f_bsize);
- put_fs_long(sb->s_nzones << sb->s_log_zone_size, &buf->f_blocks);
+ put_fs_long(sb->u.ext_sb.s_nzones << sb->u.ext_sb.s_log_zone_size, &buf->f_blocks);
tmp = ext_count_free_blocks(sb);
put_fs_long(tmp, &buf->f_bfree);
put_fs_long(tmp, &buf->f_bavail);
- put_fs_long(sb->s_ninodes, &buf->f_files);
+ put_fs_long(sb->u.ext_sb.s_ninodes, &buf->f_files);
put_fs_long(ext_count_free_inodes(sb), &buf->f_ffree);
/* Don't know what value to put in buf->f_fsid */
}
@@ -237,7 +239,7 @@ static int _ext_bmap(struct inode * inode,int block,int create)
}
if (!inode->i_data[9])
return 0;
- if (!(bh = bread(inode->i_dev,inode->i_data[9])))
+ if (!(bh = bread(inode->i_dev, inode->i_data[9], BLOCK_SIZE)))
return 0;
i = ((unsigned long *) (bh->b_data))[block];
if (create && !i)
@@ -257,7 +259,7 @@ static int _ext_bmap(struct inode * inode,int block,int create)
}
if (!inode->i_data[10])
return 0;
- if (!(bh=bread(inode->i_dev,inode->i_data[10])))
+ if (!(bh=bread(inode->i_dev, inode->i_data[10], BLOCK_SIZE)))
return 0;
i = ((unsigned long *)bh->b_data)[block>>8];
if (create && !i)
@@ -268,7 +270,7 @@ static int _ext_bmap(struct inode * inode,int block,int create)
brelse(bh);
if (!i)
return 0;
- if (!(bh=bread(inode->i_dev,i)))
+ if (!(bh=bread(inode->i_dev, i, BLOCK_SIZE)))
return 0;
i = ((unsigned long *)bh->b_data)[block&255];
if (create && !i)
@@ -279,6 +281,46 @@ static int _ext_bmap(struct inode * inode,int block,int create)
brelse(bh);
return i;
}
+ if (create && !inode->i_data[11])
+ if (inode->i_data[11] = ext_new_block(inode->i_dev)) {
+ inode->i_dirt = 1;
+ inode->i_ctime = CURRENT_TIME;
+ }
+ if (!inode->i_data[11])
+ return 0;
+ if (!(bh = bread(inode->i_dev, inode->i_data[11], BLOCK_SIZE)))
+ return 0;
+ i = ((unsigned long *) bh->b_data)[block >> 16];
+ if (create && !i)
+ if (i = ext_new_block(inode->i_dev)) {
+ ((unsigned long *) bh->b_data)[block >> 16] = i;
+ bh->b_dirt = 1;
+ }
+ brelse (bh);
+ if (!i)
+ return 0;
+ if (!(bh = bread(inode->i_dev, i, BLOCK_SIZE)))
+ return 0;
+ i = ((unsigned long *) bh->b_data)[(block >> 8) & 255];
+ if (create && !i)
+ if (i = ext_new_block(inode->i_dev)) {
+ ((unsigned long *) bh->b_data)[(block >> 8) & 255] = i;
+ bh->b_dirt = 1;
+ }
+ brelse (bh);
+ if (!i)
+ return 0;
+ if (!(bh = bread(inode->i_dev, i, BLOCK_SIZE)))
+ return 0;
+ i = ((unsigned long *) bh->b_data)[block & 255];
+ if (create && !i)
+ if (i = ext_new_block(inode->i_dev)) {
+ ((unsigned long *) bh->b_data)[block & 255] = i;
+ bh->b_dirt = 1;
+ }
+ brelse (bh);
+ return i;
+
printk("ext_bmap: triple indirection not yet implemented\n");
return 0;
}
@@ -300,13 +342,13 @@ void ext_read_inode(struct inode * inode)
int block;
#ifdef EXTFS_BITMAP
- block = 2 + inode->i_sb->s_imap_blocks + inode->i_sb->s_zmap_blocks +
+ block = 2 + inode->i_sb->u.ext_sb.s_imap_blocks + inode->i_sb->u.ext_sb.s_zmap_blocks +
(inode->i_ino-1)/EXT_INODES_PER_BLOCK;
#endif
#ifdef EXTFS_FREELIST
block = 2 + (inode->i_ino-1)/EXT_INODES_PER_BLOCK;
#endif
- if (!(bh=bread(inode->i_dev,block)))
+ if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE)))
panic("unable to read i-node block");
raw_inode = ((struct ext_inode *) bh->b_data) +
(inode->i_ino-1)%EXT_INODES_PER_BLOCK;
@@ -348,13 +390,13 @@ void ext_write_inode(struct inode * inode)
int block;
#ifdef EXTFS_BITMAP
- block = 2 + inode->i_sb->s_imap_blocks + inode->i_sb->s_zmap_blocks +
+ block = 2 + inode->i_sb->u.ext_sb.s_imap_blocks + inode->i_sb->u.ext_sb.s_zmap_blocks +
(inode->i_ino-1)/EXT_INODES_PER_BLOCK;
#endif
#ifdef EXTFS_FREELIST
block = 2 + (inode->i_ino-1)/EXT_INODES_PER_BLOCK;
#endif
- if (!(bh=bread(inode->i_dev,block)))
+ if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE)))
panic("unable to read i-node block");
raw_inode = ((struct ext_inode *)bh->b_data) +
(inode->i_ino-1)%EXT_INODES_PER_BLOCK;
diff --git a/fs/ext/namei.c b/fs/ext/namei.c
index d4d44c4..bea8dc0 100644
--- a/fs/ext/namei.c
+++ b/fs/ext/namei.c
@@ -1,13 +1,13 @@
/*
* linux/fs/ext/namei.c
*
- * (C) 1992 Remy Card (card@masi.ibp.fr)
+ * Copyright (C) 1992 Remy Card (card@masi.ibp.fr)
*
* from
*
* linux/fs/minix/namei.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
#include <linux/sched.h>
@@ -16,9 +16,10 @@
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
+#include <linux/errno.h>
+
#include <asm/segment.h>
-#include <errno.h>
#include <const.h>
/*
@@ -110,7 +111,7 @@ static struct buffer_head * ext_find_entry(struct inode * dir,
/* entries = dir->i_size / (sizeof (struct ext_dir_entry)); */
if (!(block = dir->i_data[0]))
return NULL;
- if (!(bh = bread(dir->i_dev,block)))
+ if (!(bh = bread(dir->i_dev, block, BLOCK_SIZE)))
return NULL;
if (prev_dir)
*prev_dir = NULL;
@@ -124,7 +125,7 @@ static struct buffer_head * ext_find_entry(struct inode * dir,
brelse(bh);
bh = NULL;
if (!(block = ext_bmap(dir,offset>>BLOCK_SIZE_BITS)) ||
- !(bh = bread(dir->i_dev,block))) {
+ !(bh = bread(dir->i_dev, block, BLOCK_SIZE))) {
/* i += EXT_DIR_ENTRIES_PER_BLOCK; */
/* offset += BLOCK_SIZE; */
continue;
@@ -214,7 +215,7 @@ static struct buffer_head * ext_add_entry(struct inode * dir,
return NULL;
if (!(block = dir->i_data[0]))
return NULL;
- if (!(bh = bread(dir->i_dev,block)))
+ if (!(bh = bread(dir->i_dev, block, BLOCK_SIZE)))
return NULL;
rec_len = ((8 + namelen + EXT_DIR_PAD - 1) / EXT_DIR_PAD) * EXT_DIR_PAD;
/* i = 0; */
@@ -230,7 +231,7 @@ printk ("ext_add_entry: skipping to next block\n");
block = ext_create_block(dir,offset>>BLOCK_SIZE_BITS);
if (!block)
return NULL;
- if (!(bh = bread(dir->i_dev,block))) {
+ if (!(bh = bread(dir->i_dev, block, BLOCK_SIZE))) {
/* i += EXT_DIR_ENTRIES_PER_BLOCK; */
offset += BLOCK_SIZE;
continue;
@@ -263,7 +264,7 @@ printk ("ext_add_entry : creating next block\n");
#endif
if (!block)
return NULL;
- if (!(bh = bread(dir->i_dev,block)))
+ if (!(bh = bread(dir->i_dev, block, BLOCK_SIZE)))
return NULL; /* Other thing to do ??? */
de = (struct ext_dir_entry *) bh->b_data;
}
@@ -428,7 +429,7 @@ int ext_mkdir(struct inode * dir, const char * name, int len, int mode)
return -ENOSPC;
}
inode->i_dirt = 1;
- if (!(dir_block = bread(inode->i_dev,inode->i_data[0]))) {
+ if (!(dir_block = bread(inode->i_dev, inode->i_data[0], BLOCK_SIZE))) {
iput(dir);
inode->i_nlink--;
inode->i_dirt = 1;
@@ -481,7 +482,7 @@ static int empty_dir(struct inode * inode)
/* len = inode->i_size / sizeof (struct ext_dir_entry); */
if (inode->i_size < 2 * 12 || !inode->i_data[0] ||
- !(bh=bread(inode->i_dev,inode->i_data[0]))) {
+ !(bh=bread(inode->i_dev, inode->i_data[0], BLOCK_SIZE))) {
printk("warning - bad directory on dev %04x\n",inode->i_dev);
return 0;
}
@@ -503,7 +504,7 @@ static int empty_dir(struct inode * inode)
offset += BLOCK_SIZE;
continue;
}
- if (!(bh=bread(inode->i_dev,block)))
+ if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE)))
return 0;
de = (struct ext_dir_entry *) bh->b_data;
}
@@ -643,7 +644,7 @@ int ext_symlink(struct inode * dir, const char * name, int len, const char * sym
return -ENOSPC;
}
inode->i_dirt = 1;
- if (!(name_block = bread(inode->i_dev,inode->i_data[0]))) {
+ if (!(name_block = bread(inode->i_dev, inode->i_data[0], BLOCK_SIZE))) {
iput(dir);
inode->i_nlink--;
inode->i_dirt = 1;
@@ -825,7 +826,7 @@ start_up:
retval = -EIO;
if (!old_inode->i_data[0])
goto end_rename;
- if (!(dir_bh = bread(old_inode->i_dev, old_inode->i_data[0])))
+ if (!(dir_bh = bread(old_inode->i_dev, old_inode->i_data[0], BLOCK_SIZE)))
goto end_rename;
if (PARENT_INO(dir_bh->b_data) != old_dir->i_ino)
goto end_rename;
@@ -845,8 +846,8 @@ start_up:
/* ok, that's it */
old_de->inode = 0;
old_de->name_len = 0;
- ext_merge_entries (old_de, pde, nde);
new_de->inode = old_inode->i_ino;
+ ext_merge_entries (old_de, pde, nde);
if (new_inode) {
new_inode->i_nlink--;
new_inode->i_dirt = 1;
diff --git a/fs/ext/symlink.c b/fs/ext/symlink.c
index eeef2b4..1daf1cb 100644
--- a/fs/ext/symlink.c
+++ b/fs/ext/symlink.c
@@ -1,21 +1,20 @@
/*
* linux/fs/ext/symlink.c
*
- * (C) 1992 Remy Card (card@masi.ibp.fr)
+ * Copyright (C) 1992 Remy Card (card@masi.ibp.fr)
*
* from
*
* linux/fs/minix/symlink.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*
* ext symlink handling code
*/
-#include <errno.h>
-
#include <asm/segment.h>
+#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/ext_fs.h>
@@ -63,7 +62,7 @@ static struct inode * ext_follow_link(struct inode * dir, struct inode * inode)
}
__asm__("mov %%fs,%0":"=r" (fs));
if ((current->link_count > 5) || !inode->i_data[0] ||
- !(bh = bread(inode->i_dev, inode->i_data[0]))) {
+ !(bh = bread(inode->i_dev, inode->i_data[0], BLOCK_SIZE))) {
iput(dir);
iput(inode);
return NULL;
@@ -91,7 +90,7 @@ static int ext_readlink(struct inode * inode, char * buffer, int buflen)
if (buflen > 1023)
buflen = 1023;
if (inode->i_data[0])
- bh = bread(inode->i_dev, inode->i_data[0]);
+ bh = bread(inode->i_dev, inode->i_data[0], BLOCK_SIZE);
else
bh = NULL;
iput(inode);
diff --git a/fs/ext/truncate.c b/fs/ext/truncate.c
index 04c0b2e..3e647e8 100644
--- a/fs/ext/truncate.c
+++ b/fs/ext/truncate.c
@@ -1,13 +1,13 @@
/*
* linux/fs/ext/truncate.c
*
- * (C) 1992 Remy Card (card@masi.ibp.fr)
+ * Copyright (C) 1992 Remy Card (card@masi.ibp.fr)
*
* from
*
* linux/fs/minix/truncate.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
#include <linux/sched.h>
@@ -15,8 +15,7 @@
#include <linux/tty.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
-
-#include <errno.h>
+#include <linux/errno.h>
/*
* Truncate has the most races in the whole filesystem: coding it is
@@ -59,7 +58,7 @@ static int trunc_indirect(struct inode * inode, int offset, unsigned long * p)
#define INDIRECT_BLOCK (DIRECT_BLOCK-offset)
if (*p)
- bh = bread(inode->i_dev,*p);
+ bh = bread(inode->i_dev, *p, BLOCK_SIZE);
if (!bh)
return 0;
repeat:
@@ -88,16 +87,16 @@ repeat:
return result;
}
-static int trunc_dindirect(struct inode * inode)
+static int trunc_dindirect(struct inode * inode, int offset, unsigned long * p)
{
int i;
struct buffer_head * bh = NULL;
unsigned long * dind;
int result = 0;
-#define DINDIRECT_BLOCK ((DIRECT_BLOCK-(256+9))>>8)
+#define DINDIRECT_BLOCK ((DIRECT_BLOCK-offset)>>8)
- if (inode->i_data[10])
- bh = bread(inode->i_dev,inode->i_data[10]);
+ if (*p)
+ bh = bread(inode->i_dev, *p, BLOCK_SIZE);
if (!bh)
return 0;
repeat:
@@ -109,7 +108,7 @@ repeat:
dind = i+(unsigned long *) bh->b_data;
if (!*dind)
continue;
- result |= trunc_indirect(inode,9+256+(i<<8),dind);
+ result |= trunc_indirect(inode,offset+(i<<8),dind);
}
dind = (unsigned long *) bh->b_data;
for (i = 0; i < 256; i++)
@@ -118,8 +117,44 @@ repeat:
brelse(bh);
if (i >= 256) {
result = 1;
- if (ext_free_block(inode->i_dev,inode->i_data[10]))
- inode->i_data[10] = 0;
+ if (ext_free_block(inode->i_dev,*p))
+ *p = 0;
+ }
+ return result;
+}
+
+static int trunc_tindirect(struct inode * inode)
+{
+ int i;
+ struct buffer_head * bh = NULL;
+ unsigned long * tind;
+ int result = 0;
+#define TINDIRECT_BLOCK ((DIRECT_BLOCK-(256*256+256+9))>>16)
+
+ if (inode->i_data[11])
+ bh = bread(inode->i_dev, inode->i_data[11], BLOCK_SIZE);
+ if (!bh)
+ return 0;
+repeat:
+ for (i = TINDIRECT_BLOCK ; i < 256 ; i ++) {
+ if (i < 0)
+ i = 0;
+ if (i < TINDIRECT_BLOCK)
+ goto repeat;
+ tind = i+(unsigned long *) bh->b_data;
+ if (!*tind)
+ continue;
+ result |= trunc_dindirect(inode,9+256+256*256+(i<<16),tind);
+ }
+ tind = (unsigned long *) bh->b_data;
+ for (i = 0; i < 256; i++)
+ if (*(tind++))
+ break;
+ brelse(bh);
+ if (i >= 256) {
+ result = 1;
+ if (ext_free_block(inode->i_dev,inode->i_data[11]))
+ inode->i_data[11] = 0;
}
return result;
}
@@ -136,7 +171,8 @@ void ext_truncate(struct inode * inode)
while (1) {
flag = trunc_direct(inode);
flag |= trunc_indirect(inode,9,(unsigned long *)&inode->i_data[9]);
- flag |= trunc_dindirect(inode);
+ flag |= trunc_dindirect(inode,9+256,(unsigned long *)&inode->i_data[10]);
+ flag |= trunc_tindirect(inode);
if (!flag)
break;
current->counter = 0;
diff --git a/fs/fcntl.c b/fs/fcntl.c
index 02b5af1..7e61dd9 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -1,18 +1,17 @@
/*
* linux/fs/fcntl.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
-#include <errno.h>
-
#include <asm/segment.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
#include <linux/string.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
extern int sys_close(int fd);
diff --git a/fs/fifo.c b/fs/fifo.c
index 8e1a7d2..84da040 100644
--- a/fs/fifo.c
+++ b/fs/fifo.c
@@ -4,11 +4,10 @@
* written by Paul H. Hargrove
*/
-#include <errno.h>
-
-#include <linux/fcntl.h>
#include <linux/sched.h>
#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/fcntl.h>
extern struct file_operations read_pipe_fops;
extern struct file_operations write_pipe_fops;
@@ -87,7 +86,7 @@ static int fifo_open(struct inode * inode,struct file * filp)
wake_up(&PIPE_WRITE_WAIT(*inode));
if (retval || inode->i_size)
return retval;
- page = get_free_page();
+ page = get_free_page(GFP_KERNEL);
if (inode->i_size) {
free_page(page);
return 0;
diff --git a/fs/file_table.c b/fs/file_table.c
index e0589ac..fe0f44a 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -1,9 +1,24 @@
/*
* linux/fs/file_table.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
#include <linux/fs.h>
+#include <linux/string.h>
struct file file_table[NR_FILE];
+
+struct file * get_empty_filp(void)
+{
+ int i;
+ struct file * f = file_table+0;
+
+ for (i = 0; i++ < NR_FILE; f++)
+ if (!f->f_count) {
+ memset(f,0,sizeof(*f));
+ f->f_count = 1;
+ return f;
+ }
+ return NULL;
+}
diff --git a/fs/inode.c b/fs/inode.c
index 65637df..eaf3093 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1,14 +1,14 @@
/*
* linux/fs/inode.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
-#include <linux/string.h>
#include <linux/stat.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
+#include <linux/string.h>
#include <asm/system.h>
@@ -188,7 +188,7 @@ struct inode * get_pipe_inode(void)
if (!(inode = get_empty_inode()))
return NULL;
- if (!(inode->i_size = get_free_page())) {
+ if (!(inode->i_size = get_free_page(GFP_USER))) {
inode->i_count = 0;
return NULL;
}
diff --git a/fs/ioctl.c b/fs/ioctl.c
index 6c9ef40..243b604 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -1,15 +1,15 @@
/*
* linux/fs/ioctl.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
-#include <errno.h>
-
#include <asm/segment.h>
+
+#include <linux/sched.h>
+#include <linux/errno.h>
#include <linux/string.h>
#include <linux/stat.h>
-#include <linux/sched.h>
int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
{
diff --git a/fs/minix/Makefile b/fs/minix/Makefile
index 0fdd188..f834539 100644
--- a/fs/minix/Makefile
+++ b/fs/minix/Makefile
@@ -30,74 +30,88 @@ dep:
cp tmp_make Makefile
### Dependencies:
-bitmap.o : bitmap.c /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
- /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
- /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/minix_fs.h
-blkdev.o : blkdev.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
- /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/minix_fs.h \
- /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h \
- /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h
-chrdev.o : chrdev.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
- /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/minix_fs.h \
- /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h \
- /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h
-dir.o : dir.c /usr/src/linux/include/errno.h /usr/src/linux/include/asm/segment.h \
- /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
- /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
- /usr/src/linux/include/linux/minix_fs.h /usr/src/linux/include/linux/stat.h
+bitmap.o : bitmap.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/mm.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/minix_fs.h /usr/src/linux/include/linux/string.h
+blkdev.o : blkdev.c /usr/src/linux/include/linux/errno.h /usr/src/linux/include/linux/sched.h \
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/minix_fs.h /usr/src/linux/include/linux/tty.h /usr/src/linux/include/linux/termios.h \
+ /usr/src/linux/include/asm/system.h /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h
+chrdev.o : chrdev.c /usr/src/linux/include/linux/errno.h /usr/src/linux/include/linux/sched.h \
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/minix_fs.h /usr/src/linux/include/linux/tty.h /usr/src/linux/include/linux/termios.h \
+ /usr/src/linux/include/asm/system.h /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h
+dir.o : dir.c /usr/src/linux/include/asm/segment.h /usr/src/linux/include/linux/errno.h \
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/minix_fs.h \
+ /usr/src/linux/include/linux/stat.h
fifo.o : fifo.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
- /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
- /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
- /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
- /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
- /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/minix_fs.h
-file.o : file.c /usr/src/linux/include/errno.h /usr/src/linux/include/sys/dirent.h \
- /usr/src/linux/include/limits.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
- /usr/src/linux/include/asm/segment.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/linux/fcntl.h \
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/mm.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/minix_fs.h
+file.o : file.c /usr/src/linux/include/asm/segment.h /usr/src/linux/include/asm/system.h \
/usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
- /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/minix_fs.h \
- /usr/src/linux/include/linux/stat.h
-inode.o : inode.c /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \
- /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
- /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \
- /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \
- /usr/src/linux/include/linux/minix_fs.h /usr/src/linux/include/asm/system.h \
- /usr/src/linux/include/asm/segment.h
+ /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h \
+ /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/minix_fs.h /usr/src/linux/include/linux/errno.h \
+ /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/linux/stat.h
+inode.o : inode.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/mm.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/minix_fs.h /usr/src/linux/include/linux/string.h \
+ /usr/src/linux/include/linux/stat.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/segment.h
namei.o : namei.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
- /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
- /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
- /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
- /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
- /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/minix_fs.h \
- /usr/src/linux/include/linux/string.h /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h \
- /usr/src/linux/include/asm/segment.h /usr/src/linux/include/errno.h /usr/src/linux/include/const.h
-symlink.o : symlink.c /usr/src/linux/include/errno.h /usr/src/linux/include/asm/segment.h \
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/mm.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/minix_fs.h /usr/src/linux/include/linux/string.h \
+ /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/linux/errno.h \
+ /usr/src/linux/include/asm/segment.h /usr/src/linux/include/const.h
+symlink.o : symlink.c /usr/src/linux/include/asm/segment.h /usr/src/linux/include/linux/errno.h \
/usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
- /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h \
- /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
- /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \
- /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \
+ /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h \
+ /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
/usr/src/linux/include/linux/minix_fs.h /usr/src/linux/include/linux/stat.h
-truncate.o : truncate.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
- /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/minix_fs.h \
- /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h \
- /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h
+truncate.o : truncate.c /usr/src/linux/include/linux/errno.h /usr/src/linux/include/linux/sched.h \
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/minix_fs.h /usr/src/linux/include/linux/tty.h /usr/src/linux/include/linux/termios.h \
+ /usr/src/linux/include/asm/system.h /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fcntl.h
diff --git a/fs/minix/bitmap.c b/fs/minix/bitmap.c
index 4d560d4..57bed4b 100644
--- a/fs/minix/bitmap.c
+++ b/fs/minix/bitmap.c
@@ -1,15 +1,15 @@
/*
* linux/fs/minix/bitmap.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
/* bitmap.c contains the code that handles the inode and block bitmaps */
-#include <linux/string.h>
#include <linux/sched.h>
#include <linux/minix_fs.h>
#include <linux/kernel.h>
+#include <linux/string.h>
#define clear_block(addr) \
__asm__("cld\n\t" \
@@ -81,9 +81,9 @@ int minix_free_block(int dev, int block)
if (!(sb = get_super(dev)))
panic("trying to free block on nonexistent device");
- if (block < sb->s_firstdatazone || block >= sb->s_nzones)
+ if (block < sb->u.minix_sb.s_firstdatazone || block >= sb->u.minix_sb.s_nzones)
panic("trying to free block not in datazone");
- bh = get_hash_table(dev,block);
+ bh = get_hash_table(dev,block,BLOCK_SIZE);
if (bh) {
if (bh->b_count > 1) {
brelse(bh);
@@ -94,10 +94,10 @@ int minix_free_block(int dev, int block)
if (bh->b_count)
brelse(bh);
}
- zone = block - sb->s_firstdatazone + 1;
+ zone = block - sb->u.minix_sb.s_firstdatazone + 1;
bit = zone & 8191;
zone >>= 13;
- bh = sb->s_zmap[zone];
+ bh = sb->u.minix_sb.s_zmap[zone];
if (clear_bit(bit,bh->b_data))
printk("free_block (%04x:%d): bit already cleared\n",dev,block);
bh->b_dirt = 1;
@@ -114,18 +114,18 @@ int minix_new_block(int dev)
panic("trying to get new block from nonexistant device");
j = 8192;
for (i=0 ; i<8 ; i++)
- if (bh=sb->s_zmap[i])
+ if (bh=sb->u.minix_sb.s_zmap[i])
if ((j=find_first_zero(bh->b_data))<8192)
break;
if (i>=8 || !bh || j>=8192)
return 0;
- if (set_bit(j,bh->b_data))
+ if (set_bit(j,bh->b_data))
panic("new_block: bit already set");
bh->b_dirt = 1;
- j += i*8192 + sb->s_firstdatazone-1;
- if (j >= sb->s_nzones)
+ j += i*8192 + sb->u.minix_sb.s_firstdatazone-1;
+ if (j >= sb->u.minix_sb.s_nzones)
return 0;
- if (!(bh=getblk(dev,j)))
+ if (!(bh=getblk(dev,j,BLOCK_SIZE)))
panic("new_block: cannot get block");
if (bh->b_count != 1)
panic("new block: count is != 1");
@@ -138,8 +138,8 @@ int minix_new_block(int dev)
unsigned long minix_count_free_blocks(struct super_block *sb)
{
- return (sb->s_nzones - count_used(sb->s_zmap,sb->s_zmap_blocks,sb->s_nzones))
- << sb->s_log_zone_size;
+ return (sb->u.minix_sb.s_nzones - count_used(sb->u.minix_sb.s_zmap,sb->u.minix_sb.s_zmap_blocks,sb->u.minix_sb.s_nzones))
+ << sb->u.minix_sb.s_log_zone_size;
}
void minix_free_inode(struct inode * inode)
@@ -164,11 +164,11 @@ void minix_free_inode(struct inode * inode)
printk("free_inode: inode on nonexistent device\n");
return;
}
- if (inode->i_ino < 1 || inode->i_ino > inode->i_sb->s_ninodes) {
+ if (inode->i_ino < 1 || inode->i_ino > inode->i_sb->u.minix_sb.s_ninodes) {
printk("free_inode: inode 0 or nonexistent inode\n");
return;
}
- if (!(bh=inode->i_sb->s_imap[inode->i_ino>>13])) {
+ if (!(bh=inode->i_sb->u.minix_sb.s_imap[inode->i_ino>>13])) {
printk("free_inode: nonexistent imap in superblock\n");
return;
}
@@ -194,10 +194,10 @@ struct inode * minix_new_inode(int dev)
inode->i_flags = inode->i_sb->s_flags;
j = 8192;
for (i=0 ; i<8 ; i++)
- if (bh=inode->i_sb->s_imap[i])
+ if (bh=inode->i_sb->u.minix_sb.s_imap[i])
if ((j=find_first_zero(bh->b_data))<8192)
break;
- if (!bh || j >= 8192 || j+i*8192 > inode->i_sb->s_ninodes) {
+ if (!bh || j >= 8192 || j+i*8192 > inode->i_sb->u.minix_sb.s_ninodes) {
iput(inode);
return NULL;
}
@@ -221,5 +221,5 @@ struct inode * minix_new_inode(int dev)
unsigned long minix_count_free_inodes(struct super_block *sb)
{
- return sb->s_ninodes - count_used(sb->s_imap,sb->s_imap_blocks,sb->s_ninodes);
+ return sb->u.minix_sb.s_ninodes - count_used(sb->u.minix_sb.s_imap,sb->u.minix_sb.s_imap_blocks,sb->u.minix_sb.s_ninodes);
}
diff --git a/fs/minix/blkdev.c b/fs/minix/blkdev.c
index 144d19f..c8fae84 100644
--- a/fs/minix/blkdev.c
+++ b/fs/minix/blkdev.c
@@ -1,11 +1,10 @@
/*
* linux/fs/minix/blkdev.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
-#include <errno.h>
-
+#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/minix_fs.h>
#include <linux/tty.h>
diff --git a/fs/minix/chrdev.c b/fs/minix/chrdev.c
index c9e61d3..f179796 100644
--- a/fs/minix/chrdev.c
+++ b/fs/minix/chrdev.c
@@ -1,11 +1,10 @@
/*
* linux/fs/minix/chrdev.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
-#include <errno.h>
-
+#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/minix_fs.h>
#include <linux/tty.h>
diff --git a/fs/minix/dir.c b/fs/minix/dir.c
index bfa3551..1a894f8 100644
--- a/fs/minix/dir.c
+++ b/fs/minix/dir.c
@@ -1,15 +1,14 @@
/*
* linux/fs/minix/dir.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*
* minix directory handling functions
*/
-#include <errno.h>
-
#include <asm/segment.h>
+#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/minix_fs.h>
#include <linux/stat.h>
@@ -62,7 +61,7 @@ static int minix_readdir(struct inode * inode, struct file * filp,
while (filp->f_pos < inode->i_size) {
offset = filp->f_pos & 1023;
block = minix_bmap(inode,(filp->f_pos)>>BLOCK_SIZE_BITS);
- if (!block || !(bh = bread(inode->i_dev,block))) {
+ if (!block || !(bh = bread(inode->i_dev,block,BLOCK_SIZE))) {
filp->f_pos += 1024-offset;
continue;
}
diff --git a/fs/minix/file.c b/fs/minix/file.c
index cc7e33a..eb8c1b0 100644
--- a/fs/minix/file.c
+++ b/fs/minix/file.c
@@ -1,22 +1,19 @@
/*
* linux/fs/minix/file.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*
* minix regular file handling primitives
*/
-#include <errno.h>
-
-#include <sys/dirent.h>
-
#include <asm/segment.h>
#include <asm/system.h>
-#include <linux/fcntl.h>
#include <linux/sched.h>
#include <linux/minix_fs.h>
#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/fcntl.h>
#include <linux/stat.h>
#define NBUF 16
@@ -108,7 +105,7 @@ int minix_file_read(struct inode * inode, struct file * filp, char * buf, int co
if (blocks) {
--blocks;
if (nr = minix_bmap(inode,block++)) {
- *bhb = getblk(inode->i_dev,nr);
+ *bhb = getblk(inode->i_dev,nr,BLOCK_SIZE);
if (!(*bhb)->b_uptodate)
ll_rw_block(READ,*bhb);
} else
@@ -194,9 +191,9 @@ 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 = getblk(inode->i_dev, block);
+ bh = getblk(inode->i_dev, block, BLOCK_SIZE);
else
- bh = bread(inode->i_dev,block);
+ bh = bread(inode->i_dev,block, BLOCK_SIZE);
if (!bh) {
if (!written)
written = -EIO;
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index 71b45bc..b90a4e8 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -1,15 +1,16 @@
/*
* linux/fs/minix/inode.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
-#include <linux/string.h>
-#include <linux/stat.h>
#include <linux/sched.h>
#include <linux/minix_fs.h>
#include <linux/kernel.h>
#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/stat.h>
+
#include <asm/system.h>
#include <asm/segment.h>
@@ -29,9 +30,9 @@ void minix_put_super(struct super_block *sb)
lock_super(sb);
sb->s_dev = 0;
for(i = 0 ; i < MINIX_I_MAP_SLOTS ; i++)
- brelse(sb->s_imap[i]);
+ brelse(sb->u.minix_sb.s_imap[i]);
for(i = 0 ; i < MINIX_Z_MAP_SLOTS ; i++)
- brelse(sb->s_zmap[i]);
+ brelse(sb->u.minix_sb.s_zmap[i]);
free_super(sb);
return;
}
@@ -52,20 +53,21 @@ struct super_block *minix_read_super(struct super_block *s,void *data)
int i,dev=s->s_dev,block;
lock_super(s);
- if (!(bh = bread(dev,1))) {
+ if (!(bh = bread(dev,1,BLOCK_SIZE))) {
s->s_dev=0;
free_super(s);
printk("bread failed\n");
return NULL;
}
ms = (struct minix_super_block *) bh->b_data;
- s->s_ninodes = ms->s_ninodes;
- s->s_nzones = ms->s_nzones;
- s->s_imap_blocks = ms->s_imap_blocks;
- s->s_zmap_blocks = ms->s_zmap_blocks;
- s->s_firstdatazone = ms->s_firstdatazone;
- s->s_log_zone_size = ms->s_log_zone_size;
- s->s_max_size = ms->s_max_size;
+ s->s_blocksize = 1024;
+ s->u.minix_sb.s_ninodes = ms->s_ninodes;
+ s->u.minix_sb.s_nzones = ms->s_nzones;
+ s->u.minix_sb.s_imap_blocks = ms->s_imap_blocks;
+ s->u.minix_sb.s_zmap_blocks = ms->s_zmap_blocks;
+ s->u.minix_sb.s_firstdatazone = ms->s_firstdatazone;
+ s->u.minix_sb.s_log_zone_size = ms->s_log_zone_size;
+ s->u.minix_sb.s_max_size = ms->s_max_size;
s->s_magic = ms->s_magic;
brelse(bh);
if (s->s_magic != MINIX_SUPER_MAGIC) {
@@ -75,32 +77,32 @@ struct super_block *minix_read_super(struct super_block *s,void *data)
return NULL;
}
for (i=0;i < MINIX_I_MAP_SLOTS;i++)
- s->s_imap[i] = NULL;
+ s->u.minix_sb.s_imap[i] = NULL;
for (i=0;i < MINIX_Z_MAP_SLOTS;i++)
- s->s_zmap[i] = NULL;
+ s->u.minix_sb.s_zmap[i] = NULL;
block=2;
- for (i=0 ; i < s->s_imap_blocks ; i++)
- if (s->s_imap[i]=bread(dev,block))
+ for (i=0 ; i < s->u.minix_sb.s_imap_blocks ; i++)
+ if (s->u.minix_sb.s_imap[i]=bread(dev,block,BLOCK_SIZE))
block++;
else
break;
- for (i=0 ; i < s->s_zmap_blocks ; i++)
- if (s->s_zmap[i]=bread(dev,block))
+ for (i=0 ; i < s->u.minix_sb.s_zmap_blocks ; i++)
+ if (s->u.minix_sb.s_zmap[i]=bread(dev,block,BLOCK_SIZE))
block++;
else
break;
- if (block != 2+s->s_imap_blocks+s->s_zmap_blocks) {
+ if (block != 2+s->u.minix_sb.s_imap_blocks+s->u.minix_sb.s_zmap_blocks) {
for(i=0;i<MINIX_I_MAP_SLOTS;i++)
- brelse(s->s_imap[i]);
+ brelse(s->u.minix_sb.s_imap[i]);
for(i=0;i<MINIX_Z_MAP_SLOTS;i++)
- brelse(s->s_zmap[i]);
+ brelse(s->u.minix_sb.s_zmap[i]);
s->s_dev=0;
free_super(s);
printk("block failed\n");
return NULL;
}
- s->s_imap[0]->b_data[0] |= 1;
- s->s_zmap[0]->b_data[0] |= 1;
+ s->u.minix_sb.s_imap[0]->b_data[0] |= 1;
+ s->u.minix_sb.s_zmap[0]->b_data[0] |= 1;
free_super(s);
/* set up enough so that it can read an inode */
s->s_dev = dev;
@@ -119,11 +121,11 @@ void minix_statfs (struct super_block *sb, struct statfs *buf)
put_fs_long(MINIX_SUPER_MAGIC, &buf->f_type);
put_fs_long(1024, &buf->f_bsize);
- put_fs_long(sb->s_nzones << sb->s_log_zone_size, &buf->f_blocks);
+ put_fs_long(sb->u.minix_sb.s_nzones << sb->u.minix_sb.s_log_zone_size, &buf->f_blocks);
tmp = minix_count_free_blocks(sb);
put_fs_long(tmp, &buf->f_bfree);
put_fs_long(tmp, &buf->f_bavail);
- put_fs_long(sb->s_ninodes, &buf->f_files);
+ put_fs_long(sb->u.minix_sb.s_ninodes, &buf->f_files);
put_fs_long(minix_count_free_inodes(sb), &buf->f_ffree);
/* Don't know what value to put in buf->f_fsid */
}
@@ -158,7 +160,7 @@ static int _minix_bmap(struct inode * inode,int block,int create)
}
if (!inode->i_data[7])
return 0;
- if (!(bh = bread(inode->i_dev,inode->i_data[7])))
+ if (!(bh = bread(inode->i_dev,inode->i_data[7],BLOCK_SIZE)))
return 0;
i = ((unsigned short *) (bh->b_data))[block];
if (create && !i)
@@ -177,7 +179,7 @@ static int _minix_bmap(struct inode * inode,int block,int create)
}
if (!inode->i_data[8])
return 0;
- if (!(bh=bread(inode->i_dev,inode->i_data[8])))
+ if (!(bh=bread(inode->i_dev,inode->i_data[8], BLOCK_SIZE)))
return 0;
i = ((unsigned short *)bh->b_data)[block>>9];
if (create && !i)
@@ -188,7 +190,7 @@ static int _minix_bmap(struct inode * inode,int block,int create)
brelse(bh);
if (!i)
return 0;
- if (!(bh=bread(inode->i_dev,i)))
+ if (!(bh=bread(inode->i_dev,i,BLOCK_SIZE)))
return 0;
i = ((unsigned short *)bh->b_data)[block&511];
if (create && !i)
@@ -216,9 +218,9 @@ void minix_read_inode(struct inode * inode)
struct minix_inode * raw_inode;
int block;
- block = 2 + inode->i_sb->s_imap_blocks + inode->i_sb->s_zmap_blocks +
+ 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;
- if (!(bh=bread(inode->i_dev,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;
@@ -259,9 +261,9 @@ void minix_write_inode(struct inode * inode)
struct minix_inode * raw_inode;
int block;
- block = 2 + inode->i_sb->s_imap_blocks + inode->i_sb->s_zmap_blocks +
+ 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;
- if (!(bh=bread(inode->i_dev,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;
diff --git a/fs/minix/namei.c b/fs/minix/namei.c
index a00c8cd..1a51c87 100644
--- a/fs/minix/namei.c
+++ b/fs/minix/namei.c
@@ -1,7 +1,7 @@
/*
* linux/fs/minix/namei.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
#include <linux/sched.h>
@@ -10,9 +10,10 @@
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/fcntl.h>
+#include <linux/errno.h>
+
#include <asm/segment.h>
-#include <errno.h>
#include <const.h>
/*
@@ -77,7 +78,7 @@ static struct buffer_head * minix_find_entry(struct inode * dir,
entries = dir->i_size / (sizeof (struct minix_dir_entry));
if (!(block = dir->i_data[0]))
return NULL;
- if (!(bh = bread(dir->i_dev,block)))
+ if (!(bh = bread(dir->i_dev, block, BLOCK_SIZE)))
return NULL;
i = 0;
de = (struct minix_dir_entry *) bh->b_data;
@@ -86,7 +87,7 @@ static struct buffer_head * minix_find_entry(struct inode * dir,
brelse(bh);
bh = NULL;
if (!(block = minix_bmap(dir,i/MINIX_DIR_ENTRIES_PER_BLOCK)) ||
- !(bh = bread(dir->i_dev,block))) {
+ !(bh = bread(dir->i_dev, block, BLOCK_SIZE))) {
i += MINIX_DIR_ENTRIES_PER_BLOCK;
continue;
}
@@ -162,7 +163,7 @@ static struct buffer_head * minix_add_entry(struct inode * dir,
return NULL;
if (!(block = dir->i_data[0]))
return NULL;
- if (!(bh = bread(dir->i_dev,block)))
+ if (!(bh = bread(dir->i_dev, block, BLOCK_SIZE)))
return NULL;
i = 0;
de = (struct minix_dir_entry *) bh->b_data;
@@ -173,7 +174,7 @@ static struct buffer_head * minix_add_entry(struct inode * dir,
block = minix_create_block(dir,i/MINIX_DIR_ENTRIES_PER_BLOCK);
if (!block)
return NULL;
- if (!(bh = bread(dir->i_dev,block))) {
+ if (!(bh = bread(dir->i_dev, block, BLOCK_SIZE))) {
i += MINIX_DIR_ENTRIES_PER_BLOCK;
continue;
}
@@ -321,7 +322,7 @@ int minix_mkdir(struct inode * dir, const char * name, int len, int mode)
return -ENOSPC;
}
inode->i_dirt = 1;
- if (!(dir_block = bread(inode->i_dev,inode->i_data[0]))) {
+ if (!(dir_block = bread(inode->i_dev, inode->i_data[0], BLOCK_SIZE))) {
iput(dir);
inode->i_nlink--;
inode->i_dirt = 1;
@@ -368,7 +369,7 @@ static int empty_dir(struct inode * inode)
len = inode->i_size / sizeof (struct minix_dir_entry);
if (len<2 || !inode->i_data[0] ||
- !(bh=bread(inode->i_dev,inode->i_data[0]))) {
+ !(bh=bread(inode->i_dev, inode->i_data[0], BLOCK_SIZE))) {
printk("warning - bad directory on dev %04x\n",inode->i_dev);
return 0;
}
@@ -388,7 +389,7 @@ static int empty_dir(struct inode * inode)
nr += MINIX_DIR_ENTRIES_PER_BLOCK;
continue;
}
- if (!(bh=bread(inode->i_dev,block)))
+ if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE)))
return 0;
de = (struct minix_dir_entry *) bh->b_data;
}
@@ -515,7 +516,7 @@ int minix_symlink(struct inode * dir, const char * name, int len, const char * s
return -ENOSPC;
}
inode->i_dirt = 1;
- if (!(name_block = bread(inode->i_dev,inode->i_data[0]))) {
+ if (!(name_block = bread(inode->i_dev, inode->i_data[0], BLOCK_SIZE))) {
iput(dir);
inode->i_nlink--;
inode->i_dirt = 1;
@@ -693,7 +694,7 @@ start_up:
retval = -EIO;
if (!old_inode->i_data[0])
goto end_rename;
- if (!(dir_bh = bread(old_inode->i_dev, old_inode->i_data[0])))
+ if (!(dir_bh = bread(old_inode->i_dev, old_inode->i_data[0], BLOCK_SIZE)))
goto end_rename;
if (PARENT_INO(dir_bh->b_data) != old_dir->i_ino)
goto end_rename;
diff --git a/fs/minix/symlink.c b/fs/minix/symlink.c
index 1f99b07..65263a0 100644
--- a/fs/minix/symlink.c
+++ b/fs/minix/symlink.c
@@ -1,15 +1,14 @@
/*
* linux/fs/minix/symlink.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*
* minix symlink handling code
*/
-#include <errno.h>
-
#include <asm/segment.h>
+#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/minix_fs.h>
@@ -57,7 +56,7 @@ static struct inode * minix_follow_link(struct inode * dir, struct inode * inode
}
__asm__("mov %%fs,%0":"=r" (fs));
if ((current->link_count > 5) || !inode->i_data[0] ||
- !(bh = bread(inode->i_dev, inode->i_data[0]))) {
+ !(bh = bread(inode->i_dev, inode->i_data[0], BLOCK_SIZE))) {
iput(dir);
iput(inode);
return NULL;
@@ -85,7 +84,7 @@ static int minix_readlink(struct inode * inode, char * buffer, int buflen)
if (buflen > 1023)
buflen = 1023;
if (inode->i_data[0])
- bh = bread(inode->i_dev, inode->i_data[0]);
+ bh = bread(inode->i_dev, inode->i_data[0], BLOCK_SIZE);
else
bh = NULL;
iput(inode);
diff --git a/fs/minix/truncate.c b/fs/minix/truncate.c
index e9c7a82..767dd3d 100644
--- a/fs/minix/truncate.c
+++ b/fs/minix/truncate.c
@@ -1,11 +1,10 @@
/*
* linux/fs/truncate.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
-#include <errno.h>
-
+#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/minix_fs.h>
#include <linux/tty.h>
@@ -53,7 +52,7 @@ static int trunc_indirect(struct inode * inode, int offset, unsigned short * p)
#define INDIRECT_BLOCK (DIRECT_BLOCK-offset)
if (*p)
- bh = bread(inode->i_dev,*p);
+ bh = bread(inode->i_dev, *p, BLOCK_SIZE);
if (!bh)
return 0;
repeat:
@@ -91,7 +90,7 @@ static int trunc_dindirect(struct inode * inode)
#define DINDIRECT_BLOCK ((DIRECT_BLOCK-(512+7))>>9)
if (inode->i_data[8])
- bh = bread(inode->i_dev,inode->i_data[8]);
+ bh = bread(inode->i_dev, inode->i_data[8], BLOCK_SIZE);
if (!bh)
return 0;
repeat:
diff --git a/fs/msdos/Makefile b/fs/msdos/Makefile
index 204791e..485a62b 100644
--- a/fs/msdos/Makefile
+++ b/fs/msdos/Makefile
@@ -26,52 +26,56 @@ clean:
dep:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
- (for i in *.c;do $(CPP) -M $$i;done) >> tmp_make
+ for i in *.c;do $(CPP) -M $$i;done >> tmp_make
cp tmp_make Makefile
### Dependencies:
-dir.o : dir.c /usr/src/linux/include/errno.h /usr/src/linux/include/asm/segment.h \
- /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
- /usr/src/linux/include/linux/wait.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
- /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
- /usr/src/linux/include/linux/msdos_fs.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
- /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h
-fat.o : fat.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/stat.h \
- /usr/src/linux/include/linux/msdos_fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
- /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
- /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
- /usr/src/linux/include/linux/kernel.h
-file.o : file.c /usr/src/linux/include/errno.h /usr/src/linux/include/asm/segment.h \
- /usr/src/linux/include/asm/system.h /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/sched.h \
+dir.o : dir.c /usr/src/linux/include/asm/segment.h /usr/src/linux/include/linux/sched.h \
/usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
- /usr/src/linux/include/linux/wait.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
- /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/msdos_fs.h
-inode.o : inode.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/string.h \
- /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/stat.h \
- /usr/src/linux/include/linux/msdos_fs.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
- /usr/src/linux/include/linux/wait.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/signal.h \
- /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
- /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/segment.h
-misc.o : misc.c /usr/src/linux/include/errno.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
- /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/msdos_fs.h \
- /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
- /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
- /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h
-namei.o : namei.c /usr/src/linux/include/errno.h /usr/src/linux/include/asm/segment.h \
- /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
- /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
- /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
- /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
- /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
- /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
- /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/msdos_fs.h
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/msdos_fs.h /usr/src/linux/include/linux/errno.h \
+ /usr/src/linux/include/linux/stat.h
+fat.o : fat.c /usr/src/linux/include/linux/msdos_fs.h /usr/src/linux/include/linux/fs.h \
+ /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h \
+ /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/errno.h /usr/src/linux/include/linux/stat.h
+file.o : file.c /usr/src/linux/include/asm/segment.h /usr/src/linux/include/asm/system.h \
+ /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
+ /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h \
+ /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/msdos_fs.h /usr/src/linux/include/linux/errno.h \
+ /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/linux/stat.h
+inode.o : inode.c /usr/src/linux/include/linux/msdos_fs.h /usr/src/linux/include/linux/fs.h \
+ /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h \
+ /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/signal.h /usr/src/linux/include/linux/time.h \
+ /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/errno.h /usr/src/linux/include/linux/string.h /usr/src/linux/include/linux/stat.h \
+ /usr/src/linux/include/asm/segment.h
+misc.o : misc.c /usr/src/linux/include/linux/msdos_fs.h /usr/src/linux/include/linux/fs.h \
+ /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h \
+ /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/mm.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/errno.h /usr/src/linux/include/linux/string.h /usr/src/linux/include/linux/stat.h
+namei.o : namei.c /usr/src/linux/include/asm/segment.h /usr/src/linux/include/linux/sched.h \
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/msdos_fs.h /usr/src/linux/include/linux/errno.h \
+ /usr/src/linux/include/linux/string.h /usr/src/linux/include/linux/stat.h
diff --git a/fs/msdos/dir.c b/fs/msdos/dir.c
index 999610d..e3caef2 100644
--- a/fs/msdos/dir.c
+++ b/fs/msdos/dir.c
@@ -6,14 +6,13 @@
* MS-DOS directory handling functions
*/
-#include <errno.h>
#include <asm/segment.h>
-#include <linux/stat.h>
-#include <linux/fs.h>
-#include <linux/msdos_fs.h>
-/* for compatibility warnings */
#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/msdos_fs.h>
+#include <linux/errno.h>
+#include <linux/stat.h>
static int msdos_dummy_read(struct inode *inode,struct file *filp,char *buf,
int count);
diff --git a/fs/msdos/fat.c b/fs/msdos/fat.c
index 7336ca6..b1a120e 100644
--- a/fs/msdos/fat.c
+++ b/fs/msdos/fat.c
@@ -4,15 +4,13 @@
* Written 1992 by Werner Almesberger
*/
-#include <errno.h>
-#include <linux/stat.h>
#include <linux/msdos_fs.h>
#include <linux/kernel.h>
-
+#include <linux/errno.h>
+#include <linux/stat.h>
static struct fat_cache *fat_cache,cache[FAT_CACHE];
-
/* Returns the this'th FAT entry, -1 if it is an end-of-file entry. If
new_value is != -1, that FAT entry is replaced by it. */
diff --git a/fs/msdos/file.c b/fs/msdos/file.c
index 449b40d..eb48bbd 100644
--- a/fs/msdos/file.c
+++ b/fs/msdos/file.c
@@ -6,20 +6,19 @@
* MS-DOS regular file handling primitives
*/
-#include <errno.h>
#include <asm/segment.h>
#include <asm/system.h>
-#include <linux/fcntl.h>
-#include <linux/stat.h>
+
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/msdos_fs.h>
-
+#include <linux/errno.h>
+#include <linux/fcntl.h>
+#include <linux/stat.h>
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
-
static int msdos_file_read(struct inode *inode,struct file *filp,char *buf,
int count);
static int msdos_file_write(struct inode *inode,struct file *filp,char *buf,
@@ -202,7 +201,6 @@ void msdos_truncate(struct inode *inode)
{
int cluster;
- if (!S_ISREG(inode->i_mode)) return;
cluster = SECTOR_SIZE*MSDOS_SB(inode->i_sb)->cluster_size;
(void) fat_free(inode,(inode->i_size+(cluster-1))/cluster);
inode->i_data[D_ATTRS] |= ATTR_ARCH;
diff --git a/fs/msdos/inode.c b/fs/msdos/inode.c
index 0b43c72..451cb37 100644
--- a/fs/msdos/inode.c
+++ b/fs/msdos/inode.c
@@ -4,14 +4,14 @@
* Written 1992 by Werner Almesberger
*/
-#include <errno.h>
-#include <linux/string.h>
-#include <linux/stat.h>
#include <linux/msdos_fs.h>
#include <linux/kernel.h>
#include <linux/sched.h>
-#include <asm/segment.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/stat.h>
+#include <asm/segment.h>
void msdos_put_inode(struct inode *inode)
{
@@ -66,7 +66,7 @@ static int parse_options(char *options,char *check,char *conversion)
if (!strcmp(this,"check") && value) {
if (value[0] && !value[1] && strchr("rns",*value))
*check = *value;
- else if (!strcmp(value,"releaxed")) *check = 'r';
+ else if (!strcmp(value,"relaxed")) *check = 'r';
else if (!strcmp(value,"normal")) *check = 'n';
else if (!strcmp(value,"strict")) *check = 's';
else return 0;
@@ -100,7 +100,7 @@ struct super_block *msdos_read_super(struct super_block *s,void *data)
}
cache_init();
lock_super(s);
- bh = bread(s->s_dev,0);
+ bh = bread(s->s_dev, 0, BLOCK_SIZE);
free_super(s);
if (bh == NULL) {
s->s_dev = 0;
@@ -108,6 +108,7 @@ struct super_block *msdos_read_super(struct super_block *s,void *data)
return NULL;
}
b = (struct msdos_boot_sector *) bh->b_data;
+ s->s_blocksize = 1024; /* we cannot handle anything else yet */
MSDOS_SB(s)->cluster_size = b->cluster_size;
MSDOS_SB(s)->fats = b->fats;
MSDOS_SB(s)->fat_start = b->reserved;
@@ -122,7 +123,7 @@ struct super_block *msdos_read_super(struct super_block *s,void *data)
0;
MSDOS_SB(s)->fat_bits = MSDOS_SB(s)->clusters > MSDOS_FAT12 ? 16 : 12;
brelse(bh);
-printk("[MS-DOS FS Rel. alpha.5, FAT %d, check=%c, conv=%c]\r\n",
+printk("[MS-DOS FS Rel. alpha.6, FAT %d, check=%c, conv=%c]\r\n",
MSDOS_SB(s)->fat_bits,check,conversion);
printk("[me=0x%x,cs=%d,#f=%d,fs=%d,fl=%d,ds=%d,de=%d,data=%d,se=%d,ts=%d]\r\n",
b->media,MSDOS_SB(s)->cluster_size,MSDOS_SB(s)->fats,MSDOS_SB(s)->fat_start,
@@ -214,7 +215,7 @@ void msdos_read_inode(struct inode *inode)
inode->i_mtime = inode->i_atime = inode->i_ctime = 0;
return;
}
- if (!(bh = bread(inode->i_dev,inode->i_ino >> MSDOS_DPB_BITS)))
+ if (!(bh = bread(inode->i_dev,inode->i_ino >> MSDOS_DPB_BITS, BLOCK_SIZE)))
panic("unable to read i-node block");
raw_entry = &((struct msdos_dir_entry *) (bh->b_data))
[inode->i_ino & (MSDOS_DPB-1)];
@@ -255,7 +256,7 @@ void msdos_write_inode(struct inode *inode)
inode->i_dirt = 0;
if (inode->i_ino == MSDOS_ROOT_INO || !inode->i_nlink) return;
- if (!(bh = bread(inode->i_dev,inode->i_ino >> MSDOS_DPB_BITS)))
+ if (!(bh = bread(inode->i_dev,inode->i_ino >> MSDOS_DPB_BITS, BLOCK_SIZE)))
panic("unable to read i-node block");
raw_entry = &((struct msdos_dir_entry *) (bh->b_data))
[inode->i_ino & (MSDOS_DPB-1)];
diff --git a/fs/msdos/misc.c b/fs/msdos/misc.c
index 563be03..65d3ee9 100644
--- a/fs/msdos/misc.c
+++ b/fs/msdos/misc.c
@@ -4,19 +4,17 @@
* Written 1992 by Werner Almesberger
*/
-#include <errno.h>
-#include <limits.h>
-#include <linux/string.h>
-#include <linux/stat.h>
#include <linux/msdos_fs.h>
#include <linux/sched.h>
#include <linux/kernel.h>
-
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/stat.h>
static char bin_extensions[] =
"EXECOMAPPSYSOVLOBJLIB" /* program code */
- "ARCZIPLHALZHZOOTARZ ARJ" /* common archivers */
- "GIFBMPTIFGL JPG" /* graphics */
+ "ARCZIPLHALZHZOOTARZ ARJTZ " /* common archivers */
+ "GIFBMPTIFGL JPGPCX" /* graphics */
"TFMVF GF PK PXLDVI"; /* TeX */
@@ -100,7 +98,7 @@ printk("set to %x\r\n",fat_access(inode->i_sb,this,-1));
else {
last = 0;
if (current = inode->i_data[D_START]) {
- cache_lookup(inode,INT_MAX,&last,&current);
+ cache_lookup(inode,0x7fffffff,&last,&current);
while (current && current != -1)
if (!(current = fat_access(inode->i_sb,
last = current,-1)))
@@ -127,7 +125,7 @@ printk("zeroing sector %d\r\n",sector);
#endif
if (current < MSDOS_SB(inode->i_sb)->cluster_size-1 &&
!(sector & 1)) {
- if (!(bh = getblk(inode->i_dev,sector >> 1)))
+ if (!(bh = getblk(inode->i_dev,sector >> 1, BLOCK_SIZE)))
printk("getblk failed\r\n");
else {
memset(bh->b_data,0,BLOCK_SIZE);
@@ -171,7 +169,7 @@ int date_dos2unix(unsigned short time,unsigned short date)
{
int month,year;
- month = ((date >> 5) & 4)-1;
+ month = ((date >> 5) & 15)-1;
year = date >> 9;
return (time & 31)*2+60*((time >> 5) & 63)+(time >> 11)*3600+86400*
((date & 31)-1+day_n[month]+(year/4)+year*365-((year & 3) == 0 &&
@@ -220,10 +218,13 @@ int msdos_get_entry(struct inode *dir,int *pos,struct buffer_head **bh,
offset = *pos;
if ((sector = msdos_smap(dir,*pos >> SECTOR_BITS)) == -1)
return -1;
- if (!sector) return -1; /* FAT error ... */
+ if (!sector)
+ return -1; /* FAT error ... */
*pos += sizeof(struct msdos_dir_entry);
- if (*bh) brelse(*bh);
- if (!(*bh = msdos_sread(dir->i_dev,sector,&data))) continue;
+ if (*bh)
+ brelse(*bh);
+ if (!(*bh = msdos_sread(dir->i_dev,sector,&data)))
+ continue;
*de = (struct msdos_dir_entry *) (data+(offset &
(SECTOR_SIZE-1)));
return (sector << MSDOS_DPS_BITS)+((offset & (SECTOR_SIZE-1)) >>
diff --git a/fs/msdos/namei.c b/fs/msdos/namei.c
index ebe9bf3..0c4cc4f 100644
--- a/fs/msdos/namei.c
+++ b/fs/msdos/namei.c
@@ -4,14 +4,14 @@
* Written 1992 by Werner Almesberger
*/
-#include <errno.h>
#include <asm/segment.h>
-#include <linux/string.h>
-#include <linux/stat.h>
+
#include <linux/sched.h>
#include <linux/msdos_fs.h>
#include <linux/kernel.h>
-
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/stat.h>
/* MS-DOS "device special files" */
@@ -280,14 +280,17 @@ int msdos_rmdir(struct inode *dir,const char *name,int len)
res = -EBUSY;
if (dir->i_dev != inode->i_dev || dir == inode) goto rmdir_done;
if (inode->i_count > 1) goto rmdir_done;
- res = -ENOTEMPTY;
- pos = 0;
- dbh = NULL;
- while (msdos_get_entry(inode,&pos,&dbh,&dde) > -1)
- if (dde->name[0] && ((unsigned char *) dde->name)[0] !=
- DELETED_FLAG && strncmp(dde->name,MSDOS_DOT,MSDOS_NAME) &&
- strncmp(dde->name,MSDOS_DOTDOT,MSDOS_NAME)) goto rmdir_done;
- if (dbh) brelse(dbh);
+ if (inode->i_data[D_START]) { /* may be zero in mkdir */
+ res = -ENOTEMPTY;
+ pos = 0;
+ dbh = NULL;
+ while (msdos_get_entry(inode,&pos,&dbh,&dde) > -1)
+ if (dde->name[0] && ((unsigned char *) dde->name)[0] !=
+ DELETED_FLAG && strncmp(dde->name,MSDOS_DOT,
+ MSDOS_NAME) && strncmp(dde->name,MSDOS_DOTDOT,
+ MSDOS_NAME)) goto rmdir_done;
+ if (dbh) brelse(dbh);
+ }
inode->i_nlink = 0;
dir->i_mtime = CURRENT_TIME;
inode->i_dirt = dir->i_dirt = 1;
diff --git a/fs/namei.c b/fs/namei.c
index 17bdd29..42eb868 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1,18 +1,18 @@
/*
* linux/fs/namei.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
* Some corrections by tytso.
*/
-#include <errno.h>
#include <const.h>
#include <asm/segment.h>
+#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/string.h>
diff --git a/fs/open.c b/fs/open.c
index 275e429..538f7ae 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -1,20 +1,19 @@
/*
* linux/fs/open.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
-#include <errno.h>
-#include <sys/types.h>
-#include <utime.h>
-
-#include <sys/vfs.h>
-
+#include <linux/vfs.h>
+#include <linux/types.h>
+#include <linux/utime.h>
+#include <linux/errno.h>
#include <linux/fcntl.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/sched.h>
#include <linux/kernel.h>
+#include <linux/signal.h>
#include <asm/segment.h>
@@ -307,20 +306,17 @@ int sys_open(const char * filename,int flag,int mode)
if (fd>=NR_OPEN)
return -EMFILE;
current->close_on_exec &= ~(1<<fd);
- f=0+file_table;
- for (i=0 ; i<NR_FILE ; i++,f++)
- if (!f->f_count) break;
- if (i>=NR_FILE)
+ f = get_empty_filp();
+ if (!f)
return -ENFILE;
- (current->filp[fd] = f)->f_count++;
+ current->filp[fd] = f;
if ((i = open_namei(filename,flag,mode,&inode))<0) {
current->filp[fd]=NULL;
- f->f_count=0;
+ f->f_count--;
return i;
}
f->f_mode = "\001\002\003\000"[flag & O_ACCMODE];
f->f_flags = flag;
- f->f_count = 1;
f->f_inode = inode;
f->f_pos = 0;
f->f_reada = 0;
@@ -330,7 +326,7 @@ int sys_open(const char * filename,int flag,int mode)
if (f->f_op && f->f_op->open)
if (i = f->f_op->open(inode,f)) {
iput(inode);
- f->f_count=0;
+ f->f_count--;
current->filp[fd]=NULL;
return i;
}
@@ -365,6 +361,12 @@ int sys_close(unsigned int fd)
if (filp->f_op && filp->f_op->release)
filp->f_op->release(inode,filp);
filp->f_count--;
+ filp->f_inode = NULL;
iput(inode);
return 0;
}
+
+int sys_vhangup(void)
+{
+ return -ENOSYS;
+}
diff --git a/fs/pipe.c b/fs/pipe.c
index 29f43bf..014f690 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -1,18 +1,17 @@
/*
* linux/fs/pipe.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
-#include <signal.h>
-#include <errno.h>
-#include <termios.h>
-
#include <asm/segment.h>
-#include <linux/fcntl.h>
#include <linux/sched.h>
#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/fcntl.h>
+#include <linux/termios.h>
static int pipe_read(struct inode * inode, struct file * filp, char * buf, int count)
{
@@ -208,14 +207,13 @@ int sys_pipe(unsigned long * fildes)
int i,j;
verify_area(fildes,8);
- j=0;
- for(i=0;j<2 && i<NR_FILE;i++)
- if (!file_table[i].f_count)
- (f[j++]=i+file_table)->f_count++;
+ for(j=0 ; j<2 ; j++)
+ if (!(f[j] = get_empty_filp()))
+ break;
if (j==1)
- f[0]->f_count=0;
+ f[0]->f_count--;
if (j<2)
- return -1;
+ return -ENFILE;
j=0;
for(i=0;j<2 && i<NR_OPEN;i++)
if (!current->filp[i]) {
@@ -225,14 +223,16 @@ int sys_pipe(unsigned long * fildes)
if (j==1)
current->filp[fd[0]]=NULL;
if (j<2) {
- f[0]->f_count=f[1]->f_count=0;
- return -1;
+ f[0]->f_count--;
+ f[1]->f_count--;
+ return -EMFILE;
}
if (!(inode=get_pipe_inode())) {
- current->filp[fd[0]] =
- current->filp[fd[1]] = NULL;
- f[0]->f_count = f[1]->f_count = 0;
- return -1;
+ current->filp[fd[0]] = NULL;
+ current->filp[fd[1]] = NULL;
+ f[0]->f_count--;
+ f[1]->f_count--;
+ return -ENFILE;
}
f[0]->f_inode = f[1]->f_inode = inode;
f[0]->f_pos = f[1]->f_pos = 0;
diff --git a/fs/read_write.c b/fs/read_write.c
index f7919fd..e72e6b2 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -1,17 +1,16 @@
/*
* linux/fs/read_write.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/dirent.h>
-
+#include <linux/types.h>
+#include <linux/errno.h>
#include <linux/stat.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/minix_fs.h>
+
#include <asm/segment.h>
/*
diff --git a/fs/select.c b/fs/select.c
index d5fa7e8..5cd8e0f 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -5,21 +5,20 @@
* patches by Peter MacDonald. Heavily edited by Linus.
*/
+#include <linux/types.h>
+#include <linux/time.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/stat.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
#include <asm/segment.h>
#include <asm/system.h>
-#include <sys/types.h>
-#include <sys/time.h>
-
#include <const.h>
-#include <errno.h>
-#include <signal.h>
/*
* Ok, Peter made a complicated, but straightforward multiple_wait() function.
@@ -33,8 +32,6 @@
* functions have to call it to add an entry to the select table.
*/
-static select_table * sel_tables = NULL;
-
static void free_wait(select_table * p)
{
struct select_table_entry * entry = p->entry + p->nr;
@@ -134,9 +131,9 @@ repeat:
}
/*
- * Note that we cannot return -ERESTARTSYS, as we change our input
- * parameters. Sad, but there you are. We could do some tweaking in
- * the library function ...
+ * We can actually return ERESTARTSYS insetad of EINTR, but I'd
+ * like to be certain this leads to no problems. So I return
+ * EINTR just for safety.
*/
int sys_select( unsigned long *buffer )
{
@@ -178,8 +175,17 @@ int sys_select( unsigned long *buffer )
else
timeout = 0;
current->timeout = 0;
+ if (tvp) {
+ verify_area(tvp, sizeof(*tvp));
+ put_fs_long(timeout/HZ, (unsigned long *) &tvp->tv_sec);
+ timeout %= HZ;
+ timeout *= (1000000/HZ);
+ put_fs_long(timeout, (unsigned long *) &tvp->tv_usec);
+ }
if (i < 0)
return i;
+ if (!i && (current->signal & ~current->blocked))
+ return -EINTR;
if (inp) {
verify_area(inp, 4);
put_fs_long(res_in,inp);
@@ -192,16 +198,5 @@ int sys_select( unsigned long *buffer )
verify_area(exp,4);
put_fs_long(res_ex,exp);
}
- if (tvp) {
- verify_area(tvp, sizeof(*tvp));
- put_fs_long(timeout/HZ, (unsigned long *) &tvp->tv_sec);
- timeout %= HZ;
- timeout *= (1000000/HZ);
- put_fs_long(timeout, (unsigned long *) &tvp->tv_usec);
- }
- if (i)
- return i;
- if (current->signal & ~current->blocked)
- return -EINTR;
- return 0;
+ return i;
}
diff --git a/fs/stat.c b/fs/stat.c
index 3f1dbf6..225f9d3 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -1,11 +1,10 @@
/*
* linux/fs/stat.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
-#include <errno.h>
-
+#include <linux/errno.h>
#include <linux/stat.h>
#include <linux/fs.h>
#include <linux/sched.h>
diff --git a/fs/super.c b/fs/super.c
index 970ce2e..4d0e030 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -1,7 +1,7 @@
/*
* linux/fs/super.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
@@ -14,12 +14,11 @@
#include <linux/msdos_fs.h>
#include <linux/kernel.h>
#include <linux/stat.h>
+#include <linux/errno.h>
+
#include <asm/system.h>
#include <asm/segment.h>
-#include <errno.h>
-
-
int sync_dev(int dev);
void wait_for_keypress(void);
@@ -139,28 +138,16 @@ static struct super_block * read_super(int dev,char *name,int flags,void *data)
return(NULL);
s->s_dev = dev;
s->s_covered = NULL;
- s->s_time = 0;
s->s_rd_only = 0;
s->s_dirt = 0;
return(s);
}
-int sys_umount(char * dev_name)
+static int do_umount(int dev)
{
- struct inode * inode;
struct super_block * sb;
- int dev;
+ struct inode * inode;
- if (!suser())
- return -EPERM;
- if (!(inode = namei(dev_name)))
- return -ENOENT;
- dev = inode->i_rdev;
- if (!S_ISBLK(inode->i_mode)) {
- iput(inode);
- return -ENOTBLK;
- }
- iput(inode);
if (dev==ROOT_DEV)
return -EBUSY;
if (!(sb=get_super(dev)) || !(sb->s_covered))
@@ -181,6 +168,29 @@ int sys_umount(char * dev_name)
if (sb->s_op && sb->s_op->write_super && sb->s_dirt)
sb->s_op->write_super (sb);
put_super(dev);
+ return 0;
+}
+
+int sys_umount(char * dev_name)
+{
+ struct inode * inode;
+ int dev,retval;
+
+ if (!suser())
+ return -EPERM;
+ if (!(inode = namei(dev_name)))
+ return -ENOENT;
+ dev = inode->i_rdev;
+ if (!S_ISBLK(inode->i_mode)) {
+ iput(inode);
+ return -ENOTBLK;
+ }
+ retval = do_umount(dev);
+ if (!retval && MAJOR(dev) < MAX_BLKDEV &&
+ blkdev_fops[MAJOR(dev)]->release)
+ blkdev_fops[MAJOR(dev)]->release(inode,NULL);
+ iput(inode);
+ if (retval) return retval;
sync_dev(dev);
return 0;
}
@@ -261,13 +271,16 @@ int sys_mount(char * dev_name, char * dir_name, char * type,
retval = -EPERM;
else if (IS_NODEV(inode))
retval = -EACCES;
- iput(inode);
- if (retval)
+ if (!retval && blkdev_fops[MAJOR(dev)]->open)
+ retval = blkdev_fops[MAJOR(dev)]->open(inode,NULL);
+ if (retval) {
+ iput(inode);
return retval;
+ }
if ((new_flags & 0xffff0000) == 0xC0ED0000) {
flags = new_flags & 0xffff;
if (data && (unsigned long) data < TASK_SIZE)
- page = get_free_page();
+ page = get_free_page(GFP_KERNEL);
}
if (page) {
i = TASK_SIZE - (unsigned long) data;
@@ -284,12 +297,16 @@ int sys_mount(char * dev_name, char * dir_name, char * type,
t = "minix";
retval = do_mount(dev,dir_name,t,flags,(void *) page);
free_page(page);
+ if (retval && blkdev_fops[MAJOR(dev)]->release)
+ blkdev_fops[MAJOR(dev)]->release(inode,NULL);
+ iput(inode);
return retval;
}
void mount_root(void)
{
- int i,free;
+ int i;
+ struct file_system_type * fs_type = file_systems;
struct super_block * p;
struct inode * mi;
@@ -303,31 +320,23 @@ void mount_root(void)
}
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;
+ return;
+ }
+ fs_type++;
}
- if (!(p=read_super(ROOT_DEV,"minix",0,NULL)))
- panic("Unable to mount root");
- /*wait_for_keypress();
- if (!(mi=iget(ROOT_DEV,MINIX_ROOT_INO)))
- panic("Unable to read root i-node");
- wait_for_keypress();*/
- mi=p->s_mounted;
- mi->i_count += 3 ; /* NOTE! it is logically used 4 times, not 1 */
- p->s_mounted = p->s_covered = mi;
- p->s_flags = 0;
- current->pwd = mi;
- current->root = mi;
- free=0;
- i=p->s_nzones;
- while (-- i >= 0)
- if (!set_bit(i&8191,p->s_zmap[i>>13]->b_data))
- free++;
- printk("%d/%d free blocks\n\r",free,p->s_nzones);
- free=0;
- i=p->s_ninodes+1;
- while (-- i >= 0)
- if (!set_bit(i&8191,p->s_imap[i>>13]->b_data))
- free++;
- printk("%d/%d free inodes\n\r",free,p->s_ninodes);
+ panic("Unable to mount root");
}
diff --git a/include/asm/irq.h b/include/asm/irq.h
index f9fbe02..7e2b524 100644
--- a/include/asm/irq.h
+++ b/include/asm/irq.h
@@ -26,6 +26,39 @@
"movl $0x17,%edx\n\t" \
"mov %dx,%fs\n\t"
+/*
+ * SAVE_MOST/RESTORE_MOST is used for the faster version of IRQ handlers,
+ * installed by using the SA_INTERRUPT flag. These kinds of IRQ's don't
+ * call the routines that do signal handling etc on return, and can have
+ * more relaxed register-saving etc. They are also atomic, and are thus
+ * suited for small, fast interrupts like the serial lines or the harddisk
+ * drivers, which don't actually need signal handling etc.
+ *
+ * Also note that we actually save only those registers that are used in
+ * C subroutines (%eax, %edx and %ecx), so if you do something weird,
+ * you're on your own. The only segments that are saved (not counting the
+ * automatic stack and code segment handling) are %ds and %es, and they
+ * point to kernel space. No messing around with %fs here.
+ */
+#define SAVE_MOST \
+ "cld\n\t" \
+ "push %es\n\t" \
+ "push %ds\n\t" \
+ "pushl %eax\n\t" \
+ "pushl %edx\n\t" \
+ "pushl %ecx\n\t" \
+ "movl $0x10,%edx\n\t" \
+ "mov %dx,%ds\n\t" \
+ "mov %dx,%es\n\t"
+
+#define RESTORE_MOST \
+ "popl %ecx\n\t" \
+ "popl %edx\n\t" \
+ "popl %eax\n\t" \
+ "pop %ds\n\t" \
+ "pop %es\n\t" \
+ "iret"
+
#define ACK_FIRST(mask) \
"inb $0x21,%al\n\t" \
"jmp 1f\n" \
@@ -67,16 +100,18 @@
#define IRQ_NAME2(nr) nr##_interrupt()
#define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
+#define FAST_IRQ_NAME(nr) IRQ_NAME2(fast_IRQ##nr)
+#define BAD_IRQ_NAME(nr) IRQ_NAME2(bad_IRQ##nr)
#define BUILD_IRQ(chip,nr,mask) \
-extern void IRQ_NAME(nr); \
+void IRQ_NAME(nr); \
+void FAST_IRQ_NAME(nr); \
+void BAD_IRQ_NAME(nr); \
__asm__( \
"\n.align 2\n" \
-".globl _IRQ" #nr "_interrupt\n" \
"_IRQ" #nr "_interrupt:\n\t" \
"pushl $-1\n\t" \
SAVE_ALL \
- "cli\n\t" \
ACK_##chip(mask) \
"sti\n\t" \
"movl %esp,%ebx\n\t" \
@@ -88,7 +123,25 @@ __asm__( \
"jne ret_from_sys_call\n\t" \
"cli\n\t" \
UNBLK_##chip(mask) \
- "sti\n\t" \
- "jmp ret_from_sys_call");
+ "jmp ret_from_sys_call\n" \
+"\n.align 2\n" \
+"_fast_IRQ" #nr "_interrupt:\n\t" \
+ SAVE_MOST \
+ ACK_##chip(mask) \
+ "pushl $" #nr "\n\t" \
+ "call _do_fast_IRQ\n\t" \
+ "addl $4,%esp\n\t" \
+ "testl %eax,%eax\n\t" \
+ "jne 2f\n\t" \
+ "cli\n\t" \
+ UNBLK_##chip(mask) \
+ "\n2:\t" \
+ RESTORE_MOST \
+"\n\n.align 2\n" \
+"_bad_IRQ" #nr "_interrupt:\n\t" \
+ "pushl %eax\n\t" \
+ ACK_##chip(mask) \
+ "popl %eax\n\t" \
+ "iret");
#endif
diff --git a/include/errno.h b/include/errno.h
deleted file mode 100644
index fdb1b14..0000000
--- a/include/errno.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef _ERRNO_H
-#define _ERRNO_H
-
-/*
- * ok, as I hadn't got any other source of information about
- * possible error numbers, I was forced to use the same numbers
- * as minix.
- * Hopefully these are posix or something. I wouldn't know (and posix
- * isn't telling me - they want $$$ for their f***ing standard).
- *
- * We don't use the _SIGN cludge of minix, so kernel returns must
- * see to the sign by themselves.
- *
- * NOTE! Remember to change strerror() if you change this file!
- */
-
-extern int errno;
-
-#define EPERM 1
-#define ENOENT 2
-#define ESRCH 3
-#define EINTR 4
-#define EIO 5
-#define ENXIO 6
-#define E2BIG 7
-#define ENOEXEC 8
-#define EBADF 9
-#define ECHILD 10
-#define EAGAIN 11
-#define ENOMEM 12
-#define EACCES 13
-#define EFAULT 14
-#define ENOTBLK 15
-#define EBUSY 16
-#define EEXIST 17
-#define EXDEV 18
-#define ENODEV 19
-#define ENOTDIR 20
-#define EISDIR 21
-#define EINVAL 22
-#define ENFILE 23
-#define EMFILE 24
-#define ENOTTY 25
-#define ETXTBSY 26
-#define EFBIG 27
-#define ENOSPC 28
-#define ESPIPE 29
-#define EROFS 30
-#define EMLINK 31
-#define EPIPE 32
-#define EDOM 33
-#define ERANGE 34
-#define EDEADLK 35
-#define ENAMETOOLONG 36
-#define ENOLCK 37
-#define ENOSYS 38
-#define ENOTEMPTY 39
-#define ELOOP 40
-
-/* Should never be seen by user programs */
-#define ERESTARTSYS 512
-#define ERESTARTNOINTR 513
-
-#endif
diff --git a/include/limits.h b/include/limits.h
deleted file mode 100644
index 1303adf..0000000
--- a/include/limits.h
+++ /dev/null
@@ -1,62 +0,0 @@
-#ifndef _LIMITS_H
-#define _LIMITS_H
-
-#define RAND_MAX 0x7ffffffd /* don't ask - see rand.c */
-
-#define CHAR_BIT 8
-#define MB_LEN_MAX 1
-
-#define SCHAR_MIN (-128)
-#define SCHAR_MAX 127
-
-#define UCHAR_MAX 255U
-
-#ifdef __CHAR_UNSIGNED__
-#define CHAR_MIN 0
-#define CHAR_MAX UCHAR_MAX
-#else
-#define CHAR_MIN SCHAR_MIN
-#define CHAR_MAX SCHAR_MAX
-#endif
-
-#define SHRT_MIN (-32768)
-#define SHRT_MAX 32767
-
-#define USHRT_MAX 65535U
-
-#define INT_MIN (-2147483648)
-#define INT_MAX 2147483647
-
-#define UINT_MAX 4294967295U
-
-#define LONG_MIN (-2147483648)
-#define LONG_MAX 2147483647
-
-#define ULONG_MAX 4294967295U
-
-/*
- * Why are these different from the section below? -- TYT
- */
-#define _POSIX_ARG_MAX 40960 /* exec() may have 40K worth of args */
-#define _POSIX_CHILD_MAX 6 /* a process may have 6 children */
-#define _POSIX_LINK_MAX 8 /* a file may have 8 links */
-#define _POSIX_MAX_CANON 255 /* size of the canonical input queue */
-#define _POSIX_MAX_INPUT 255 /* you can type 255 chars ahead */
-#define _POSIX_NAME_MAX 14 /* a file name may have 14 chars */
-#define _POSIX_NGROUPS_MAX 32 /* supplementary group IDs are optional */
-#define _POSIX_OPEN_MAX 16 /* a process may have 16 files open */
-#define _POSIX_PATH_MAX 255 /* a pathname may contain 255 chars */
-#define _POSIX_PIPE_BUF 512 /* pipes writes of 512 bytes must be atomic */
-
-#define NGROUPS_MAX 32 /* supplemental group IDs are available */
-#define ARG_MAX 40960 /* # bytes of args + environ for exec() */
-#define CHILD_MAX 999 /* no limit :-) */
-#define OPEN_MAX 20 /* # 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 */
-#define NAME_MAX 255 /* # chars in a file name */
-#define PATH_MAX 1024 /* # chars in a path name */
-#define PIPE_BUF 4095 /* # bytes in atomic write to a pipe */
-
-#endif
diff --git a/include/a.out.h b/include/linux/a.out.h
index 69bf01f..69bf01f 100644
--- a/include/a.out.h
+++ b/include/linux/a.out.h
diff --git a/include/linux/config.dist.h b/include/linux/config.dist.h
index 4a84fbf..15b6e4b 100644
--- a/include/linux/config.dist.h
+++ b/include/linux/config.dist.h
@@ -17,7 +17,11 @@
#define CONFIG_SCSI_SEAGATE
#undef CONFIG_SCSI_ULTRASTOR
#define CONFIG_SCSI_ULTRASTOR
+#undef CONFIG_SCSI_7000FASST
+#define CONFIG_SCSI_7000FASST
+#undef CONFIG_BLK_DEV_HD
+#define CONFIG_BLK_DEV_HD
#undef CONFIG_BLK_DEV_SD
#define CONFIG_BLK_DEV_SD
#undef CONFIG_BLK_DEV_ST
diff --git a/include/linux/config.h b/include/linux/config.h
index 0e5f4cd..ef79c38 100644
--- a/include/linux/config.h
+++ b/include/linux/config.h
@@ -66,9 +66,11 @@
#undef HD_TYPE
+#define CONFIG_BLK_DEV_HD
#undef CONFIG_BLK_DEV_SD
#undef CONFIG_BLK_DEV_ST
+
/*
Choose supported SCSI adapters here.
*/
@@ -80,23 +82,25 @@
#undef CONFIG_SCSI_FUTURE_DOMAIN
#undef CONFIG_SCSI_SEAGATE
#undef CONFIG_SCSI_ULTRASTOR
+#undef CONFIG_SCSI_7000FASST
-#if defined(CONFIG_BLK_DEV_SD) || defined(CONFIG_BLK_DEV_ST)
- #ifndef CONFIG_SCSI
- #define CONFIG_SCSI
- #endif
-
- #if !defined(CONFIG_SCSI_AHA1542) && !defined(CONFIG_SCSI_CSC) && !defined(CONFIG_SCSI_DTC) && \
- !defined(CONFIG_SCSI_FUTURE_DOMAIN) && !defined(CONFIG_SCSI_SEAGATE) && !defined(CONFIG_SCSI_ULTRASTOR)
+#if defined(CONFIG_BLK_DEV_SD) || defined(CONFIG_BLK_DEV_CD) || \
+defined(CONFIG_CHR_DEV_ST)
+#ifndef CONFIG_SCSI
+ #define CONFIG_SCSI
+#endif
- #error Error : SCSI devices enabled, but no low level drivers have been enabled.
- #endif
+#if !defined(CONFIG_SCSI_AHA1542) && !defined(CONFIG_SCSI_CSC) && !defined(CONFIG_SCSI_DTC) && \
+ !defined(CONFIG_SCSI_FUTURE_DOMAIN) && !defined(CONFIG_SCSI_SEAGATE) && !defined(CONFIG_SCSI_ULTRASTOR) && \
+ !defined(CONFIG_SCSI_7000FASST)
+#error Error : SCSI devices enabled, but no low level drivers have been enabled.
+#endif
#endif
#ifdef CONFIG_DISTRIBUTION
- #include <linux/config.dist.h>
+#include <linux/config.dist.h>
#else
- #include <linux/config.site.h>
+#include <linux/config.site.h>
#endif
/*
diff --git a/include/linux/config_rel.h b/include/linux/config_rel.h
index c286ac2..bd66dee 100644
--- a/include/linux/config_rel.h
+++ b/include/linux/config_rel.h
@@ -1 +1 @@
-#define UTS_RELEASE "0.96b-63"
+#define UTS_RELEASE "0.97-11"
diff --git a/include/linux/config_ver.h b/include/linux/config_ver.h
index d32d8b2..e09eeab 100644
--- a/include/linux/config_ver.h
+++ b/include/linux/config_ver.h
@@ -1 +1 @@
-#define UTS_VERSION "07/04/92"
+#define UTS_VERSION "08/01/92"
diff --git a/include/sys/dirent.h b/include/linux/dirent.h
index 2df2c83..01d16c8 100644
--- a/include/sys/dirent.h
+++ b/include/linux/dirent.h
@@ -1,8 +1,5 @@
-#ifndef _SYS_DIRENT_H
-#define _SYS_DIRENT_H
-
-#include <limits.h>
-#include <sys/types.h>
+#ifndef _LINUX_DIRENT_H
+#define _LINUX_DIRENT_H
struct dirent {
long d_ino;
diff --git a/include/linux/errno.h b/include/linux/errno.h
new file mode 100644
index 0000000..420d5ff
--- /dev/null
+++ b/include/linux/errno.h
@@ -0,0 +1,130 @@
+#ifndef _LINUX_ERRNO_H
+#define _LINUX_ERRNO_H
+
+#define EPERM 1 /* Operation not permitted */
+#define ENOENT 2 /* No such file or directory */
+#define ESRCH 3 /* No such process */
+#define EINTR 4 /* Interrupted system call */
+#define EIO 5 /* I/O error */
+#define ENXIO 6 /* No such device or address */
+#define E2BIG 7 /* Arg list too long */
+#define ENOEXEC 8 /* Exec format error */
+#define EBADF 9 /* Bad file number */
+#define ECHILD 10 /* No child processes */
+#define EAGAIN 11 /* Try again */
+#define ENOMEM 12 /* Out of memory */
+#define EACCES 13 /* Permission denied */
+#define EFAULT 14 /* Bad address */
+#define ENOTBLK 15 /* Block device required */
+#define EBUSY 16 /* Device or resource busy */
+#define EEXIST 17 /* File exists */
+#define EXDEV 18 /* Cross-device link */
+#define ENODEV 19 /* No such device */
+#define ENOTDIR 20 /* Not a directory */
+#define EISDIR 21 /* Is a directory */
+#define EINVAL 22 /* Invalid argument */
+#define ENFILE 23 /* File table overflow */
+#define EMFILE 24 /* Too many open files */
+#define ENOTTY 25 /* Not a typewriter */
+#define ETXTBSY 26 /* Text file busy */
+#define EFBIG 27 /* File too large */
+#define ENOSPC 28 /* No space left on device */
+#define ESPIPE 29 /* Illegal seek */
+#define EROFS 30 /* Read-only file system */
+#define EMLINK 31 /* Too many links */
+#define EPIPE 32 /* Broken pipe */
+#define EDOM 33 /* Math argument out of domain of func */
+#define ERANGE 34 /* Math result not representable */
+#define EDEADLK 35 /* Resource deadlock would occur */
+#define ENAMETOOLONG 36 /* File name too long */
+#define ENOLCK 37 /* No record locks available */
+#define ENOSYS 38 /* Function not implemented */
+#define ENOTEMPTY 39 /* Directory not empty */
+#define ELOOP 40 /* Too many symbolic links encountered */
+#define EWOULDBLOCK 41 /* Operation would block */
+#define ENOMSG 42 /* No message of desired type */
+#define EIDRM 43 /* Identifier removed */
+#define ECHRNG 44 /* Channel number out of range */
+#define EL2NSYNC 45 /* Level 2 not synchronized */
+#define EL3HLT 46 /* Level 3 halted */
+#define EL3RST 47 /* Level 3 reset */
+#define ELNRNG 48 /* Link number out of range */
+#define EUNATCH 49 /* Protocol driver not attached */
+#define ENOCSI 50 /* No CSI structure available */
+#define EL2HLT 51 /* Level 2 halted */
+#define EBADE 52 /* Invalid exchange */
+#define EBADR 53 /* Invalid request descriptor */
+#define EXFULL 54 /* Exchange full */
+#define ENOANO 55 /* No anode */
+#define EBADRQC 56 /* Invalid request code */
+#define EBADSLT 57 /* Invalid slot */
+#define EDEADLOCK 58 /* File locking deadlock error */
+#define EBFONT 59 /* Bad font file format */
+#define ENOSTR 60 /* Device not a stream */
+#define ENODATA 61 /* No data available */
+#define ETIME 62 /* Timer expired */
+#define ENOSR 63 /* Out of streams resources */
+#define ENONET 64 /* Machine is not on the network */
+#define ENOPKG 65 /* Package not installed */
+#define EREMOTE 66 /* Object is remote */
+#define ENOLINK 67 /* Link has been severed */
+#define EADV 68 /* Advertise error */
+#define ESRMNT 69 /* Srmount error */
+#define ECOMM 70 /* Communication error on send */
+#define EPROTO 71 /* Protocol error */
+#define EMULTIHOP 72 /* Multihop attempted */
+#define EDOTDOT 73 /* RFS specific error */
+#define EBADMSG 74 /* Not a data message */
+#define EOVERFLOW 75 /* Value too large for defined data type */
+#define ENOTUNIQ 76 /* Name not unique on network */
+#define EBADFD 77 /* File descriptor in bad state */
+#define EREMCHG 78 /* Remote address changed */
+#define ELIBACC 79 /* Can not access a needed shared library */
+#define ELIBBAD 80 /* Accessing a corrupted shared library */
+#define ELIBSCN 81 /* .lib section in a.out corrupted */
+#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
+#define ELIBEXEC 83 /* Cannot exec a shared library directly */
+#define EILSEQ 84 /* Illegal byte sequence */
+#define ERESTART 85 /* Interrupted system call should be restarted */
+#define ESTRPIPE 86 /* Streams pipe error */
+#define EUSERS 87 /* Too many users */
+#define ENOTSOCK 88 /* Socket operation on non-socket */
+#define EDESTADDRREQ 89 /* Destination address required */
+#define EMSGSIZE 90 /* Message too long */
+#define EPROTOTYPE 91 /* Protocol wrong type for socket */
+#define ENOPROTOOPT 92 /* Protocol not available */
+#define EPROTONOSUPPORT 93 /* Protocol not supported */
+#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
+#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
+#define EPFNOSUPPORT 96 /* Protocol family not supported */
+#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
+#define EADDRINUSE 98 /* Address already in use */
+#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
+#define ENETDOWN 100 /* Network is down */
+#define ENETUNREACH 101 /* Network is unreachable */
+#define ENETRESET 102 /* Network dropped connection because of reset */
+#define ECONNABORTED 103 /* Software caused connection abort */
+#define ECONNRESET 104 /* Connection reset by peer */
+#define ENOBUFS 105 /* No buffer space available */
+#define EISCONN 106 /* Transport endpoint is already connected */
+#define ENOTCONN 107 /* Transport endpoint is not connected */
+#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
+#define ETOOMANYREFS 109 /* Too many references: cannot splice */
+#define ETIMEDOUT 110 /* Connection timed out */
+#define ECONNREFUSED 111 /* Connection refused */
+#define EHOSTDOWN 112 /* Host is down */
+#define EHOSTUNREACH 113 /* No route to host */
+#define EALREADY 114 /* Operation already in progress */
+#define EINPROGRESS 115 /* Operation now in progress */
+#define ESTALE 116 /* Stale NFS file handle */
+#define EUCLEAN 117 /* Structure needs cleaning */
+#define ENOTNAM 118 /* Not a XENIX named type file */
+#define ENAVAIL 119 /* No XENIX semaphores available */
+#define EISNAM 120 /* Is a named type file */
+#define EREMOTEIO 121 /* Remote I/O error */
+
+/* Should never be seen by user programs */
+#define ERESTARTSYS 512
+#define ERESTARTNOINTR 513
+
+#endif
diff --git a/include/linux/ext_fs.h b/include/linux/ext_fs.h
index 0877bdb..c4b3cf4 100644
--- a/include/linux/ext_fs.h
+++ b/include/linux/ext_fs.h
@@ -1,11 +1,9 @@
-/*
- * The ext filesystem constants/structures
- */
-
#ifndef _EXT_FS_H
#define _EXT_FS_H
-#include <sys/types.h>
+/*
+ * The ext filesystem constants/structures
+ */
/*
* Free blocks/inodes management style
diff --git a/include/linux/ext_fs_sb.h b/include/linux/ext_fs_sb.h
new file mode 100644
index 0000000..8aff1ff
--- /dev/null
+++ b/include/linux/ext_fs_sb.h
@@ -0,0 +1,19 @@
+#ifndef _EXT_FS_SB
+#define _EXT_FS_SB
+
+/*
+ * extended-fs super-block data in memory (same as minix: has to change)
+ */
+struct ext_sb_info {
+ unsigned long s_ninodes;
+ unsigned long s_nzones;
+ unsigned long s_imap_blocks;
+ unsigned long s_zmap_blocks;
+ unsigned long s_firstdatazone;
+ unsigned long s_log_zone_size;
+ unsigned long s_max_size;
+ struct buffer_head * s_imap[8];
+ struct buffer_head * s_zmap[8];
+};
+
+#endif
diff --git a/include/linux/fcntl.h b/include/linux/fcntl.h
index dcf49e3..e477370 100644
--- a/include/linux/fcntl.h
+++ b/include/linux/fcntl.h
@@ -1,8 +1,6 @@
#ifndef _FCNTL_H
#define _FCNTL_H
-#include <sys/types.h>
-
/* open/fcntl - O_SYNC isn't implemented yet */
#define O_ACCMODE 0003
#define O_RDONLY 00
diff --git a/include/linux/fd.h b/include/linux/fd.h
index d490194..4828db0 100644
--- a/include/linux/fd.h
+++ b/include/linux/fd.h
@@ -1,5 +1,5 @@
-#ifndef _FD_H
-#define _FD_H
+#ifndef _LINUX_FD_H
+#define _LINUX_FD_H
#define FDCLRPRM 0 /* clear user-defined parameters */
#define FDSETPRM 1 /* set user-defined parameters for current media */
@@ -10,6 +10,7 @@
#define FDFMTBEG 6 /* begin formatting a disk */
#define FDFMTTRK 7 /* format the specified track */
#define FDFMTEND 8 /* end formatting a disk */
+#define FDSETEMSGTRESH 10 /* set fdc error reporting treshold */
#define FD_FILL_BYTE 0xF6 /* format fill byte */
@@ -20,13 +21,20 @@
#define FORMAT_ERROR 4 /* formatting error */
struct floppy_struct {
- unsigned int size, sect, head, track, stretch;
- unsigned char gap,rate,spec1,fmt_gap;
- char *name; /* used only for predefined formats */
+ unsigned int size, /* nr of 512-byte sectors total */
+ sect, /* sectors per track */
+ head, /* nr of heads */
+ track, /* nr of tracks */
+ stretch; /* !=0 means double track steps */
+ unsigned char gap, /* gap1 size */
+ rate, /* data rate. |= 0x40 for perpendicular */
+ spec1, /* stepping rate, head unload time */
+ fmt_gap; /* gap2 size */
+ char * name; /* used only for predefined formats */
};
struct format_descr {
- unsigned int device,head,track;
+ unsigned int device,head,track;
};
#endif
diff --git a/include/linux/fdreg.h b/include/linux/fdreg.h
index 77a270e..6d172b6 100644
--- a/include/linux/fdreg.h
+++ b/include/linux/fdreg.h
@@ -1,10 +1,10 @@
+#ifndef _LINUX_FDREG_H
+#define _LINUX_FDREG_H
/*
* This file contains some defines for the floppy disk controller.
* Various sources. Mostly "IBM Microcomputers: A Programmers
* Handbook", Sanches and Canton.
*/
-#ifndef _FDREG_H
-#define _FDREG_H
extern int ticks_to_floppy_on(unsigned int nr);
extern void floppy_on(unsigned int nr);
@@ -57,16 +57,23 @@ extern void floppy_deselect(unsigned int nr);
#define ST3_WP 0x40 /* Write Protect */
/* Values for FD_COMMAND */
-#define FD_RECALIBRATE 0x07 /* move to track 0 */
-#define FD_SEEK 0x0F /* seek track */
-#define FD_READ 0xE6 /* read with MT, MFM, SKip deleted */
-#define FD_WRITE 0xC5 /* write with MT, MFM */
-#define FD_SENSEI 0x08 /* Sense Interrupt Status */
-#define FD_SPECIFY 0x03 /* specify HUT etc */
-#define FD_FORMAT 0x4D /* format one track */
+#define FD_RECALIBRATE 0x07 /* move to track 0 */
+#define FD_SEEK 0x0F /* seek track */
+#define FD_READ 0xE6 /* read with MT, MFM, SKip deleted */
+#define FD_WRITE 0xC5 /* write with MT, MFM */
+#define FD_SENSEI 0x08 /* Sense Interrupt Status */
+#define FD_SPECIFY 0x03 /* specify HUT etc */
+#define FD_FORMAT 0x4D /* format one track */
+#define FD_VERSION 0x10 /* get version code */
+#define FD_CONFIGURE 0x13 /* configure FIFO operation */
+#define FD_PERPENDICULAR 0x12 /* perpendicular r/w mode */
/* DMA commands */
#define DMA_READ 0x46
#define DMA_WRITE 0x4A
+/* FDC version return types */
+#define FDC_TYPE_STD 0x80 /* normal 8272A clone FDC */
+#define FDC_TYPE_82077 0x90 /* FIFO + perpendicular support */
+
#endif
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 925f64a..86cb92a 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1,17 +1,16 @@
+#ifndef _LINUX_FS_H
+#define _LINUX_FS_H
+
/*
* This file has definitions for some important file table
* structures etc.
*/
-#ifndef _FS_H
-#define _FS_H
-
#include <linux/limits.h>
#include <linux/wait.h>
-
-#include <sys/types.h>
-#include <sys/dirent.h>
-#include <sys/vfs.h>
+#include <linux/types.h>
+#include <linux/dirent.h>
+#include <linux/vfs.h>
/* devices are as follows: (same as minix, so we can use the minix
* file system. These are major numbers.)
@@ -39,7 +38,7 @@
#define READA 2 /* read-ahead - don't pause */
#define WRITEA 3 /* "write-ahead" - silly, but somewhat useful */
-void buffer_init(long buffer_end);
+extern void buffer_init(void);
#define MAJOR(a) (((unsigned)(a))>>8)
#define MINOR(a) ((a)&0xff)
@@ -96,18 +95,20 @@ typedef char buffer_block[BLOCK_SIZE];
struct buffer_head {
char * b_data; /* pointer to data block (1024 bytes) */
+ unsigned long b_size; /* block size */
unsigned long b_blocknr; /* block number */
unsigned short b_dev; /* device (0 = free) */
+ unsigned short b_count; /* users using this block */
unsigned char b_uptodate;
unsigned char b_dirt; /* 0-clean,1-dirty */
- unsigned char b_count; /* users using this block */
unsigned char b_lock; /* 0 - ok, 1 -locked */
struct wait_queue * b_wait;
- struct buffer_head * b_prev;
+ struct buffer_head * b_prev; /* doubly linked list of hash-queue */
struct buffer_head * b_next;
- struct buffer_head * b_prev_free;
+ struct buffer_head * b_prev_free; /* doubly linked list of buffers */
struct buffer_head * b_next_free;
- struct buffer_head * b_reqnext;
+ struct buffer_head * b_this_page; /* circular list of buffers in one page */
+ struct buffer_head * b_reqnext; /* request queue */
};
struct inode {
@@ -148,29 +149,28 @@ struct file {
off_t f_pos;
};
+#include <linux/minix_fs_sb.h>
+#include <linux/ext_fs_sb.h>
+#include <linux/msdos_fs_sb.h>
+
struct super_block {
- unsigned long s_ninodes;
- unsigned long s_nzones;
- unsigned long s_imap_blocks;
- unsigned long s_zmap_blocks;
- unsigned long s_firstdatazone;
- unsigned long s_log_zone_size;
- unsigned long s_max_size;
- unsigned short s_magic;
-/* These are only in memory */
- struct buffer_head * s_imap[8];
- struct buffer_head * s_zmap[8];
unsigned short s_dev;
- struct inode * s_covered;
- struct inode * s_mounted;
- unsigned long s_time;
- struct wait_queue * s_wait;
+ unsigned long s_blocksize;
unsigned char s_lock;
unsigned char s_rd_only;
unsigned char s_dirt;
- /* TUBE */
struct super_operations *s_op;
- int s_flags;
+ unsigned long s_flags;
+ unsigned long s_magic;
+ unsigned long s_time;
+ struct inode * s_covered;
+ struct inode * s_mounted;
+ struct wait_queue * s_wait;
+ union {
+ struct minix_sb_info minix_sb;
+ struct ext_sb_info ext_sb;
+ struct msdos_sb_info msdos_sb;
+ } u;
};
struct file_operations {
@@ -223,8 +223,12 @@ extern struct file_system_type *get_fs_type(char *name);
extern struct inode inode_table[NR_INODE];
extern struct file file_table[NR_FILE];
extern struct super_block super_block[NR_SUPER];
-extern struct buffer_head * start_buffer;
+
+extern void grow_buffers(int size);
+extern int shrink_buffers(void);
+
extern int nr_buffers;
+extern int nr_buffer_heads;
extern void check_disk_change(int dev);
extern void invalidate_inodes(int dev);
@@ -247,13 +251,14 @@ extern void iput(struct inode * inode);
extern struct inode * iget(int dev,int nr);
extern struct inode * get_empty_inode(void);
extern struct inode * get_pipe_inode(void);
-extern struct buffer_head * get_hash_table(int dev, int block);
-extern struct buffer_head * getblk(int dev, int block);
+extern struct file * get_empty_filp(void);
+extern struct buffer_head * get_hash_table(int dev, int block, int size);
+extern struct buffer_head * getblk(int dev, int block, int size);
extern void ll_rw_block(int rw, 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);
-extern struct buffer_head * bread(int dev,int block);
+extern struct buffer_head * bread(int dev, int block, int size);
extern void bread_page(unsigned long addr,int dev,int b[4]);
extern struct buffer_head * breada(int dev,int block,...);
extern int sync_dev(int dev);
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
new file mode 100644
index 0000000..c1d1b4e
--- /dev/null
+++ b/include/linux/genhd.h
@@ -0,0 +1,52 @@
+#ifndef _GENHD_H
+#define _GENHD_H
+
+/*
+ * genhd.h Copyright (C) 1992 Drew Eckhardt
+ * Generic hard disk header file by
+ * Drew Eckhardt
+ *
+ * <drew@colorado.edu>
+ */
+
+#define EXTENDED_PARTITION 5
+
+struct partition {
+ unsigned char boot_ind; /* 0x80 - active */
+ unsigned char head; /* starting head */
+ unsigned char sector; /* starting sector */
+ unsigned char cyl; /* starting cylinder */
+ unsigned char sys_ind; /* What partition type */
+ unsigned char end_head; /* end head */
+ unsigned char end_sector; /* end sector */
+ unsigned char end_cyl; /* end cylinder */
+ unsigned int start_sect; /* starting sector counting from 0 */
+ unsigned int nr_sects; /* nr of sectors in partition */
+};
+
+struct hd_struct {
+ long start_sect;
+ long nr_sects;
+};
+
+struct gendisk {
+ int major; /* major number of driver */
+ char *major_name; /* name of major driver */
+ int minor_shift; /* number of times minor is shifted to
+ get real minor */
+ int max_p; /* maximum partitions per device */
+ int max_nr; /* maximum number of real devices */
+
+ void (*init)(void); /* Initialization called before we do our thing */
+ struct hd_struct *part; /* partition table */
+ int *sizes; /* block sizes */
+ int nr_real; /* number of real devices */
+
+ void *real_devices; /* internal use */
+ struct gendisk *next;
+};
+
+extern int NR_GENDISKS; /* total */
+extern struct gendisk *gendisk_head; /* linked list of disks */
+
+#endif
diff --git a/include/linux/hdreg.h b/include/linux/hdreg.h
index 67e5386..28e3054 100644
--- a/include/linux/hdreg.h
+++ b/include/linux/hdreg.h
@@ -1,10 +1,11 @@
+#ifndef _LINUX_HDREG_H
+#define _LINUX_HDREG_H
+
/*
* This file contains some defines for the AT-hd-controller.
* Various sources. Check out some definitions (see comments with
* a ques).
*/
-#ifndef _HDREG_H
-#define _HDREG_H
/* Hd controller regs. Ref: IBM AT Bios-listing */
#define HD_DATA 0x1f0 /* _CTL when writing */
@@ -49,20 +50,6 @@
#define ECC_ERR 0x40 /* ? */
#define BBD_ERR 0x80 /* ? */
-#define EXTENDED_PARTITION 5
-
-struct partition {
- unsigned char boot_ind; /* 0x80 - active */
- unsigned char head; /* starting head */
- unsigned char sector; /* starting sector */
- unsigned char cyl; /* starting cylinder */
- unsigned char sys_ind; /* What partition type */
- unsigned char end_head; /* end head */
- unsigned char end_sector; /* end sector */
- unsigned char end_cyl; /* end cylinder */
- unsigned int start_sect; /* starting sector counting from 0 */
- unsigned int nr_sects; /* nr of sectors in partition */
-};
#define HDIO_REQ 0x301
struct hd_geometry {
diff --git a/include/linux/head.h b/include/linux/head.h
index db3dda2..b871742 100644
--- a/include/linux/head.h
+++ b/include/linux/head.h
@@ -1,5 +1,5 @@
-#ifndef _HEAD_H
-#define _HEAD_H
+#ifndef _LINUX_HEAD_H
+#define _LINUX_HEAD_H
typedef struct desc_struct {
unsigned long a,b;
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index ef27d83..cf77d54 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -1,6 +1,10 @@
+#ifndef _LINUX_KERNEL_H
+#define _LINUX_KERNEL_H
+
/*
* 'kernel.h' contains some often-used function prototypes etc
*/
+
void verify_area(void * addr,int count);
volatile void panic(const char * str);
volatile void do_exit(long error_code);
@@ -19,3 +23,4 @@ void free_s(void * obj, int size);
*/
#define suser() (current->euid == 0)
+#endif
diff --git a/include/linux/limits.h b/include/linux/limits.h
index 97450b7..9b04df7 100644
--- a/include/linux/limits.h
+++ b/include/linux/limits.h
@@ -1,16 +1,27 @@
#ifndef _LINUX_LIMITS_H
#define _LINUX_LIMITS_H
+#define NAME_MAX 255
+
#define NR_OPEN 32
#define NR_INODE 128
#define NR_FILE 128
#define NR_SUPER 8
#define NR_HASH 307
-#define NR_BUFFERS nr_buffers
#define BLOCK_SIZE 1024
#define BLOCK_SIZE_BITS 10
#define MAX_CHRDEV 16
#define MAX_BLKDEV 16
+#define NGROUPS_MAX 32 /* supplemental group IDs are available */
+#define ARG_MAX 40960 /* # bytes of args + environ for exec() */
+#define CHILD_MAX 999 /* no limit :-) */
+#define OPEN_MAX 32 /* # 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 */
+#define NAME_MAX 255 /* # chars in a file name */
+#define PATH_MAX 1024 /* # chars in a path name */
+#define PIPE_BUF 4095 /* # bytes in atomic write to a pipe */
#endif
diff --git a/include/linux/lp.h b/include/linux/lp.h
index 785b17d..2fef688 100644
--- a/include/linux/lp.h
+++ b/include/linux/lp.h
@@ -1,10 +1,14 @@
+#ifndef _LINUX_LP_H
+#define _LINUX_LP_H
+
/*
$Header: /usr/src/linux/include/linux/lp.h,v 1.2 1992/01/21 23:59:24 james_r_wiegand Exp james_r_wiegand $
*/
-#include <errno.h>
+#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/sched.h>
+
#include <asm/io.h>
#include <asm/segment.h>
@@ -37,9 +41,6 @@ $Header: /usr/src/linux/include/linux/lp.h,v 1.2 1992/01/21 23:59:24 james_r_wie
since we are dealing with a horribly slow device
I don't see the need for a queue
*/
-#ifndef __LP_C__
- extern
-#endif
struct lp_struct {
int base;
int flags;
@@ -52,9 +53,6 @@ struct lp_struct {
* please let me know if you have different equipment
* if you have more than 3 printers, remember to increase LP_NO
*/
-#ifndef __LP_C__
- extern
-#endif
struct lp_struct lp_table[] = {
{ 0x3bc, 0, },
{ 0x378, 0, },
@@ -101,3 +99,5 @@ struct lp_struct lp_table[] = {
*/
extern long lp_init(long);
+
+#endif
diff --git a/include/linux/math_emu.h b/include/linux/math_emu.h
index 64e734c..827e9c9 100644
--- a/include/linux/math_emu.h
+++ b/include/linux/math_emu.h
@@ -1,8 +1,3 @@
-/*
- * linux/include/linux/math_emu.h
- *
- * (C) 1991 Linus Torvalds
- */
#ifndef _LINUX_MATH_EMU_H
#define _LINUX_MATH_EMU_H
diff --git a/include/linux/minix_fs.h b/include/linux/minix_fs.h
index 99b9f45..1205d6e 100644
--- a/include/linux/minix_fs.h
+++ b/include/linux/minix_fs.h
@@ -1,11 +1,9 @@
-/*
- * The minix filesystem constants/structures
- */
-
#ifndef _MINIX_FS_H
#define _MINIX_FS_H
-#include <sys/types.h>
+/*
+ * The minix filesystem constants/structures
+ */
#define MINIX_NAME_LEN 14
#define MINIX_ROOT_INO 1
@@ -27,6 +25,9 @@ struct minix_inode {
unsigned short i_zone[9];
};
+/*
+ * minix super-block data on disk
+ */
struct minix_super_block {
unsigned short s_ninodes;
unsigned short s_nzones;
diff --git a/include/linux/minix_fs_sb.h b/include/linux/minix_fs_sb.h
new file mode 100644
index 0000000..18de6ef
--- /dev/null
+++ b/include/linux/minix_fs_sb.h
@@ -0,0 +1,19 @@
+#ifndef _MINIX_FS_SB
+#define _MINIX_FS_SB
+
+/*
+ * minix super-block data in memory
+ */
+struct minix_sb_info {
+ unsigned long s_ninodes;
+ unsigned long s_nzones;
+ unsigned long s_imap_blocks;
+ unsigned long s_zmap_blocks;
+ unsigned long s_firstdatazone;
+ unsigned long s_log_zone_size;
+ unsigned long s_max_size;
+ struct buffer_head * s_imap[8];
+ struct buffer_head * s_zmap[8];
+};
+
+#endif
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 4b3b61b..256f032 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -5,11 +5,49 @@
#include <linux/fs.h>
#include <linux/kernel.h>
-#include <signal.h>
+#include <linux/signal.h>
+
+/*
+ * 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 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()
extern unsigned int swap_device;
extern struct inode * swap_file;
+extern int nr_free_pages;
+
extern void rw_swap_page(int rw, unsigned int nr, char * buf);
#define read_swap_page(nr,buf) \
@@ -19,7 +57,7 @@ extern void rw_swap_page(int rw, unsigned int nr, char * buf);
/* memory.c */
-extern unsigned long get_free_page(void);
+extern unsigned long get_free_page(int priority);
extern unsigned long put_dirty_page(unsigned long page,unsigned long address);
extern void free_page(unsigned long addr);
extern int free_page_tables(unsigned long from,unsigned long size);
@@ -27,38 +65,34 @@ extern int copy_page_tables(unsigned long from,unsigned long to,long size);
extern int unmap_page_range(unsigned long from, unsigned long size);
extern int remap_page_range(unsigned long from, unsigned long to, unsigned long size,
int permiss);
-extern void un_wp_page(unsigned long * table_entry);
-extern void do_wp_page(unsigned long error_code,unsigned long address);
extern void write_verify(unsigned long address);
+
+extern void do_wp_page(unsigned long error_code, unsigned long address,
+ struct task_struct *tsk, unsigned long user_esp);
extern void do_no_page(unsigned long error_code, unsigned long address,
struct task_struct *tsk, unsigned long user_esp);
-extern void mem_init(long start_mem, long end_mem);
+
+extern unsigned long mem_init(unsigned long start_mem, unsigned long end_mem);
extern void show_mem(void);
extern void do_page_fault(unsigned long *esp, unsigned long error_code);
+extern void oom(struct task_struct * task);
/* swap.c */
-extern void swap_free(int page_nr);
+extern void swap_free(unsigned int page_nr);
extern void swap_in(unsigned long *table_ptr);
-extern inline volatile void oom(void)
-{
- printk("out of memory\n\r");
- do_exit(SIGSEGV);
-}
-
#define invalidate() \
__asm__("movl %%eax,%%cr3"::"a" (0))
-/* these are not to be changed without changing head.s etc */
-#define LOW_MEM 0x100000
-extern unsigned long HIGH_MEMORY;
-#define PAGING_MEMORY (15*1024*1024)
-#define PAGING_PAGES (PAGING_MEMORY>>12)
-#define MAP_NR(addr) (((addr)-LOW_MEM)>>12)
+extern unsigned long low_memory;
+extern unsigned long high_memory;
+extern unsigned long paging_pages;
+
+#define MAP_NR(addr) (((addr)-low_memory)>>12)
#define USED 100
-extern unsigned char mem_map [ PAGING_PAGES ];
+extern unsigned char * mem_map;
#define PAGE_DIRTY 0x40
#define PAGE_ACCESSED 0x20
@@ -66,4 +100,8 @@ extern unsigned char mem_map [ PAGING_PAGES ];
#define PAGE_RW 0x02
#define PAGE_PRESENT 0x01
+#define GFP_BUFFER 0x00
+#define GFP_USER 0x01
+#define GFP_KERNEL 0x02
+
#endif
diff --git a/include/linux/mouse.h b/include/linux/mouse.h
index 913123c..4723a54 100644
--- a/include/linux/mouse.h
+++ b/include/linux/mouse.h
@@ -1,3 +1,6 @@
+#ifndef _LINUX_MOUSE_H
+#define _LINUX_MOUSE_H
+
/*
* linux/include/linux/mouse.h: header file for Logitech Bus Mouse driver
* by James Banks
@@ -11,9 +14,6 @@
*
*/
-#ifndef _MOUSE_H
-#define _MOUSE_H
-
#define MOUSE_IRQ 5
#define MSE_DATA_PORT 0x23c
diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h
index 719dcc3..0eebbf4 100644
--- a/include/linux/msdos_fs.h
+++ b/include/linux/msdos_fs.h
@@ -1,14 +1,13 @@
+#ifndef _MSDOS_FS_H
+#define _MSDOS_FS_H
+
/*
* The MS-DOS filesystem constants/structures
*/
-#ifndef _MSDOS_FS_H
-#define _MSDOS_FS_H
-
-#include <sys/types.h>
#include <linux/fs.h>
-#define MSDOS_ROOT_INO 1
+#define MSDOS_ROOT_INO 1 /* == MINIX_ROOT_INO */
#define SECTOR_SIZE 512 /* sector size (bytes) */
#define SECTOR_BITS 9 /* log2(SECTOR_SIZE) */
#define MSDOS_DPB (MSDOS_DPS*2) /* dir entries per block */
@@ -29,7 +28,7 @@
#define ATTR_ARCH 32 /* archived */
#define ATTR_NONE 0 /* no attribute bits */
-#define ATTR_UNUSED (ATTR_VOLUME | ATTR_ARCH | ATTR_SYS)
+#define ATTR_UNUSED (ATTR_VOLUME | ATTR_ARCH | ATTR_SYS | ATTR_HIDDEN)
/* attribute bits that are copied "as is" */
#define DELETED_FLAG 0xe5 /* marks file as deleted when in name[0] */
@@ -44,9 +43,7 @@
on */
#define D_BINARY 5 /* i_data[5]: file contains non-text data */
-#define SET_DIRTY(i) (i)->i_dirt = (i)->i_data[D_DIRT] = 1
-
-#define MSDOS_SB(s) ((struct msdos_sb_info *) s)
+#define MSDOS_SB(s) (&((s)->u.msdos_sb))
#define MSDOS_NAME 11 /* maximum name length */
#define MSDOS_DOT ". " /* ".", padded to MSDOS_NAME chars */
@@ -69,20 +66,6 @@ struct msdos_boot_sector {
unsigned long total_sect; /* number of sectors (if sectors == 0) */
};
-struct msdos_sb_info { /* space in struct super_block is 28 bytes */
- unsigned short cluster_size; /* sectors/cluster */
- unsigned char fats,fat_bits; /* number of FATs, FAT bits (12 or 16) */
- unsigned short fat_start,fat_length; /* FAT start & length (sec.) */
- unsigned short dir_start,dir_entries; /* root dir start & entries */
- unsigned short data_start; /* first data sector */
- unsigned long clusters; /* number of clusters */
- uid_t fs_uid;
- gid_t fs_gid;
- unsigned short fs_umask;
- unsigned char name_check; /* r = releaxed, n = normal, s = strict */
- unsigned char conversion; /* b = binary, t = text, a = auto */
-}; /* 28 bytes */
-
struct msdos_dir_entry {
char name[8],ext[3]; /* name and extension */
unsigned char attr; /* attribute bits */
@@ -106,20 +89,19 @@ struct fat_cache {
/* Convert attribute bits and a mask to the UNIX mode. */
-#define MSDOS_MKMODE(a,m) (m & (a & ATTR_RO ? 0444 : (a & ATTR_HIDDEN ? 0 : \
- 0777)))
+#define MSDOS_MKMODE(a,m) (m & (a & ATTR_RO ? 0444 : 0777))
/* Convert the UNIX mode to MS-DOS attribute bits. */
-#define MSDOS_MKATTR(m) (!(m & 0600) ? ATTR_HIDDEN : ((m & 0600) == 0400 ? \
- ATTR_RO : ATTR_NONE))
+#define MSDOS_MKATTR(m) (!(m & 0200) ? ATTR_RO : ATTR_NONE)
static inline struct buffer_head *msdos_sread(int dev,int sector,void **start)
{
struct buffer_head *bh;
- if (!(bh = bread(dev,sector >> 1))) return NULL;
+ if (!(bh = bread(dev,sector >> 1, 1024)))
+ return NULL;
*start = bh->b_data+((sector & 1) << SECTOR_BITS);
return bh;
}
diff --git a/include/linux/msdos_fs_sb.h b/include/linux/msdos_fs_sb.h
new file mode 100644
index 0000000..c02db86
--- /dev/null
+++ b/include/linux/msdos_fs_sb.h
@@ -0,0 +1,18 @@
+#ifndef _MSDOS_FS_SB
+#define _MSDOS_FS_SB
+
+struct msdos_sb_info { /* space in struct super_block is 28 bytes */
+ unsigned short cluster_size; /* sectors/cluster */
+ unsigned char fats,fat_bits; /* number of FATs, FAT bits (12 or 16) */
+ unsigned short fat_start,fat_length; /* FAT start & length (sec.) */
+ unsigned short dir_start,dir_entries; /* root dir start & entries */
+ unsigned short data_start; /* first data sector */
+ unsigned long clusters; /* number of clusters */
+ uid_t fs_uid;
+ gid_t fs_gid;
+ unsigned short fs_umask;
+ unsigned char name_check; /* r = relaxed, n = normal, s = strict */
+ unsigned char conversion; /* b = binary, t = text, a = auto */
+};
+
+#endif
diff --git a/include/sys/param.h b/include/linux/param.h
index c864701..c864701 100644
--- a/include/sys/param.h
+++ b/include/linux/param.h
diff --git a/include/sys/ptrace.h b/include/linux/ptrace.h
index 9d9defb..ad26e03 100644
--- a/include/sys/ptrace.h
+++ b/include/linux/ptrace.h
@@ -1,8 +1,8 @@
+#ifndef _LINUX_PTRACE_H
+#define _LINUX_PTRACE_H
/* ptrace.h */
/* structs and defines to help the user use the ptrace system call. */
-#ifndef _SYS_PTRACE_H
-#define _SYS_PTRACE_H
/* has the defines to get at the registers. */
#define PTRACE_TRACEME 0
@@ -64,4 +64,4 @@ struct pt_regs {
long ss;
};
-#endif /* _SYS_PTRACE_H */
+#endif
diff --git a/include/sys/resource.h b/include/linux/resource.h
index 3f34379..4fa0f41 100644
--- a/include/sys/resource.h
+++ b/include/linux/resource.h
@@ -1,10 +1,10 @@
+#ifndef _LINUX_RESOURCE_H
+#define _LINUX_RESOURCE_H
+
/*
* Resource control/accounting header file for linux
*/
-#ifndef _SYS_RESOURCE_H
-#define _SYS_RESOURCE_H
-
/*
* Definition of struct rusage taken from BSD 4.3 Reno
*
@@ -67,4 +67,4 @@ struct rlimit {
#define PRIO_PGRP 1
#define PRIO_USER 2
-#endif /* _SYS_RESOURCE_H */
+#endif
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 8065edd..5de4d65 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1,5 +1,5 @@
-#ifndef _SCHED_H
-#define _SCHED_H
+#ifndef _LINUX_SCHED_H
+#define _LINUX_SCHED_H
#define HZ 100
@@ -39,10 +39,10 @@
#include <linux/head.h>
#include <linux/fs.h>
#include <linux/mm.h>
-#include <sys/param.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <signal.h>
+#include <linux/signal.h>
+#include <linux/time.h>
+#include <linux/param.h>
+#include <linux/resource.h>
#if (NR_OPEN > 32)
#error "Currently the close-on-exec-flags and select masks are in one long, max 32 files/proc"
@@ -117,7 +117,8 @@ struct task_struct {
long blocked; /* bitmap of masked signals */
/* various fields */
int exit_code;
- int dumpable;
+ int dumpable:1;
+ int swappable:1;
unsigned long start_code,end_code,end_data,brk,start_stack;
long pid,pgrp,session,leader;
int groups[NGROUPS];
@@ -183,7 +184,7 @@ struct task_struct {
#define INIT_TASK \
/* state etc */ { 0,15,15, \
/* signals */ 0,{{},},0, \
-/* ec,brk... */ 0,0,0,0,0,0,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, \
diff --git a/include/signal.h b/include/linux/signal.h
index 00ef568..24f098f 100644
--- a/include/signal.h
+++ b/include/linux/signal.h
@@ -1,9 +1,6 @@
-#ifndef _SIGNAL_H
-#define _SIGNAL_H
+#ifndef _LINUX_SIGNAL_H
+#define _LINUX_SIGNAL_H
-#include <sys/types.h>
-
-typedef int sig_atomic_t;
typedef unsigned int sigset_t; /* 32 bits */
#define _NSIG 32
@@ -54,7 +51,6 @@ typedef unsigned int sigset_t; /* 32 bits */
#define SIGLOST 29
*/
-/* Ok, I haven't implemented sigactions, but trying to keep headers POSIX */
#define SA_NOCLDSTOP 1
#define SA_INTERRUPT 0x20000000
#define SA_NOMASK 0x40000000
@@ -68,11 +64,6 @@ typedef unsigned int sigset_t; /* 32 bits */
#define SIG_IGN ((void (*)(int))1) /* ignore signal */
#define SIG_ERR ((void (*)(int))-1) /* error return from signal */
-#ifdef notdef
-#define sigemptyset(mask) ((*(mask) = 0), 1)
-#define sigfillset(mask) ((*(mask) = ~0), 1)
-#endif
-
struct sigaction {
void (*sa_handler)(int);
sigset_t sa_mask;
@@ -80,25 +71,4 @@ struct sigaction {
void (*sa_restorer)(void);
};
-#ifdef __cplusplus
-extern "C" {
#endif
-
-void (*signal(int _sig, void (*_func)(int)))(int);
-int raise(int sig);
-int kill(pid_t pid, int sig);
-int sigaddset(sigset_t *mask, int signo);
-int sigdelset(sigset_t *mask, int signo);
-int sigemptyset(sigset_t *mask);
-int sigfillset(sigset_t *mask);
-int sigismember(sigset_t *mask, int signo); /* 1 - is, 0 - not, -1 error */
-int sigpending(sigset_t *set);
-int sigprocmask(int how, sigset_t *set, sigset_t *oldset);
-int sigsuspend(sigset_t *sigmask);
-int sigaction(int sig, struct sigaction *act, struct sigaction *oldact);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _SIGNAL_H */
diff --git a/include/sys/socket.h b/include/linux/socket.h
index 7d840a6..e07703e 100644
--- a/include/sys/socket.h
+++ b/include/linux/socket.h
@@ -1,5 +1,5 @@
-#ifndef _SOCKET_H
-#define _SOCKET_H
+#ifndef _LINUX_SOCKET_H
+#define _LINUX_SOCKET_H
struct sockaddr {
u_short sa_family; /* address family, AF_xxx */
@@ -27,13 +27,4 @@ struct sockaddr {
#define PF_UNIX AF_UNIX
#define PF_INET AF_INET
-int socket(int family, int type, int protocol);
-int socketpair(int family, int type, int protocol, int sockvec[2]);
-int bind(int sockfd, struct sockaddr *my_addr, int addrlen);
-int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);
-int listen(int sockfd, int backlog);
-int accept(int sockfd, struct sockaddr *peer, int *paddrlen);
-int getsockname(int sockfd, struct sockaddr *addr, int *paddrlen);
-int getpeername(int sockfd, struct sockaddr *peer, int *paddrlen);
-
-#endif /* _SOCKET_H */
+#endif
diff --git a/include/stddef.h b/include/linux/stddef.h
index 2828f8e..c6221e7 100644
--- a/include/stddef.h
+++ b/include/linux/stddef.h
@@ -1,10 +1,5 @@
-#ifndef _STDDEF_H
-#define _STDDEF_H
-
-#ifndef _PTRDIFF_T
-#define _PTRDIFF_T
-typedef long ptrdiff_t;
-#endif
+#ifndef _LINUX_STDDEF_H
+#define _LINUX_STDDEF_H
#ifndef _SIZE_T
#define _SIZE_T
@@ -14,5 +9,7 @@ typedef unsigned int size_t;
#undef NULL
#define NULL ((void *)0)
+#undef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+
#endif
diff --git a/include/linux/string.h b/include/linux/string.h
index 73c4ee2..cdff971 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -1,14 +1,10 @@
-#ifndef _STRING_H_
-#define _STRING_H_
-
-#include <sys/types.h>
+#ifndef _LINUX_STRING_H_
+#define _LINUX_STRING_H_
#ifndef NULL
#define NULL ((void *) 0)
#endif
-extern char * strerror(int errno);
-
/*
* This string-include defines all string functions as inline
* functions. Use gcc. It also assumes ds=es=data space, this should be
@@ -18,7 +14,7 @@ extern char * strerror(int errno);
* set, making the functions fast and clean. String instructions have been
* used through-out, making for "slightly" unclear code :-)
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
extern inline char * strcpy(char * dest,const char *src)
diff --git a/include/linux/sys.h b/include/linux/sys.h
index 736ad01..deae36f 100644
--- a/include/linux/sys.h
+++ b/include/linux/sys.h
@@ -113,6 +113,7 @@ extern int sys_newlstat();
extern int sys_newfstat();
extern int sys_newuname();
extern int sys_iopl();
+extern int sys_vhangup();
fn_ptr sys_call_table[] = { sys_setup, sys_exit, sys_fork, sys_read,
sys_write, sys_open, sys_close, sys_waitpid, sys_creat, sys_link,
@@ -134,7 +135,7 @@ sys_swapon, sys_reboot, sys_readdir, sys_mmap, sys_munmap,
sys_truncate, sys_ftruncate, sys_fchmod, sys_fchown, sys_getpriority,
sys_setpriority, sys_profil, sys_statfs, sys_fstatfs, sys_ioperm,
sys_socketcall, sys_syslog, sys_setitimer, sys_getitimer, sys_newstat,
-sys_newlstat, sys_newfstat, sys_newuname, sys_iopl };
+sys_newlstat, sys_newfstat, sys_newuname, sys_iopl, sys_vhangup };
/* So we don't have to do any more manual updating.... */
int NR_syscalls = sizeof(sys_call_table)/sizeof(fn_ptr);
diff --git a/include/termios.h b/include/linux/termios.h
index da7b09a..372cda1 100644
--- a/include/termios.h
+++ b/include/linux/termios.h
@@ -1,7 +1,5 @@
-#ifndef _TERMIOS_H
-#define _TERMIOS_H
-
-#include <sys/types.h>
+#ifndef _LINUX_TERMIOS_H
+#define _LINUX_TERMIOS_H
/* 0x54 is just a magic number to make these relatively uniqe ('T') */
@@ -37,6 +35,17 @@
#define TIOCCONS 0x541D
#define TIOCGSERIAL 0x541E
#define TIOCSSERIAL 0x541F
+#define TIOCPKT 0x5420
+#define FIONBIO 0x5421
+#define TIOCNOTTY 0x5422
+
+/* Used for packet mode */
+#define TIOCPKT_FLUSHREAD 1
+#define TIOCPKT_FLUSHWRITE 2
+#define TIOCPKT_STOP 4
+#define TIOCPKT_START 8
+#define TIOCPKT_DOSTOP 16
+#define TIOCPKT_NOSTOP 32
struct winsize {
unsigned short ws_row;
@@ -213,24 +222,4 @@ struct termios {
#define TCSADRAIN 1
#define TCSAFLUSH 2
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern speed_t cfgetispeed(struct termios *termios_p);
-extern speed_t cfgetospeed(struct termios *termios_p);
-extern int cfsetispeed(struct termios *termios_p, speed_t speed);
-extern int cfsetospeed(struct termios *termios_p, speed_t speed);
-extern int tcdrain(int fildes);
-extern int tcflow(int fildes, int action);
-extern int tcflush(int fildes, int queue_selector);
-extern int tcgetattr(int fildes, struct termios *termios_p);
-extern int tcsendbreak(int fildes, int duration);
-extern int tcsetattr(int fildes, int optional_actions,
- struct termios *termios_p);
-
-#ifdef __cplusplus
-}
-#endif
-
#endif
diff --git a/include/linux/time.h b/include/linux/time.h
new file mode 100644
index 0000000..f154e5d
--- /dev/null
+++ b/include/linux/time.h
@@ -0,0 +1,33 @@
+#ifndef _LINUX_TIME_H
+#define _LINUX_TIME_H
+
+struct timeval {
+ long tv_sec; /* seconds */
+ long tv_usec; /* microseconds */
+};
+
+struct timezone {
+ int tz_minuteswest; /* minutes west of Greenwich */
+ 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)
+
+/*
+ * Names of the interval timers, and structure
+ * defining a timer setting.
+ */
+#define ITIMER_REAL 0
+#define ITIMER_VIRTUAL 1
+#define ITIMER_PROF 2
+
+struct itimerval {
+ struct timeval it_interval; /* timer interval */
+ struct timeval it_value; /* current value */
+};
+
+#endif
diff --git a/include/linux/timer.h b/include/linux/timer.h
index aa92aa3..84d6aa8 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -1,5 +1,5 @@
-#ifndef _TIMER_H
-#define _TIMER_H
+#ifndef _LINUX_TIMER_H
+#define _LINUX_TIMER_H
/*
* DON'T CHANGE THESE!! Most of them are hardcoded into some assembly language
diff --git a/include/sys/times.h b/include/linux/times.h
index 68d5bfb..e7ae2fa 100644
--- a/include/sys/times.h
+++ b/include/linux/times.h
@@ -1,7 +1,5 @@
-#ifndef _TIMES_H
-#define _TIMES_H
-
-#include <sys/types.h>
+#ifndef _LINUX_TIMES_H
+#define _LINUX_TIMES_H
struct tms {
time_t tms_utime;
@@ -10,6 +8,4 @@ struct tms {
time_t tms_cstime;
};
-extern time_t times(struct tms * tp);
-
#endif
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 329165e..d6c1f6e 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -1,3 +1,6 @@
+#ifndef _LINUX_TTY_H
+#define _LINUX_TTY_H
+
/*
* 'tty.h' defines some structures used by tty_io.c and some defines.
*
@@ -6,8 +9,7 @@
* offsets into 'tty_queue'
*/
-#ifndef _TTY_H
-#define _TTY_H
+#include <linux/termios.h>
#include <asm/system.h>
@@ -16,14 +18,46 @@
#define NR_PTYS 4
/*
+ * These are set up by the setup-routine at boot-time:
+ */
+
+struct screen_info {
+ unsigned char orig_x;
+ unsigned char orig_y;
+ unsigned char unused1[2];
+ unsigned short orig_video_page;
+ unsigned char orig_video_mode;
+ unsigned char orig_video_cols;
+ unsigned short orig_video_ega_ax;
+ unsigned short orig_video_ega_bx;
+ unsigned short orig_video_ega_cx;
+ unsigned char orig_video_lines;
+};
+
+extern struct screen_info screen_info;
+
+#define ORIG_X (screen_info.orig_x)
+#define ORIG_Y (screen_info.orig_y)
+#define ORIG_VIDEO_PAGE (screen_info.orig_video_page)
+#define ORIG_VIDEO_MODE (screen_info.orig_video_mode)
+#define ORIG_VIDEO_COLS (screen_info.orig_video_cols)
+#define ORIG_VIDEO_EGA_AX (screen_info.orig_video_ega_ax)
+#define ORIG_VIDEO_EGA_BX (screen_info.orig_video_ega_bx)
+#define ORIG_VIDEO_EGA_CX (screen_info.orig_video_ega_cx)
+#define ORIG_VIDEO_LINES (screen_info.orig_video_lines)
+
+#define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */
+#define VIDEO_TYPE_CGA 0x11 /* CGA Display */
+#define VIDEO_TYPE_EGAM 0x20 /* EGA/VGA in Monochrome Mode */
+#define VIDEO_TYPE_EGAC 0x21 /* EGA/VGA in Color Mode */
+
+/*
* This character is the same as _POSIX_VDISABLE: it cannot be used as
* a c_cc[] character, but indicates that a particular special character
* isn't in use (eg VINTR ahs no character etc)
*/
#define __DISABLED_CHAR '\0'
-#include <termios.h>
-
#define TTY_BUF_SIZE 2048
struct tty_queue {
diff --git a/include/sys/types.h b/include/linux/types.h
index 46b57b5..53088a2 100644
--- a/include/sys/types.h
+++ b/include/linux/types.h
@@ -1,7 +1,5 @@
-#ifndef _SYS_TYPES_H
-#define _SYS_TYPES_H
-
-#include <stddef.h>
+#ifndef _LINUX_TYPES_H
+#define _LINUX_TYPES_H
#ifndef _SIZE_T
#define _SIZE_T
diff --git a/include/sys/un.h b/include/linux/un.h
index 26a51f4..5c41503 100644
--- a/include/sys/un.h
+++ b/include/linux/un.h
@@ -1,5 +1,5 @@
-#ifndef _UN_H
-#define _UN_H
+#ifndef _LINUX_UN_H
+#define _LINUX_UN_H
struct sockaddr_un {
u_short sun_family; /* AF_UNIX */
diff --git a/include/sys/user.h b/include/linux/user.h
index 1a3c292..106e710 100644
--- a/include/sys/user.h
+++ b/include/linux/user.h
@@ -1,4 +1,7 @@
-#include <sys/ptrace.h>
+#ifndef _LINUX_USER_H
+#define _LINUX_USER_H
+
+#include <linux/ptrace.h>
/* Core file format: The core file is written in such a way that gdb
can understand it and provide useful information to the user (under
linux we use the 'trad-core' bfd). There are quite a number of
@@ -68,3 +71,5 @@ struct user{
#define UPAGES 1
#define HOST_TEXT_START_ADDR (u.start_code)
#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
+
+#endif
diff --git a/include/linux/utime.h b/include/linux/utime.h
new file mode 100644
index 0000000..c6bf27b
--- /dev/null
+++ b/include/linux/utime.h
@@ -0,0 +1,9 @@
+#ifndef _LINUX_UTIME_H
+#define _LINUX_UTIME_H
+
+struct utimbuf {
+ time_t actime;
+ time_t modtime;
+};
+
+#endif
diff --git a/include/sys/vfs.h b/include/linux/vfs.h
index c7e113e..6d1f625 100644
--- a/include/sys/vfs.h
+++ b/include/linux/vfs.h
@@ -1,5 +1,5 @@
-#ifndef _SYS_VFS_H_
-#define _SYS_VFS_H_
+#ifndef _LINUX_VFS_H
+#define _LINUX_VFS_H
typedef struct {
long val[2];
diff --git a/include/linux/wait.h b/include/linux/wait.h
index 77ad9a3..0c13811 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -3,6 +3,9 @@
#include <linux/limits.h>
+#define WNOHANG 1
+#define WUNTRACED 2
+
struct wait_queue {
struct task_struct * task;
struct wait_queue * next;
diff --git a/include/stdarg.h b/include/stdarg.h
index fd79ec0..fd79ec0 100755..100644
--- a/include/stdarg.h
+++ b/include/stdarg.h
diff --git a/include/sys/time.h b/include/sys/time.h
deleted file mode 100644
index 1ef722b..0000000
--- a/include/sys/time.h
+++ /dev/null
@@ -1,67 +0,0 @@
-#ifndef _SYS_TIME_H
-#define _SYS_TIME_H
-
-/* gettimofday returns this */
-struct timeval {
- long tv_sec; /* seconds */
- long tv_usec; /* microseconds */
-};
-
-struct timezone {
- int tz_minuteswest; /* minutes west of Greenwich */
- int tz_dsttime; /* type of dst correction */
-};
-
-#define DST_NONE 0 /* not on dst */
-#define DST_USA 1 /* USA style dst */
-#define DST_AUST 2 /* Australian style dst */
-#define DST_WET 3 /* Western European dst */
-#define DST_MET 4 /* Middle European dst */
-#define DST_EET 5 /* Eastern European dst */
-#define DST_CAN 6 /* Canada */
-#define DST_GB 7 /* Great Britain and Eire */
-#define DST_RUM 8 /* Rumania */
-#define DST_TUR 9 /* Turkey */
-#define DST_AUSTALT 10 /* Australian style with shift in 1986 */
-
-#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)
-
-/*
- * Operations on timevals.
- *
- * NB: timercmp does not work for >= or <=.
- */
-#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
-#define timercmp(tvp, uvp, cmp) \
- ((tvp)->tv_sec cmp (uvp)->tv_sec || \
- (tvp)->tv_sec == (uvp)->tv_sec && (tvp)->tv_usec cmp (uvp)->tv_usec)
-#define timerclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0)
-
-/*
- * Names of the interval timers, and structure
- * defining a timer setting.
- */
-#define ITIMER_REAL 0
-#define ITIMER_VIRTUAL 1
-#define ITIMER_PROF 2
-
-struct itimerval {
- struct timeval it_interval; /* timer interval */
- struct timeval it_value; /* current value */
-};
-
-int getitimer(int which, struct itimerval *value);
-int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue);
-
-#include <time.h>
-#include <sys/types.h>
-
-int gettimeofday(struct timeval * tp, struct timezone * tz);
-int select(int width, fd_set * readfds, fd_set * writefds,
- fd_set * exceptfds, struct timeval * timeout);
-
-#endif /*_SYS_TIME_H*/
diff --git a/include/sys/wait.h b/include/sys/wait.h
deleted file mode 100644
index d6c3360..0000000
--- a/include/sys/wait.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef _SYS_WAIT_H
-#define _SYS_WAIT_H
-
-#include <sys/types.h>
-
-#define _LOW(v) ( (v) & 0377)
-#define _HIGH(v) ( ((v) >> 8) & 0377)
-
-/* options for waitpid, WUNTRACED not supported */
-#define WNOHANG 1
-#define WUNTRACED 2
-
-#define WIFEXITED(s) (!((s)&0xFF))
-#define WIFSTOPPED(s) (((s)&0xFF)==0x7F)
-#define WEXITSTATUS(s) (((s)>>8)&0xFF)
-#define WTERMSIG(s) ((s)&0x7F)
-#define WCOREDUMP(s) ((s)&0x80)
-#define WSTOPSIG(s) (((s)>>8)&0xFF)
-#define WIFSIGNALED(s) (((unsigned int)(s)-1 & 0xFFFF) < 0xFF)
-
-pid_t wait(int *stat_loc);
-pid_t waitpid(pid_t pid, int *stat_loc, int options);
-
-#endif
diff --git a/include/unistd.h b/include/unistd.h
deleted file mode 100644
index 041977b..0000000
--- a/include/unistd.h
+++ /dev/null
@@ -1,164 +0,0 @@
-#ifndef _UNISTD_H
-#define _UNISTD_H
-
-/* ok, this may be a joke, but I'm working on it */
-#define _POSIX_VERSION 198808L
-
-#define _POSIX_CHOWN_RESTRICTED 1 /* only root can do a chown (I think..) */
-#define _POSIX_NO_TRUNC 1 /* no pathname truncation (but see kernel) */
-#define _POSIX_VDISABLE '\0' /* character to disable things like ^C */
-#define _POSIX_JOB_CONTROL 1
-#define _POSIX_SAVED_IDS 1 /* Implemented, for whatever good it is */
-
-#define STDIN_FILENO 0
-#define STDOUT_FILENO 1
-#define STDERR_FILENO 2
-
-#ifndef NULL
-#define NULL ((void *)0)
-#endif
-
-/* access */
-#define F_OK 0
-#define X_OK 1
-#define W_OK 2
-#define R_OK 4
-
-/* lseek */
-#define SEEK_SET 0
-#define SEEK_CUR 1
-#define SEEK_END 2
-
-/* _SC stands for System Configuration. We don't use them much */
-#define _SC_ARG_MAX 1
-#define _SC_CHILD_MAX 2
-#define _SC_CLOCKS_PER_SEC 3
-#define _SC_NGROUPS_MAX 4
-#define _SC_OPEN_MAX 5
-#define _SC_JOB_CONTROL 6
-#define _SC_SAVED_IDS 7
-#define _SC_VERSION 8
-
-/* more (possibly) configurable things - now pathnames */
-#define _PC_LINK_MAX 1
-#define _PC_MAX_CANON 2
-#define _PC_MAX_INPUT 3
-#define _PC_NAME_MAX 4
-#define _PC_PATH_MAX 5
-#define _PC_PIPE_BUF 6
-#define _PC_NO_TRUNC 7
-#define _PC_VDISABLE 8
-#define _PC_CHOWN_RESTRICTED 9
-
-#if 0
-/* XXX - <sys/stat.h> illegally <sys/types.h> already.
- * The rest of these includes are also illegal (too much pollution).
- */
-#include <sys/types.h>
-#endif
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/times.h>
-#include <sys/utsname.h>
-#include <sys/resource.h>
-#include <utime.h>
-
-#ifdef __LIBRARY__
-#include <linux/unistd.h>
-#endif /* __LIBRARY__ */
-
-/* XXX - illegal. */
-extern int errno;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* XXX - several non-POSIX functions here, and POSIX functions that are
- * supposed to be declared elsewhere. Non-promotion of short types in
- * prototypes may cause trouble. Arg names should be prefixed by
- * underscores.
- */
-int access(const char * filename, mode_t mode); /* XXX - short type */
-int acct(const char * filename);
-int brk(void * end_data_segment);
-/* XXX - POSIX says unsigned alarm(unsigned sec) */
-int alarm(int sec);
-void * sbrk(ptrdiff_t increment);
-int chdir(const char * filename);
-int chmod(const char * filename, mode_t mode); /* XXX - short type */
-int chown(const char * filename, uid_t owner, gid_t group); /* XXX - shorts */
-int chroot(const char * filename);
-int close(int fildes);
-int creat(const char * filename, mode_t mode); /* XXX - short type */
-int dup(int fildes);
-int execve(const char * filename, char ** argv, char ** envp);
-int execv(const char * pathname, char ** argv);
-int execvp(const char * file, char ** argv);
-int execl(const char * pathname, char * arg0, ...);
-int execlp(const char * file, char * arg0, ...);
-int execle(const char * pathname, char * arg0, ...);
-volatile void exit(int status);
-volatile void _exit(int status);
-int fcntl(int fildes, int cmd, ...);
-pid_t fork(void);
-pid_t getpid(void);
-uid_t getuid(void);
-uid_t geteuid(void);
-gid_t getgid(void);
-gid_t getegid(void);
-int ioctl(int fildes, int cmd, ...);
-int kill(pid_t pid, int signal);
-int link(const char * filename1, const char * filename2);
-off_t lseek(int fildes, off_t offset, int origin);
-int mknod(const char * filename, mode_t mode, dev_t dev); /* XXX - shorts */
-int mount(const char * specialfile, const char * dir, const char * type, int rwflag);
-int nice(int val);
-int open(const char * filename, int flag, ...);
-int pause(void);
-int pipe(int * fildes);
-/* XXX**2 - POSIX says unsigned count */
-int read(int fildes, char * buf, off_t count);
-int setpgrp(void);
-int setpgid(pid_t pid,pid_t pgid); /* XXX - short types */
-int setuid(uid_t uid); /* XXX - short type */
-int setgid(gid_t gid); /* XXX - short type */
-void (*signal(int sig, void (*fn)(int)))(int);
-int stat(const char * filename, struct stat * stat_buf);
-int fstat(int fildes, struct stat * stat_buf);
-int stime(time_t * tptr);
-int sync(void);
-time_t time(time_t * tloc);
-time_t times(struct tms * tbuf);
-int ulimit(int cmd, long limit);
-mode_t umask(mode_t mask);
-int umount(const char * specialfile);
-int uname(struct utsname * name);
-int unlink(const char * filename);
-int ustat(dev_t dev, struct ustat * ubuf);
-int utime(const char * filename, struct utimbuf * times);
-pid_t waitpid(pid_t pid,int * wait_stat,int options);
-pid_t wait(int * wait_stat);
-/* XXX**2 - POSIX says unsigned count */
-int write(int fildes, const char * buf, off_t count);
-int dup2(int oldfd, int newfd);
-int getppid(void);
-pid_t getpgrp(void);
-pid_t setsid(void);
-int sethostname(char *name, int len);
-int setrlimit(int resource, struct rlimit *rlp);
-int getrlimit(int resource, struct rlimit *rlp);
-int getrusage(int who, struct rusage *rusage);
-int gettimeofday(struct timeval *tv, struct timezone *tz);
-int settimeofday(struct timeval *tv, struct timezone *tz);
-int getgroups(int gidsetlen, gid_t *gidset);
-int setgroups(int gidsetlen, gid_t *gidset);
-int select(int width, fd_set * readfds, fd_set * writefds,
- fd_set * exceptfds, struct timeval * timeout);
-int swapon(const char * specialfile);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/include/utime.h b/include/utime.h
deleted file mode 100644
index a7b79b3..0000000
--- a/include/utime.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef _UTIME_H
-#define _UTIME_H
-
-#include <sys/types.h> /* I know - shouldn't do this, but .. */
-
-struct utimbuf {
- time_t actime;
- time_t modtime;
-};
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern int utime(const char *filename, struct utimbuf *times);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/init/main.c b/init/main.c
index 1f6174d..aec7bb7 100644
--- a/init/main.c
+++ b/init/main.c
@@ -1,18 +1,16 @@
/*
* linux/init/main.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
-#include <stddef.h>
#include <stdarg.h>
#include <time.h>
-#include <sys/types.h>
-
#include <asm/system.h>
#include <asm/io.h>
+#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/config.h>
#include <linux/sched.h>
@@ -59,7 +57,6 @@ extern long chr_dev_init(long,long);
extern void hd_init(void);
extern void floppy_init(void);
extern void sock_init(void);
-extern void mem_init(long start, long end);
extern long rd_init(long mem_start, int length);
extern long kernel_mktime(struct tm * tm);
@@ -82,9 +79,8 @@ static int sprintf(char * str, const char *fmt, ...)
* This is set up by the setup-routine at boot-time
*/
#define EXT_MEM_K (*(unsigned short *)0x90002)
-#define CON_ROWS ((*(unsigned short *)0x9000e) & 0xff)
-#define CON_COLS (((*(unsigned short *)0x9000e) & 0xff00) >> 8)
#define DRIVE_INFO (*(struct drive_info *)0x90080)
+#define SCREEN_INFO (*(struct screen_info *)0x90000)
#define ORIG_ROOT_DEV (*(unsigned short *)0x901FC)
/*
@@ -123,9 +119,9 @@ static void time_init(void)
startup_time = kernel_mktime(&time);
}
-static long memory_end = 0;
-static long buffer_memory_end = 0;
-static long main_memory_start = 0;
+static unsigned long memory_start = 0;
+static unsigned long memory_end = 0;
+
static char term[32];
static char * argv_init[] = { "/bin/init", NULL };
@@ -138,6 +134,7 @@ static char * argv[] = { "-/bin/sh",NULL };
static char * envp[] = { "HOME=/usr/root", NULL, NULL };
struct drive_info { char dummy[32]; } drive_info;
+struct screen_info screen_info;
void start_kernel(void)
{
@@ -146,33 +143,26 @@ void start_kernel(void)
* enable them
*/
ROOT_DEV = ORIG_ROOT_DEV;
- sprintf(term, "TERM=con%dx%d", CON_COLS, CON_ROWS);
+ drive_info = DRIVE_INFO;
+ screen_info = SCREEN_INFO;
+ sprintf(term, "TERM=con%dx%d", ORIG_VIDEO_COLS, ORIG_VIDEO_LINES);
envp[1] = term;
envp_rc[1] = term;
envp_init[1] = term;
- drive_info = DRIVE_INFO;
memory_end = (1<<20) + (EXT_MEM_K<<10);
memory_end &= 0xfffff000;
if (memory_end > 16*1024*1024)
memory_end = 16*1024*1024;
- if (memory_end >= 12*1024*1024)
- buffer_memory_end = 4*1024*1024;
- else if (memory_end >= 6*1024*1024)
- buffer_memory_end = 2*1024*1024;
- else if (memory_end >= 4*1024*1024)
- buffer_memory_end = 3*512*1024;
- else
- buffer_memory_end = 1*1024*1024;
- main_memory_start = buffer_memory_end;
+ memory_start = 1024*1024;
trap_init();
init_IRQ();
sched_init();
- main_memory_start = chr_dev_init(main_memory_start,memory_end);
- main_memory_start = blk_dev_init(main_memory_start,memory_end);
- mem_init(main_memory_start,memory_end);
+ memory_start = chr_dev_init(memory_start,memory_end);
+ memory_start = blk_dev_init(memory_start,memory_end);
+ memory_start = mem_init(memory_start,memory_end);
+ buffer_init();
time_init();
printk("Linux version " UTS_RELEASE " " __DATE__ " " __TIME__ "\n");
- buffer_init(buffer_memory_end);
hd_init();
floppy_init();
sock_init();
@@ -216,9 +206,9 @@ void init(void)
(void) open("/dev/tty1",O_RDWR,0);
(void) dup(0);
(void) dup(0);
- printf("%d buffers = %d bytes buffer space\n\r",NR_BUFFERS,
- NR_BUFFERS*BLOCK_SIZE);
- printf("Free mem: %d bytes\n\r",memory_end-main_memory_start);
+ printf("%d buffers = %d bytes buffer space\n\r",nr_buffers,
+ nr_buffers*BLOCK_SIZE);
+ printf("Free mem: %d bytes\n\r",memory_end-memory_start);
execve("/etc/init",argv_init,envp_init);
execve("/bin/init",argv_init,envp_init);
diff --git a/kernel/Makefile b/kernel/Makefile
index 3b1c608..695e77c 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -22,14 +22,14 @@ OBJS = sched.o sys_call.o traps.o irq.o fork.o \
panic.o printk.o vsprintf.o sys.o exit.o \
signal.o mktime.o ptrace.o ioport.o itimer.o
-all: kernel.o subdirs
+all: kernel.o kernelsubdirs
kernel.o: $(OBJS)
$(LD) -r -o kernel.o $(OBJS)
sync
-subdirs: dummy
- for i in $(SUBDIRS); do (cd $$i; $(MAKE)); done
+kernelsubdirs: dummy
+ @for i in $(SUBDIRS); do (cd $$i; echo $$i; $(MAKE)) || exit; done
sys_call.s: sys_call.S
@@ -47,98 +47,116 @@ dep:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
for i in *.c;do $(CPP) -M $$i;done >> tmp_make
cp tmp_make Makefile
- for i in $(SUBDIRS); do (cd $$i; $(MAKE) dep); done
+ for i in $(SUBDIRS); do (cd $$i; $(MAKE) dep) || exit; done
dummy:
### Dependencies:
-exit.o : exit.c /usr/src/linux/include/errno.h /usr/src/linux/include/signal.h \
- /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/wait.h \
- /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
- /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
- /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/sys/param.h \
- /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \
- /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h \
+exit.o : exit.c /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/errno.h /usr/src/linux/include/linux/signal.h /usr/src/linux/include/linux/sched.h \
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/types.h \
+ /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/time.h \
+ /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/tty.h /usr/src/linux/include/linux/termios.h /usr/src/linux/include/asm/system.h \
/usr/src/linux/include/asm/segment.h
-fork.o : fork.c /usr/src/linux/include/errno.h /usr/src/linux/include/stddef.h \
- /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
- /usr/src/linux/include/sys/types.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
- /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/segment.h \
- /usr/src/linux/include/asm/system.h
+fork.o : fork.c /usr/src/linux/include/linux/errno.h /usr/src/linux/include/linux/sched.h \
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/stddef.h /usr/src/linux/include/asm/segment.h /usr/src/linux/include/asm/system.h
ioport.o : ioport.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
- /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
- /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
- /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
- /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
- /usr/src/linux/include/sys/resource.h /usr/src/linux/include/errno.h
-irq.o : irq.c /usr/src/linux/include/signal.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/errno.h /usr/src/linux/include/sys/ptrace.h \
- /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
- /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
- /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/sys/param.h \
- /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \
- /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/io.h /usr/src/linux/include/asm/irq.h
-itimer.o : itimer.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
- /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
- /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
- /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
- /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
- /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/string.h \
- /usr/src/linux/include/asm/segment.h /usr/src/linux/include/errno.h
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/mm.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/errno.h
+irq.o : irq.c /usr/src/linux/include/linux/ptrace.h /usr/src/linux/include/linux/errno.h \
+ /usr/src/linux/include/linux/signal.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/mm.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h \
+ /usr/src/linux/include/linux/resource.h /usr/src/linux/include/asm/system.h \
+ /usr/src/linux/include/asm/io.h /usr/src/linux/include/asm/irq.h
+itimer.o : itimer.c /usr/src/linux/include/linux/signal.h /usr/src/linux/include/linux/sched.h \
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/time.h \
+ /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/string.h /usr/src/linux/include/linux/errno.h /usr/src/linux/include/asm/segment.h
mktime.o : mktime.c /usr/src/linux/include/time.h
panic.o : panic.c /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/signal.h \
- /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
- /usr/src/linux/include/sys/resource.h
-printk.o : printk.c /usr/src/linux/include/stdarg.h /usr/src/linux/include/stddef.h \
- /usr/src/linux/include/errno.h /usr/src/linux/include/asm/segment.h /usr/src/linux/include/asm/system.h \
- /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
- /usr/src/linux/include/sys/types.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
- /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/signal.h /usr/src/linux/include/linux/time.h \
+ /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h
+printk.o : printk.c /usr/src/linux/include/stdarg.h /usr/src/linux/include/asm/segment.h \
+ /usr/src/linux/include/asm/system.h /usr/src/linux/include/linux/errno.h /usr/src/linux/include/linux/sched.h \
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h
ptrace.o : ptrace.c /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/kernel.h \
- /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/signal.h \
- /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
- /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/segment.h /usr/src/linux/include/asm/system.h \
- /usr/src/linux/include/errno.h /usr/src/linux/include/sys/ptrace.h
-sched.o : sched.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
- /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
- /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
- /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
- /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
- /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/timer.h /usr/src/linux/include/linux/sys.h \
- /usr/src/linux/include/linux/fdreg.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/io.h \
- /usr/src/linux/include/asm/segment.h /usr/src/linux/include/errno.h
+ /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/signal.h /usr/src/linux/include/linux/time.h \
+ /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/errno.h /usr/src/linux/include/linux/ptrace.h /usr/src/linux/include/asm/segment.h \
+ /usr/src/linux/include/asm/system.h
+sched.o : sched.c /usr/src/linux/include/linux/signal.h /usr/src/linux/include/linux/sched.h \
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/time.h \
+ /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/timer.h /usr/src/linux/include/linux/sys.h /usr/src/linux/include/linux/fdreg.h \
+ /usr/src/linux/include/linux/errno.h /usr/src/linux/include/linux/ptrace.h /usr/src/linux/include/asm/system.h \
+ /usr/src/linux/include/asm/io.h /usr/src/linux/include/asm/segment.h
signal.o : signal.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
- /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
- /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
- /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
- /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
- /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/segment.h /usr/src/linux/include/sys/wait.h \
- /usr/src/linux/include/sys/ptrace.h /usr/src/linux/include/errno.h
-sys.o : sys.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
- /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/tty.h \
- /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h /usr/src/linux/include/linux/config.h \
- /usr/src/linux/include/linux/config_rel.h /usr/src/linux/include/linux/config_ver.h \
- /usr/src/linux/include/linux/config.dist.h /usr/src/linux/include/asm/segment.h \
- /usr/src/linux/include/sys/times.h /usr/src/linux/include/linux/utsname.h /usr/src/linux/include/linux/string.h
-traps.o : traps.c /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
- /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/system.h \
- /usr/src/linux/include/asm/segment.h /usr/src/linux/include/asm/io.h /usr/src/linux/include/errno.h
-vsprintf.o : vsprintf.c /usr/src/linux/include/stdarg.h /usr/src/linux/include/linux/string.h \
- /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/mm.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/errno.h /usr/src/linux/include/linux/ptrace.h /usr/src/linux/include/asm/segment.h
+sys.o : sys.c /usr/src/linux/include/linux/errno.h /usr/src/linux/include/linux/sched.h \
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/tty.h /usr/src/linux/include/linux/termios.h /usr/src/linux/include/asm/system.h \
+ /usr/src/linux/include/linux/config.h /usr/src/linux/include/linux/config_rel.h \
+ /usr/src/linux/include/linux/config_ver.h /usr/src/linux/include/linux/config.dist.h \
+ /usr/src/linux/include/linux/times.h /usr/src/linux/include/linux/utsname.h \
+ /usr/src/linux/include/linux/string.h /usr/src/linux/include/asm/segment.h
+traps.o : traps.c /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/sched.h \
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/mm.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/string.h /usr/src/linux/include/linux/errno.h /usr/src/linux/include/asm/system.h \
+ /usr/src/linux/include/asm/segment.h /usr/src/linux/include/asm/io.h
+vsprintf.o : vsprintf.c /usr/src/linux/include/stdarg.h /usr/src/linux/include/linux/types.h \
+ /usr/src/linux/include/linux/string.h
diff --git a/kernel/asm.s b/kernel/asm.s
deleted file mode 100644
index f62751c..0000000
--- a/kernel/asm.s
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * linux/kernel/asm.s
- *
- * (C) 1991 Linus Torvalds
- */
-
-/*
- * asm.s contains the low-level code for interrupts that cannot
- * result in an task-switch. These are things like the hd- and
- * floppy-interrupt etc. With these interrupts, we don't have to
- * care about the stack layout etc.
- */
-
-.globl _floppy_interrupt,_parallel_interrupt
-
-_floppy_interrupt:
- cld
- pushl %eax
- pushl %ecx
- pushl %edx
- push %ds
- push %es
- push %fs
- movl $0x10,%eax
- mov %ax,%ds
- mov %ax,%es
- movl $0x17,%eax
- mov %ax,%fs
- movb $0x20,%al
- outb %al,$0x20 # EOI to interrupt controller #1
- xorl %eax,%eax
- xchgl _do_floppy,%eax
- testl %eax,%eax
- jne 1f
- movl $_unexpected_floppy_interrupt,%eax
-1: call *%eax # "interesting" way of handling intr.
- pop %fs
- pop %es
- pop %ds
- popl %edx
- popl %ecx
- popl %eax
- iret
-
-_parallel_interrupt:
- cld
- pushl %eax
- movb $0x20,%al
- outb %al,$0x20
- popl %eax
- iret
diff --git a/kernel/blk_drv/Makefile b/kernel/blk_drv/Makefile
index 99d573a..232a0c8 100644
--- a/kernel/blk_drv/Makefile
+++ b/kernel/blk_drv/Makefile
@@ -18,63 +18,69 @@
SUBDIRS = scsi
-OBJS = hd.o ll_rw_blk.o floppy.o ramdisk.o
+OBJS = hd.o ll_rw_blk.o floppy.o ramdisk.o genhd.o
-all: blk_drv.a subdirs
+all: blk_drv.a scsisubdirs
blk_drv.a: $(OBJS)
rm -f blk_drv.a
$(AR) rcs blk_drv.a $(OBJS)
sync
-subdirs: dummy
- for i in $(SUBDIRS); do (cd $$i; $(MAKE)); done
+scsisubdirs: dummy
+ @for i in $(SUBDIRS); do (cd $$i; echo $$i; $(MAKE)) || exit; done
clean:
rm -f core *.o *.a tmp_make
for i in *.c;do rm -f `basename $$i .c`.s;done
- cd scsi; $(MAKE) clean
+ for i in $(SUBDIRS); do (cd $$i; $(MAKE) clean); done
dep:
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
for i in *.c;do $(CPP) -M $$i;done >> tmp_make
cp tmp_make Makefile
+ for i in $(SUBDIRS); do (cd $$i; $(MAKE) dep); done
dummy:
### Dependencies:
floppy.o : floppy.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
- /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
- /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
- /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
- /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
- /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/timer.h /usr/src/linux/include/linux/fdreg.h \
- /usr/src/linux/include/linux/fd.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/io.h \
- /usr/src/linux/include/asm/segment.h /usr/src/linux/include/errno.h blk.h
-hd.o : hd.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/config.h \
- /usr/src/linux/include/linux/config_rel.h /usr/src/linux/include/linux/config_ver.h \
- /usr/src/linux/include/linux/config.dist.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
- /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/timer.h \
- /usr/src/linux/include/linux/hdreg.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/io.h \
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/mm.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/timer.h /usr/src/linux/include/linux/fdreg.h /usr/src/linux/include/linux/fd.h \
+ /usr/src/linux/include/linux/errno.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/io.h \
/usr/src/linux/include/asm/segment.h blk.h
-ll_rw_blk.o : ll_rw_blk.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
- /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/system.h \
- blk.h
-ramdisk.o : ramdisk.c /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/config.h /usr/src/linux/include/linux/config_rel.h \
+genhd.o : genhd.c /usr/src/linux/include/linux/config.h /usr/src/linux/include/linux/config_rel.h \
+ /usr/src/linux/include/linux/config_ver.h /usr/src/linux/include/linux/config.dist.h \
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/genhd.h \
+ /usr/src/linux/include/linux/kernel.h
+hd.o : hd.c /usr/src/linux/include/linux/config.h /usr/src/linux/include/linux/config_rel.h \
/usr/src/linux/include/linux/config_ver.h /usr/src/linux/include/linux/config.dist.h \
- /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
- /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
- /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
- /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
- /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/minix_fs.h \
- /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/segment.h /usr/src/linux/include/asm/memory.h \
+ /usr/src/linux/include/linux/errno.h /usr/src/linux/include/linux/signal.h /usr/src/linux/include/linux/sched.h \
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/time.h \
+ /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/timer.h /usr/src/linux/include/linux/hdreg.h /usr/src/linux/include/linux/genhd.h \
+ /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/io.h /usr/src/linux/include/asm/segment.h \
+ blk.h
+ll_rw_blk.o : ll_rw_blk.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/mm.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/errno.h /usr/src/linux/include/linux/string.h /usr/src/linux/include/asm/system.h \
blk.h
+ramdisk.o : ramdisk.c /usr/src/linux/include/linux/config.h /usr/src/linux/include/linux/config_rel.h \
+ /usr/src/linux/include/linux/config_ver.h /usr/src/linux/include/linux/config.dist.h
diff --git a/kernel/blk_drv/blk.h b/kernel/blk_drv/blk.h
index 097c993..70dab1b 100644
--- a/kernel/blk_drv/blk.h
+++ b/kernel/blk_drv/blk.h
@@ -26,6 +26,7 @@ struct request {
int errors;
unsigned long sector;
unsigned long nr_sectors;
+ unsigned long current_nr_sectors;
char * buffer;
struct wait_queue * waiting;
struct buffer_head * bh;
@@ -39,7 +40,7 @@ struct request {
* are much more time-critical than writes.
*/
#define IN_ORDER(s1,s2) \
-((s1)->cmd<(s2)->cmd || ((s1)->cmd==(s2)->cmd && \
+((s1)->cmd < (s2)->cmd || ((s1)->cmd == (s2)->cmd && \
((s1)->dev < (s2)->dev || (((s1)->dev == (s2)->dev && \
(s1)->sector < (s2)->sector)))))
@@ -48,6 +49,20 @@ struct blk_dev_struct {
struct request * current_request;
};
+
+struct sec_size {
+ unsigned block_size;
+ unsigned block_size_bits;
+};
+
+/*
+ * These will have to be changed to be aware of different buffer
+ * sizes etc..
+ */
+#define SECTOR_MASK ((1 << (BLOCK_SIZE_BITS - 9)) -1)
+#define SUBSECTOR(block) ((block) & SECTOR_MASK)
+
+extern struct sec_size * blk_sec[NR_BLK_DEV];
extern struct blk_dev_struct blk_dev[NR_BLK_DEV];
extern struct request request[NR_REQUEST];
extern struct wait_queue * wait_for_request;
@@ -60,7 +75,8 @@ extern void set_device_ro(int dev,int flag);
#define RO_IOCTLS(dev,where) \
case BLKROSET: if (!suser()) return -EPERM; \
set_device_ro((dev),get_fs_long((long *) (where))); return 0; \
- case BLKROGET: put_fs_long(is_read_only(dev),(long *) (where)); return 0;
+ case BLKROGET: verify_area((void *) (where), sizeof(long)); \
+ put_fs_long(is_read_only(dev),(long *) (where)); return 0;
#ifdef MAJOR_NR
@@ -101,6 +117,7 @@ extern void set_device_ro(int dev,int flag);
/* scsi disk */
#define DEVICE_NAME "scsidisk"
#define DEVICE_INTR do_sd
+#define TIMEOUT_VALUE 200
#define DEVICE_REQUEST do_sd_request
#define DEVICE_NR(device) (MINOR(device) >> 4)
#define DEVICE_ON(device)
@@ -121,7 +138,10 @@ extern void set_device_ro(int dev,int flag);
#endif
+#ifndef CURRENT
#define CURRENT (blk_dev[MAJOR_NR].current_request)
+#endif
+
#define CURRENT_DEV DEVICE_NR(CURRENT->dev)
#ifdef DEVICE_INTR
@@ -168,18 +188,20 @@ static void end_request(int uptodate)
printk(DEVICE_NAME " I/O error\n\r");
printk("dev %04x, sector %d\n\r",req->dev,req->sector);
req->nr_sectors--;
- req->nr_sectors &= ~1;
- req->sector += 2;
- req->sector &= ~1;
+ req->nr_sectors &= ~SECTOR_MASK;
+ req->sector += (BLOCK_SIZE / 512);
+ req->sector &= ~SECTOR_MASK;
}
+
if (bh = req->bh) {
req->bh = bh->b_reqnext;
bh->b_reqnext = NULL;
bh->b_uptodate = uptodate;
unlock_buffer(bh);
if (bh = req->bh) {
- if (req->nr_sectors < 2) {
- req->nr_sectors = 2;
+ req->current_nr_sectors = bh->b_size >> 9;
+ if (req->nr_sectors < req->current_nr_sectors) {
+ req->nr_sectors = req->current_nr_sectors;
printk("end_request: buffer-list destroyed\n");
}
req->buffer = bh->b_data;
@@ -200,7 +222,6 @@ static void end_request(int uptodate)
#endif
#define INIT_REQUEST \
-repeat: \
if (!CURRENT) {\
CLEAR_INTR; \
return; \
diff --git a/kernel/blk_drv/floppy.c b/kernel/blk_drv/floppy.c
index 7fb9e57..8bfff57 100644
--- a/kernel/blk_drv/floppy.c
+++ b/kernel/blk_drv/floppy.c
@@ -1,7 +1,7 @@
/*
* linux/kernel/floppy.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
@@ -38,6 +38,14 @@
* the floppy-change signal detection.
*/
+/*
+ * 1992/7/22 -- Hennus Bergman: Added better error reporting, fixed
+ * FDC data overrun bug, added some preliminary stuff for vertical
+ * recording support.
+ * TODO: Errors are still not counted properly.
+ */
+
+#define REALLY_SLOW_IO
#define FLOPPY_IRQ 6
#include <linux/sched.h>
@@ -46,10 +54,14 @@
#include <linux/timer.h>
#include <linux/fdreg.h>
#include <linux/fd.h>
+#include <linux/errno.h>
+#ifdef HHB_SYSMACROS
+#include <linux/system.h>
+#endif
+
#include <asm/system.h>
#include <asm/io.h>
#include <asm/segment.h>
-#include <errno.h>
#define MAJOR_NR 2
#include "blk.h"
@@ -68,6 +80,7 @@ __asm__("outb %0,%1\n\tjmp 1f\n1:\tjmp 1f\n1:"::"a" ((char) (val)),"i" (port))
#define TYPE(x) ((x)>>2)
#define DRIVE(x) ((x)&0x03)
+
/*
* Note that MAX_ERRORS=X doesn't imply that we retry every bad read
* max X times - some types of errors increase the errorcount by 2 or
@@ -79,17 +92,21 @@ __asm__("outb %0,%1\n\tjmp 1f\n1:\tjmp 1f\n1:"::"a" ((char) (val)),"i" (port))
* Maximum disk size (in kilobytes). This default is used whenever the
* current disk size is unknown.
*/
-
#define MAX_DISK_SIZE 1440
/*
* Maximum number of sectors in a track buffer. Track buffering is disabled
* if tracks are bigger.
*/
-
#define MAX_BUFFER_SECTORS 18
/*
+ * The DMA channel used by the floppy controller cannot access data at
+ * addresses >= 1MB
+ */
+#define LAST_DMA_ADDR (0x100000 - BLOCK_SIZE)
+
+/*
* globals used by 'result()'
*/
#define MAX_REPLIES 7
@@ -100,16 +117,12 @@ static unsigned char reply_buffer[MAX_REPLIES];
#define ST3 (reply_buffer[3])
/*
- * This struct defines the different floppy types. Unlike minix
- * linux doesn't have a "search for right type"-type, as the code
- * for that is convoluted and weird. I've got enough problems with
- * this driver as it is.
+ * This struct defines the different floppy types.
*
- * The 'stretch' tells if the tracks need to be boubled for some
+ * The 'stretch' tells if the tracks need to be doubled for some
* types (ie 360kB diskette in 1.2MB drive etc). Others should
* be self-explanatory.
*/
-
static struct floppy_struct floppy_type[] = {
{ 0, 0,0, 0,0,0x00,0x00,0x00,0x00,NULL }, /* no testing */
{ 720, 9,2,40,0,0x2A,0x02,0xDF,0x50,NULL }, /* 360kB PC diskettes */
@@ -121,8 +134,11 @@ static struct floppy_struct floppy_type[] = {
{ 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,NULL }, /* 1.44MB diskette */
};
-/* For auto-detection. Each drive type has a pair of formats to try. */
-
+/*
+ * Auto-detection. Each drive type has a pair of formats which are
+ * used in succession to try to read the disk. If the FDC cannot lock onto
+ * the disk, the next format is tried. This uses the variable 'probing'.
+ */
static struct floppy_struct floppy_types[] = {
{ 720, 9,2,40,0,0x2A,0x02,0xDF,0x50,"360k/PC" }, /* 360kB PC diskettes */
{ 720, 9,2,40,0,0x2A,0x02,0xDF,0x50,"360k/PC" }, /* 360kB PC diskettes */
@@ -135,16 +151,15 @@ static struct floppy_struct floppy_types[] = {
};
/* Auto-detection: Disk type used until the next media change occurs. */
-
struct floppy_struct *current_type[4] = { NULL, NULL, NULL, NULL };
/* This type is tried first. */
-
struct floppy_struct *base_type[4];
-/* User-provided type information. current_type points to the respective entry
- of this array. */
-
+/*
+ * User-provided type information. current_type points to
+ * the respective entry of this array.
+ */
struct floppy_struct user_params[4];
static int floppy_sizes[] ={
@@ -158,48 +173,61 @@ static int floppy_sizes[] ={
1440,1440,1440,1440
};
-/* The driver is trying to determine the correct media format while probing
- is set. rw_interrupts clears it after a successful access. */
-
+/*
+ * The driver is trying to determine the correct media format
+ * while probing is set. rw_interrupt() clears it after a
+ * successful access.
+ */
static int probing = 0;
-/* (User-provided) media information is _not_ discarded after a media change
- if the corresponding keep_data flag is non-zero. Positive values are
- decremented after each probe. */
-
+/*
+ * (User-provided) media information is _not_ discarded after a media change
+ * if the corresponding keep_data flag is non-zero. Positive values are
+ * decremented after each probe.
+ */
static int keep_data[4] = { 0,0,0,0 };
-/* Announce successful media type detection and media information loss after
- disk changes. */
-
+/*
+ * Announce successful media type detection and media information loss after
+ * disk changes.
+ */
static ftd_msg[4] = { 1,1,1,1 };
-/* Synchronization of FDC access. */
+/* Prevent "aliased" accesses. */
+
+static fd_ref[4] = { 0,0,0,0 };
+static fd_device[4] = { 0,0,0,0 };
+/* Synchronization of FDC access. */
static volatile int format_status = FORMAT_NONE, fdc_busy = 0;
static struct wait_queue *fdc_wait = NULL, *format_done = NULL;
/* Errors during formatting are counted here. */
-
static int format_errors;
/* Format request descriptor. */
-
static struct format_descr format_req;
-/* Current device number. Taken either from the block header or from the
- format request descriptor. */
-
+/*
+ * Current device number. Taken either from the block header or from the
+ * format request descriptor.
+ */
#define CURRENT_DEVICE (format_status == FORMAT_BUSY ? format_req.device : \
(CURRENT->dev))
/* Current error count. */
-
#define CURRENT_ERRORS (format_status == FORMAT_BUSY ? format_errors : \
(CURRENT->errors))
/*
- * Rate is 0 for 500kb/s, 2 for 300kbps, 1 for 250kbps
+ * Treshold for reporting FDC errors to the console.
+ * Setting this to zero may flood your screen when using
+ * ultra cheap floppies ;-)
+ */
+static unsigned short min_report_error_cnt[4] = {2, 2, 2, 2};
+
+/*
+ * Rate is 0 for 500kb/s, 1 for 300kbps, 2 for 250kbps
* Spec1 is 0xSH, where S is stepping rate (F=1ms, E=2ms, D=3ms etc),
* H is head unload time (1=16ms, 2=32ms, etc)
*
@@ -207,7 +235,14 @@ static struct format_descr format_req;
* and ND is set means no DMA. Hardcoded to 6 (HLD=6ms, use DMA).
*/
-extern char tmp_floppy_area[1024];
+/*
+ * Track buffer and block buffer (in case track buffering doesn't work).
+ * Because these are written to by the DMA controller, they must
+ * not contain a 64k byte boundary crossing, or data will be
+ * corrupted/lost. Alignment of these is enforced in boot/head.s.
+ * Note that you must not change the sizes below without updating head.s.
+ */
+extern char tmp_floppy_area[BLOCK_SIZE];
extern char floppy_track_buffer[512*2*MAX_BUFFER_SECTORS];
static void redo_fd_request(void);
@@ -219,7 +254,7 @@ static void redo_fd_request(void);
*/
#define NO_TRACK 255
-static int read_track = 0; /* flag to indicate if we want to read all track */
+static int read_track = 0; /* flag to indicate if we want to read entire track */
static int buffer_track = -1;
static int buffer_drive = -1;
static int cur_spec1 = -1;
@@ -232,6 +267,7 @@ static unsigned char track = 0;
static unsigned char seek_track = 0;
static unsigned char current_track = NO_TRACK;
static unsigned char command = 0;
+static unsigned char fdc_version = FDC_TYPE_STD; /* FDC version code */
unsigned char selected = 0;
struct wait_queue * wait_on_floppy_select = NULL;
@@ -321,13 +357,14 @@ static void setup_DMA(void)
buffer_drive = buffer_track = -1;
count = floppy->sect*2*512;
addr = (long) floppy_track_buffer;
- } else if (addr >= 0x100000) {
+ } else if (addr >= LAST_DMA_ADDR) {
addr = (long) tmp_floppy_area;
if (command == FD_WRITE)
copy_buffer(CURRENT->buffer,tmp_floppy_area);
}
/* mask DMA 2 */
cli();
+#ifndef HHB_SYSMACROS
immoutb_p(4|2,10);
/* output command byte. I don't know why, but everyone (minix, */
/* sanches & canton) output this twice, first to 12 then to 11 */
@@ -350,6 +387,14 @@ static void setup_DMA(void)
immoutb_p(count,5);
/* activate DMA 2 */
immoutb_p(0|2,10);
+#else /* just to show off my macros -- hhb */
+ DISABLE_DMA(DMA2);
+ CLEAR_DMA_FF(DMA2);
+ SET_DMA_MODE(DMA2, (command == FD_READ)? DMA_MODE_READ : DMA_MODE_WRITE);
+ SET_DMA_ADDR(DMA2, addr);
+ SET_DMA_COUNT(DMA2, count);
+ ENABLE_DMA(DMA2);
+#endif
sti();
}
@@ -380,11 +425,14 @@ static int result(void)
return -1;
for (counter = 0 ; counter < 10000 ; counter++) {
status = inb_p(FD_STATUS)&(STATUS_DIR|STATUS_READY|STATUS_BUSY);
- if (status == STATUS_READY)
+ if (status == STATUS_READY) {
return i;
+ }
if (status == (STATUS_DIR|STATUS_READY|STATUS_BUSY)) {
- if (i >= MAX_REPLIES)
+ if (i >= MAX_REPLIES) {
+ printk("floppy_stat reply overrun\n");
break;
+ }
reply_buffer[i++] = inb_p(FD_DATA);
}
}
@@ -409,23 +457,103 @@ static void bad_flp_intr(void)
}
/*
- * Ok, this interrupt is called after a DMA read/write has succeeded,
- * so we check the results, and copy any buffers.
+ * This has only been tested for the case fdc_version == FDC_TYPE_STD.
+ * In case you have a 82077 and want to test it, you'll have to compile
+ * with `FDC_FIFO_UNTESTED' defined. You may also want to add support for
+ * recognizing drives with vertical recording support.
+ */
+static void configure_fdc_mode(void)
+{
+ if (fdc_version == FDC_TYPE_82077) {
+ /* Enhanced version with FIFO & vertical recording. */
+ output_byte(FD_CONFIGURE);
+ output_byte(0);
+ output_byte(0x1A); /* FIFO on, polling off, 10 byte treshold */
+ output_byte(0); /* precompensation from track 0 upwards */
+ printk(DEVICE_NAME ": FIFO enabled\n");
+ }
+} /* configure_fdc_mode */
+
+
+static void tell_sector(int nr)
+{
+ if (nr!=7) {
+ printk(" -- FDC reply errror");
+ reset = 1;
+ } else
+ printk(": track %d, head %d, sector %d", reply_buffer[3],
+ reply_buffer[4], reply_buffer[5]);
+} /* tell_sector */
+
+
+/*
+ * Ok, this interrupt is called after a DMA read/write has succeeded
+ * or failed, so we check the results, and copy any buffers.
+ * hhb: Added better error reporting.
*/
static void rw_interrupt(void)
{
char * buffer_area;
+ int nr;
+ char bad;
+
+ nr = result();
+ /* check IC to find cause of interrupt */
+ switch ((ST0 & ST0_INTR)>>6) {
+ case 1: /* error occured during command execution */
+ bad = 1;
+ if (ST1 & ST1_WP) {
+ printk(DEVICE_NAME ": Drive %d is write protected\n", current_drive);
+ floppy_deselect(current_drive);
+ request_done(0);
+ bad = 0;
+ } else if (ST1 & ST1_OR) {
+ printk(DEVICE_NAME ": Over/Underrun - retrying\n");
+ /* could continue from where we stopped, but ... */
+ bad = 0;
+ } else if (CURRENT_ERRORS > min_report_error_cnt[ST0 & ST0_DS]) {
+ printk(DEVICE_NAME " %d: ", ST0 & ST0_DS);
+ if (ST0 & ST0_ECE) {
+ printk("Recalibrate failed!");
+ } else if (ST2 & ST2_CRC) {
+ printk("data CRC error");
+ tell_sector(nr);
+ } else if (ST1 & ST1_CRC) {
+ printk("CRC error");
+ tell_sector(nr);
+ } else if ((ST1 & (ST1_MAM|ST1_ND)) || (ST2 & ST2_MAM)) {
+ if (!probing) {
+ printk("sector not found");
+ tell_sector(nr);
+ } else
+ printk("probe failed...");
+ } else if (ST2 & ST2_WC) { /* seek error */
+ printk("wrong cylinder");
+ } else if (ST2 & ST2_BC) { /* cylinder marked as bad */
+ printk("bad cylinder");
+ } else {
+ printk("unknown error. ST[0..3] are: 0x%x 0x%x 0x%x 0x%x\n", ST0, ST1, ST2, ST3);
+ }
+ printk("\n");
- if (result() != 7 || (ST0 & 0xf8) || (ST1 & 0xbf) || (ST2 & 0x73)) {
- if (ST1 & 0x02) {
- printk("Drive %d is write protected\n\r",current_drive);
- floppy_deselect(current_drive);
+ }
+ if (bad)
+ bad_flp_intr();
+ redo_fd_request();
+ return;
+ case 2: /* invalid command given */
+ printk(DEVICE_NAME ": Invalid FDC command given!\n");
request_done(0);
- } else
+ return;
+ case 3:
+ printk(DEVICE_NAME ": Abnormal termination caused by polling\n");
bad_flp_intr();
- redo_fd_request();
- return;
+ redo_fd_request();
+ return;
+ default: /* (0) Normal command termination */
+ break;
}
+
if (probing) {
int drive = MINOR(CURRENT->dev);
@@ -443,7 +571,7 @@ static void rw_interrupt(void)
((sector-1 + head*floppy->sect)<<9);
copy_buffer(buffer_area,CURRENT->buffer);
} else if (command == FD_READ &&
- (unsigned long)(CURRENT->buffer) >= 0x100000)
+ (unsigned long)(CURRENT->buffer) >= LAST_DMA_ADDR)
copy_buffer(tmp_floppy_area,CURRENT->buffer);
floppy_deselect(current_drive);
request_done(1);
@@ -499,6 +627,7 @@ static void seek_interrupt(void)
/* sense drive status */
output_byte(FD_SENSEI);
if (result() != 2 || (ST0 & 0xF8) != 0x20 || ST1 != seek_track) {
+ printk(DEVICE_NAME ": seek failed\n");
recalibrate = 1;
bad_flp_intr();
redo_fd_request();
@@ -508,6 +637,34 @@ static void seek_interrupt(void)
setup_rw_floppy();
}
+/* Set perpendicular mode as required, based on data rate, if supported.
+ * 80277: 1Mbps data rate only possible with 82077-1.
+ * Untested!! TODO: increase MAX_BUFFER_SECTORS, add floppy_type entries.
+ */
+static void inline perpendicular_mode(unsigned char rate)
+{
+ if (fdc_version == FDC_TYPE_82077) {
+ output_byte(FD_PERPENDICULAR);
+ if (rate & 0x40) {
+ unsigned char r = rate & 0x03;
+ if (r == 0)
+ output_byte(2); /* perpendicular, 500 kbps */
+ else if (r == 3)
+ output_byte(3); /* perpendicular, 1Mbps */
+ else {
+ printk(DEVICE_NAME ": Invalid data rate for perpendicular mode!\n");
+ reset = 1;
+ }
+ } else
+ output_byte(0); /* conventional mode */
+ } else {
+ if (rate & 0x40) {
+ printk(DEVICE_NAME ": perpendicular mode not supported by FDC.\n");
+ reset = 1;
+ }
+ }
+} /* perpendicular_mode */
+
/*
* This routine is called when everything should be correctly set up
* for the transfer (ie floppy motor is on and the correct floppy is
@@ -523,8 +680,11 @@ static void transfer(void)
output_byte(cur_spec1); /* hut etc */
output_byte(6); /* Head load time =6ms, DMA */
}
- if (cur_rate != floppy->rate)
- outb_p(cur_rate = floppy->rate,FD_DCR);
+ if (cur_rate != floppy->rate) {
+ /* use bit 6 of floppy->rate to indicate perpendicular mode */
+ perpendicular_mode(floppy->rate);
+ outb_p(cur_rate = ((floppy->rate)) & ~0x40, FD_DCR);
+ }
if (reset) {
redo_fd_request();
return;
@@ -548,7 +708,7 @@ static void transfer(void)
* Special case - used after a unexpected interrupt (or reset)
*/
-static void recalibrate_floppy();
+static void recalibrate_floppy(void);
static void recal_interrupt(void)
{
@@ -565,6 +725,7 @@ static void unexpected_floppy_interrupt(void)
{
current_track = NO_TRACK;
output_byte(FD_SENSEI);
+ printk(DEVICE_NAME ": unexpected interrupt\n");
if (result()!=2 || (ST0 & 0xE0) == 0x60)
reset = 1;
else
@@ -582,13 +743,21 @@ static void recalibrate_floppy(void)
redo_fd_request();
}
+/*
+ * Must do 4 FD_SENSEIs after reset because of ``drive polling''.
+ */
static void reset_interrupt(void)
{
- output_byte(FD_SENSEI);
- (void) result();
+ short i;
+
+ for (i=0; i<4; i++) {
+ output_byte(FD_SENSEI);
+ (void) result();
+ }
output_byte(FD_SPECIFY);
output_byte(cur_spec1); /* hut etc */
output_byte(6); /* Head load time =6ms, DMA */
+ configure_fdc_mode(); /* reprogram if smart fdc */
if (!recover) redo_fd_request();
else {
recalibrate_floppy();
@@ -676,7 +845,8 @@ static void floppy_on_interrupt(void)
floppy_sizes[current_drive] = MAX_DISK_SIZE;
}
/* Forcing the drive to seek makes the "media changed" condition go away.
- There should be a cleaner solution for that ... */
+ * There should be a cleaner solution for that ...
+ */
if (!reset && !recalibrate) {
do_floppy = (current_track && current_track != NO_TRACK)
? shake_zero : shake_one;
@@ -711,6 +881,7 @@ static void setup_format_params(void)
unsigned char *here = (unsigned char *) tmp_floppy_area;
int count;
+ /* XXX: should do a check to see this fits in tmp_floppy_area!! */
for (count = 1; count <= floppy->sect; count++) {
*here++ = track;
*here++ = head;
@@ -726,10 +897,12 @@ static void redo_fd_request(void)
int device;
repeat:
- if (format_status == FORMAT_WAIT) format_status = FORMAT_BUSY;
+ if (format_status == FORMAT_WAIT)
+ format_status = FORMAT_BUSY;
if (format_status != FORMAT_BUSY) {
if (!CURRENT) {
- if (!fdc_busy) panic("FDC access conflict");
+ if (!fdc_busy)
+ printk("FDC access conflict");
fdc_busy = 0;
wake_up(&fdc_wait);
CLEAR_INTR;
@@ -759,9 +932,10 @@ repeat:
}
}
if (format_status != FORMAT_BUSY) {
- if (current_drive != CURRENT_DEV)
+ if (current_drive != CURRENT_DEV) {
current_track = NO_TRACK;
- current_drive = CURRENT_DEV;
+ current_drive = CURRENT_DEV;
+ }
block = CURRENT->sector;
if (block+2 > floppy->size) {
request_done(0);
@@ -781,8 +955,7 @@ repeat:
request_done(0);
goto repeat;
}
- }
- else {
+ } else {
if (current_drive != (format_req.device & 3))
current_track = NO_TRACK;
current_drive = format_req.device & 3;
@@ -918,6 +1091,9 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
case FDMSGOFF:
ftd_msg[drive] = 0;
break;
+ case FDSETEMSGTRESH:
+ min_report_error_cnt[drive] = (unsigned short) (param & 0x0f);
+ break;
default:
return -EINVAL;
}
@@ -956,9 +1132,26 @@ static void config_types(void)
printk("\r\n");
}
+/*
+ * floppy_open check for aliasing (/dev/fd0 can be the same as
+ * /dev/PS0 etc), and disallows simultaneous access to the same
+ * drive with different device numbers.
+ */
static int floppy_open(struct inode * inode, struct file * filp)
{
- if (filp->f_mode)
+ int drive;
+ int old_dev;
+
+ drive = inode->i_rdev & 3;
+ old_dev = fd_device[drive];
+ if (fd_ref[drive])
+ if (old_dev != inode->i_rdev)
+ return -EBUSY;
+ fd_ref[drive]++;
+ fd_device[drive] = inode->i_rdev;
+ if (old_dev && old_dev != inode->i_rdev)
+ invalidate_buffers(old_dev);
+ if (filp && filp->f_mode)
check_disk_change(inode->i_rdev);
return 0;
}
@@ -966,6 +1159,10 @@ static int floppy_open(struct inode * inode, struct file * filp)
static void floppy_release(struct inode * inode, struct file * filp)
{
sync_dev(inode->i_rdev);
+ if (!fd_ref[inode->i_rdev & 3]--) {
+ printk("floppy_release with fd_ref == 0");
+ fd_ref[inode->i_rdev & 3] = 0;
+ }
}
static struct file_operations floppy_fops = {
@@ -979,7 +1176,24 @@ static struct file_operations floppy_fops = {
floppy_release /* release */
};
-static void floppy_interrupt(int cpl)
+
+/*
+ * The version command is not supposed to generate an interrupt, but
+ * my FDC does, except when booting in SVGA screen mode.
+ * When it does generate an interrupt, it doesn't return any status bytes.
+ * It appears to have something to do with the version command...
+ */
+static void ignore_interrupt(void)
+{
+ if (result() != 0) {
+ printk(DEVICE_NAME ": weird interrupt ignored\n");
+ reset = 1;
+ }
+ CLEAR_INTR; /* ignore only once */
+}
+
+
+static void floppy_interrupt(int unused)
{
void (*handler)(void) = DEVICE_INTR;
@@ -990,9 +1204,8 @@ static void floppy_interrupt(int cpl)
}
/*
- * This is the harddisk IRQ descruption. The SA_INTERRUPT in sa_flags
- * means we run the IRQ-handler with interrupts disabled: this is bad for
- * interrupt latency, but may be safer...
+ * This is the floppy IRQ description. The SA_INTERRUPT in sa_flags
+ * means we run the IRQ-handler with interrupts disabled.
*/
static struct sigaction floppy_sigaction = {
floppy_interrupt,
@@ -1012,4 +1225,19 @@ void floppy_init(void)
config_types();
if (irqaction(FLOPPY_IRQ,&floppy_sigaction))
printk("Unable to grab IRQ%d for the floppy driver\n",FLOPPY_IRQ);
+
+ /* Try to determine the floppy controller type */
+ DEVICE_INTR = ignore_interrupt; /* don't ask ... */
+ output_byte(FD_VERSION); /* get FDC version code */
+ if (result() != 1) {
+ printk(DEVICE_NAME ": FDC failed to return version byte\n");
+ fdc_version = FDC_TYPE_STD;
+ } else
+ fdc_version = reply_buffer[0];
+ if (fdc_version != FDC_TYPE_STD)
+ printk(DEVICE_NAME ": FDC version 0x%x\n", fdc_version);
+#ifndef FDC_FIFO_UNTESTED
+ fdc_version = FDC_TYPE_STD; /* force std fdc type; can't test other. */
+#endif
+ configure_fdc_mode();
}
diff --git a/kernel/blk_drv/genhd.c b/kernel/blk_drv/genhd.c
new file mode 100644
index 0000000..6618ce1
--- /dev/null
+++ b/kernel/blk_drv/genhd.c
@@ -0,0 +1,195 @@
+/*
+ * Code extracted from
+ * linux/kernel/hd.c
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ */
+
+/*
+ * Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug
+ * in the early extended-partition checks and added DM partitions
+ */
+
+#include <linux/config.h>
+#include <linux/fs.h>
+#include <linux/genhd.h>
+#include <linux/kernel.h>
+struct gendisk *gendisk_head = NULL;
+
+static int current_minor = 0;
+extern int *blk_size[];
+/*
+ * Create devices for each logical partition in an extended partition.
+ * The logical partitions form a linked list, with each entry being
+ * a partition table with two entries. The first entry
+ * is the real data partition (with a start relative to the partition
+ * table start). The second is a pointer to the next logical partition
+ * (with a start relative to the entire extended partition).
+ * We do not create a Linux partition for the partition tables, but
+ * only for the actual data partitions.
+ */
+
+static void extended_partition(struct gendisk *hd, int dev)
+{
+ struct buffer_head *bh;
+ struct partition *p;
+ unsigned long first_sector, this_sector;
+ int mask = (1 << hd->minor_shift) - 1;
+
+ first_sector = hd->part[MINOR(dev)].start_sect;
+ this_sector = first_sector;
+
+ while (1) {
+ if ((current_minor & mask) >= (4 + hd->max_p))
+ return;
+ if (!(bh = bread(dev,0,1024))) {
+ printk("Unable to read partition table of device %04x\n",dev);
+ return;
+ }
+ /*
+ * This block is from a device that we're about to stomp on.
+ * So make sure nobody thinks this block is usable.
+ */
+ bh->b_dirt=0;
+ bh->b_uptodate=0;
+ if (*(unsigned short *) (bh->b_data+510) == 0xAA55) {
+ p = 0x1BE + (void *)bh->b_data;
+ /*
+ * Process the first entry, which should be the real
+ * data partition.
+ */
+ if (p->sys_ind == EXTENDED_PARTITION ||
+ !(hd->part[current_minor].nr_sects = p->nr_sects))
+ goto done; /* shouldn't happen */
+ hd->part[current_minor].start_sect = this_sector + p->start_sect;
+ printk(" Logical part %d start %d size %d end %d\n\r",
+ current_minor, hd->part[current_minor].start_sect,
+ hd->part[current_minor].nr_sects,
+ hd->part[current_minor].start_sect +
+ hd->part[current_minor].nr_sects - 1);
+ current_minor++;
+ p++;
+ /*
+ * Process the second entry, which should be a link
+ * to the next logical partition. Create a minor
+ * for this just long enough to get the next partition
+ * table. The minor will be reused for the real
+ * data partition.
+ */
+ if (p->sys_ind != EXTENDED_PARTITION ||
+ !(hd->part[current_minor].nr_sects = p->nr_sects))
+ goto done; /* no more logicals in this partition */
+ hd->part[current_minor].start_sect = first_sector + p->start_sect;
+ this_sector = first_sector + p->start_sect;
+ dev = ((hd->major) << 8) | current_minor;
+ brelse(bh);
+ } else
+ goto done;
+ }
+done:
+ brelse(bh);
+}
+
+static void check_partition(struct gendisk *hd, unsigned int dev)
+{
+ int i, minor = current_minor;
+ struct buffer_head *bh;
+ struct partition *p;
+ unsigned long first_sector;
+
+ first_sector = hd->part[MINOR(dev)].start_sect;
+
+ if (!(bh = bread(dev,0,1024))) {
+ printk("Unable to read partition table of device %04x\n",dev);
+ return;
+ }
+ printk("%s%d :\n\r", hd->major_name, minor >> hd->minor_shift);
+ current_minor += 4; /* first "extra" minor */
+ if (*(unsigned short *) (bh->b_data+510) == 0xAA55) {
+ p = 0x1BE + (void *)bh->b_data;
+ for (i=1 ; i<=4 ; minor++,i++,p++) {
+ if (!(hd->part[minor].nr_sects = p->nr_sects))
+ continue;
+ hd->part[minor].start_sect = first_sector + p->start_sect;
+ printk(" part %d start %d size %d end %d \n\r", i,
+ hd->part[minor].start_sect, hd->part[minor].nr_sects,
+ hd->part[minor].start_sect + hd->part[minor].nr_sects - 1);
+ if ((current_minor & 0x3f) >= 60)
+ continue;
+ if (p->sys_ind == EXTENDED_PARTITION) {
+ extended_partition(hd, (hd->major << 8) | minor);
+ }
+ }
+ /*
+ * check for Disk Manager partition table
+ */
+ if (*(unsigned short *) (bh->b_data+0xfc) == 0x55AA) {
+ p = 0x1BE + (void *)bh->b_data;
+ for (i = 4 ; i < 16 ; i++, current_minor++) {
+ p--;
+ if ((current_minor & 0x3f) >= 60)
+ break;
+ if (!(p->start_sect && p->nr_sects))
+ continue;
+ hd->part[current_minor].start_sect = p->start_sect;
+ hd->part[current_minor].nr_sects = p->nr_sects;
+ printk(" DM part %d start %d size %d end %d\n\r",
+ current_minor,
+ hd->part[current_minor].start_sect,
+ hd->part[current_minor].nr_sects,
+ hd->part[current_minor].start_sect +
+ hd->part[current_minor].nr_sects - 1);
+ }
+ }
+ } else
+ printk("Bad partition table on dev %04x\n",dev);
+ brelse(bh);
+}
+
+static void setup_dev(struct gendisk *dev)
+{
+ int i;
+ int j = dev->max_nr * dev->max_p;
+ int major = dev->major << 8;
+ int drive;
+
+
+ for (i = 0 ; i < j; i++) {
+ dev->part[i].start_sect = 0;
+ dev->part[i].nr_sects = 0;
+ }
+ dev->init();
+ for (drive=0 ; drive<dev->nr_real ; drive++) {
+ current_minor = 1+(drive<<dev->minor_shift);
+ check_partition(dev, major+(drive<<dev->minor_shift));
+ }
+ for (i=0 ; i < j ; i++)
+ dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);
+ blk_size[dev->major] = dev->sizes;
+}
+
+/* This may be used only once, enforced by 'static int callable' */
+int sys_setup(void * BIOS)
+{
+ static int callable = 1;
+ struct gendisk *p;
+ int nr=0;
+
+ if (!callable)
+ return -1;
+ callable = 0;
+
+ for (p = gendisk_head ; p ; p=p->next) {
+ setup_dev(p);
+ nr += p->nr_real;
+ }
+
+ if (nr)
+ printk("Partition table%s ok.\n\r",(nr>1)?"s":"");
+
+#ifdef RAMDISK
+ rd_load();
+#endif
+ mount_root();
+ return (0);
+}
diff --git a/kernel/blk_drv/hd.c b/kernel/blk_drv/hd.c
index 8ff900d..b1620d2 100644
--- a/kernel/blk_drv/hd.c
+++ b/kernel/blk_drv/hd.c
@@ -1,7 +1,7 @@
/*
* linux/kernel/hd.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
@@ -16,17 +16,19 @@
* in the early extended-partition checks and added DM partitions
*/
-#define HD_IRQ 14
+#include <linux/config.h>
+#ifdef CONFIG_BLK_DEV_HD
-#include <errno.h>
-#include <signal.h>
+#define HD_IRQ 14
-#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/hdreg.h>
+#include <linux/genhd.h>
#define REALLY_SLOW_IO
#include <asm/system.h>
@@ -72,11 +74,7 @@ struct hd_i_struct hd_info[] = { {0,0,0,0,0,0},{0,0,0,0,0,0} };
static int NR_HD = 0;
#endif
-static struct hd_struct {
- long start_sect;
- long nr_sects;
-} hd[MAX_HD<<6]={{0,0},};
-
+static struct hd_struct hd[MAX_HD<<6]={{0,0},};
static int hd_sizes[MAX_HD<<6] = {0, };
#define port_read(port,buf,nr) \
@@ -85,209 +83,6 @@ __asm__("cld;rep;insw"::"d" (port),"D" (buf),"c" (nr):"cx","di")
#define port_write(port,buf,nr) \
__asm__("cld;rep;outsw"::"d" (port),"S" (buf),"c" (nr):"cx","si")
-extern void rd_load(void);
-
-static unsigned int current_minor;
-
-/*
- * Create devices for each logical partition in an extended partition.
- * The logical partitions form a linked list, with each entry being
- * a partition table with two entries. The first entry
- * is the real data partition (with a start relative to the partition
- * table start). The second is a pointer to the next logical partition
- * (with a start relative to the entire extended partition).
- * We do not create a Linux partition for the partition tables, but
- * only for the actual data partitions.
- */
-static void extended_partition(unsigned int dev)
-{
- struct buffer_head *bh;
- struct partition *p;
- unsigned long first_sector, this_sector;
-
- first_sector = hd[MINOR(dev)].start_sect;
- this_sector = first_sector;
-
- while (1) {
- if ((current_minor & 0x3f) >= 60)
- return;
- if (!(bh = bread(dev,0))) {
- printk("Unable to read partition table of device %04x\n",dev);
- return;
- }
- /*
- * This block is from a device that we're about to stomp on.
- * So make sure nobody thinks this block is usable.
- */
- bh->b_dirt=0;
- bh->b_uptodate=0;
- if (*(unsigned short *) (bh->b_data+510) == 0xAA55) {
- p = 0x1BE + (void *)bh->b_data;
- /*
- * Process the first entry, which should be the real
- * data partition.
- */
- if (p->sys_ind == EXTENDED_PARTITION ||
- !(hd[current_minor].nr_sects = p->nr_sects))
- goto done; /* shouldn't happen */
- hd[current_minor].start_sect = this_sector + p->start_sect;
- printk(" Logical part %d start %d size %d end %d\n\r",
- current_minor, hd[current_minor].start_sect,
- hd[current_minor].nr_sects,
- hd[current_minor].start_sect +
- hd[current_minor].nr_sects - 1);
- current_minor++;
- p++;
- /*
- * Process the second entry, which should be a link
- * to the next logical partition. Create a minor
- * for this just long enough to get the next partition
- * table. The minor will be reused for the real
- * data partition.
- */
- if (p->sys_ind != EXTENDED_PARTITION ||
- !(hd[current_minor].nr_sects = p->nr_sects))
- goto done; /* no more logicals in this partition */
- hd[current_minor].start_sect = first_sector + p->start_sect;
- this_sector = first_sector + p->start_sect;
- dev = 0x0300 | current_minor;
- brelse(bh);
- } else
- goto done;
- }
-done:
- brelse(bh);
-}
-
-static void check_partition(unsigned int dev)
-{
- int i, minor = current_minor;
- struct buffer_head *bh;
- struct partition *p;
- unsigned long first_sector;
-
- first_sector = hd[MINOR(dev)].start_sect;
- if (!(bh = bread(dev,0))) {
- printk("Unable to read partition table of device %04x\n",dev);
- return;
- }
- printk("Drive %d:\n\r",minor >> 6);
- current_minor += 4; /* first "extra" minor */
- if (*(unsigned short *) (bh->b_data+510) == 0xAA55) {
- p = 0x1BE + (void *)bh->b_data;
- for (i=1 ; i<=4 ; minor++,i++,p++) {
- if (!(hd[minor].nr_sects = p->nr_sects))
- continue;
- hd[minor].start_sect = first_sector + p->start_sect;
- printk(" part %d start %d size %d end %d \n\r", i,
- hd[minor].start_sect, hd[minor].nr_sects,
- hd[minor].start_sect + hd[minor].nr_sects - 1);
- if ((current_minor & 0x3f) >= 60)
- continue;
- if (p->sys_ind == EXTENDED_PARTITION) {
- extended_partition(0x0300 | minor);
- }
- }
- /*
- * check for Disk Manager partition table
- */
- if (*(unsigned short *) (bh->b_data+0xfc) == 0x55AA) {
- p = 0x1BE + (void *)bh->b_data;
- for (i = 4 ; i < 16 ; i++, current_minor++) {
- p--;
- if ((current_minor & 0x3f) >= 60)
- break;
- if (!(p->start_sect && p->nr_sects))
- continue;
- hd[current_minor].start_sect = p->start_sect;
- hd[current_minor].nr_sects = p->nr_sects;
- printk(" DM part %d start %d size %d end %d\n\r",
- current_minor,
- hd[current_minor].start_sect,
- hd[current_minor].nr_sects,
- hd[current_minor].start_sect +
- hd[current_minor].nr_sects - 1);
- }
- }
- } else
- printk("Bad partition table on dev %04x\n",dev);
- brelse(bh);
-}
-
-/* This may be used only once, enforced by 'static int callable' */
-int sys_setup(void * BIOS)
-{
- static int callable = 1;
- int i,drive;
- unsigned char cmos_disks;
-
- if (!callable)
- return -1;
- callable = 0;
-#ifndef HD_TYPE
- for (drive=0 ; drive<2 ; drive++) {
- hd_info[drive].cyl = *(unsigned short *) BIOS;
- hd_info[drive].head = *(unsigned char *) (2+BIOS);
- hd_info[drive].wpcom = *(unsigned short *) (5+BIOS);
- hd_info[drive].ctl = *(unsigned char *) (8+BIOS);
- hd_info[drive].lzone = *(unsigned short *) (12+BIOS);
- hd_info[drive].sect = *(unsigned char *) (14+BIOS);
- BIOS += 16;
- }
-
- /*
- We querry CMOS about hard disks : it could be that
- we have a SCSI/ESDI/etc controller that is BIOS
- compatable with ST-506, and thus showing up in our
- BIOS table, but not register compatable, and therefore
- not present in CMOS.
-
- Furthurmore, we will assume that our ST-506 drives
- <if any> are the primary drives in the system, and
- the ones reflected as drive 1 or 2.
-
- The first drive is stored in the high nibble of CMOS
- byte 0x12, the second in the low nibble. This will be
- either a 4 bit drive type or 0xf indicating use byte 0x19
- for an 8 bit type, drive 1, 0x1a for drive 2 in CMOS.
-
- Needless to say, a non-zero value means we have
- an AT controller hard disk for that drive.
-
-
- */
-
- if ((cmos_disks = CMOS_READ(0x12)) & 0xf0)
- if (cmos_disks & 0x0f)
- NR_HD = 2;
- else
- NR_HD = 1;
- else
- NR_HD = 0;
-#endif
- for (i = 0 ; i < (MAX_HD<<6) ; i++) {
- hd[i].start_sect = 0;
- hd[i].nr_sects = 0;
- }
- for (i = 0 ; i < NR_HD ; i++)
- hd[i<<6].nr_sects = hd_info[i].head*
- hd_info[i].sect*hd_info[i].cyl;
- for (drive=0 ; drive<NR_HD ; drive++) {
- current_minor = 1+(drive<<6);
- check_partition(0x0300+(drive<<6));
- }
- for (i=0 ; i<(MAX_HD<<6) ; i++)
- hd_sizes[i] = hd[i].nr_sects>>1 ;
- blk_size[MAJOR_NR] = hd_sizes;
- if (NR_HD)
- printk("Partition table%s ok.\n\r",(NR_HD>1)?"s":"");
-#ifdef RAMDISK
- rd_load();
-#endif
- mount_root();
- return (0);
-}
-
#if (HD_DELAY > 0)
unsigned long read_timer(void)
{
@@ -322,10 +117,13 @@ static int win_result(void)
if ((i & (BUSY_STAT | READY_STAT | WRERR_STAT | SEEK_STAT | ERR_STAT))
== (READY_STAT | SEEK_STAT))
- return(0); /* ok */
- if (i&1)
+ return 0; /* ok */
+ printk("HD: win_result: status = 0x%02x\n",i);
+ if (i&1) {
i=inb(HD_ERROR);
- return (1);
+ printk("HD: win_result: error = 0x%02x\n",i);
+ }
+ return 1;
}
static void hd_out(unsigned int drive,unsigned int nsect,unsigned int sect,
@@ -367,7 +165,7 @@ static int drive_busy(void)
if (c == (READY_STAT | SEEK_STAT))
return 0;
}
- printk("HD controller times out, c=%02x\n\r",c);
+ printk("HD controller times out, status = 0x%02x\n\r",c);
return(1);
}
@@ -416,12 +214,9 @@ repeat:
*/
void unexpected_hd_interrupt(void)
{
+ sti();
printk("Unexpected HD interrupt\n\r");
SET_TIMER;
-#if 0
- reset = 1;
- do_hd_request();
-#endif
}
static void bad_rw_intr(void)
@@ -436,6 +231,16 @@ static void bad_rw_intr(void)
recalibrate = 1;
}
+static inline int wait_DRQ(void)
+{
+ int retries = 100000;
+
+ while (--retries > 0)
+ if (inb_p(HD_STATUS) & DRQ_STAT)
+ return 0;
+ return -1;
+}
+
#define STAT_MASK (BUSY_STAT | READY_STAT | WRERR_STAT | SEEK_STAT | ERR_STAT)
#define STAT_OK (READY_STAT | SEEK_STAT)
@@ -444,23 +249,36 @@ static void read_intr(void)
int i;
i = (unsigned) inb_p(HD_STATUS);
- if (!(i & DRQ_STAT))
+ if ((i & STAT_MASK) != STAT_OK) {
+ printk("HD: read_intr: status = 0x%02x\n",i);
goto bad_read;
- if ((i & STAT_MASK) != STAT_OK)
+ }
+ if (wait_DRQ()) {
+ printk("HD: read_intr: no DRQ\n");
goto bad_read;
+ }
port_read(HD_DATA,CURRENT->buffer,256);
i = (unsigned) inb_p(HD_STATUS);
if (!(i & BUSY_STAT))
- if ((i & STAT_MASK) != STAT_OK)
+ if ((i & STAT_MASK) != STAT_OK) {
+ printk("HD: read_intr: second status = 0x%02x\n",i);
goto bad_read;
+ }
CURRENT->errors = 0;
CURRENT->buffer += 512;
CURRENT->sector++;
i = --CURRENT->nr_sectors;
- if (!i || (CURRENT->bh && !(i&1)))
+ --CURRENT->current_nr_sectors;
+#ifdef DEBUG
+ printk("hd%d : sector = %d, %d remaining to buffer = %08x\n",
+ MINOR(CURRENT->dev), CURRENT->sector, i, CURRENT->
+ buffer);
+#endif
+ if (!i || (CURRENT->bh && !SUBSECTOR(i)))
end_request(1);
if (i > 0) {
SET_INTR(&read_intr);
+ sti();
return;
}
#if (HD_DELAY > 0)
@@ -469,8 +287,10 @@ static void read_intr(void)
do_hd_request();
return;
bad_read:
- if (i & ERR_STAT)
+ if (i & ERR_STAT) {
i = (unsigned) inb(HD_ERROR);
+ printk("HD: read_intr: error = 0x%02x\n",i);
+ }
bad_rw_intr();
do_hd_request();
return;
@@ -481,18 +301,24 @@ static void write_intr(void)
int i;
i = (unsigned) inb_p(HD_STATUS);
- if ((i & STAT_MASK) != STAT_OK)
+ if ((i & STAT_MASK) != STAT_OK) {
+ printk("HD: write_intr: status = 0x%02x\n",i);
goto bad_write;
- if (CURRENT->nr_sectors > 1 && !(i & DRQ_STAT))
+ }
+ if (CURRENT->nr_sectors > 1 && wait_DRQ()) {
+ printk("HD: write_intr: no DRQ\n");
goto bad_write;
+ }
CURRENT->sector++;
i = --CURRENT->nr_sectors;
+ --CURRENT->current_nr_sectors;
CURRENT->buffer += 512;
- if (!i || (CURRENT->bh && !(i & 1)))
+ if (!i || (CURRENT->bh && !SUBSECTOR(i)))
end_request(1);
if (i > 0) {
SET_INTR(&write_intr);
port_write(HD_DATA,CURRENT->buffer,256);
+ sti();
} else {
#if (HD_DELAY > 0)
last_req = read_timer();
@@ -501,9 +327,13 @@ static void write_intr(void)
}
return;
bad_write:
- if (i & ERR_STAT)
+ sti();
+ if (i & ERR_STAT) {
i = (unsigned) inb(HD_ERROR);
+ printk("HD: write_intr: error = 0x%02x\n",i);
+ }
bad_rw_intr();
+ cli();
do_hd_request();
return;
}
@@ -520,30 +350,50 @@ static void recal_intr(void)
* best idea seems to just set reset, and start all over again.
*/
static void hd_times_out(void)
-{
+{
+ sti();
DEVICE_INTR = NULL;
reset = 1;
if (!CURRENT)
return;
printk("HD timeout\n\r");
cli();
- if (++CURRENT->errors >= MAX_ERRORS)
+ if (++CURRENT->errors >= MAX_ERRORS) {
+#ifdef DEBUG
+ printk("hd : too many errors.\n");
+#endif
end_request(0);
+ }
+
do_hd_request();
}
+/*
+ * The driver has been modified to enable interrupts a bit more: in order to
+ * do this we first (a) disable the timeout-interrupt and (b) clear the
+ * device-interrupt. This way the interrupts won't mess with out code (the
+ * worst that can happen is that an unexpected HD-interrupt comes in and
+ * sets the "reset" variable and starts the timer)
+ */
static void do_hd_request(void)
{
- int i,r;
unsigned int block,dev;
unsigned int sec,head,cyl;
unsigned int nsect;
+repeat:
+ DEVICE_INTR = NULL;
+ timer_active &= ~(1<<HD_TIMER);
+ sti();
INIT_REQUEST;
dev = MINOR(CURRENT->dev);
block = CURRENT->sector;
nsect = CURRENT->nr_sectors;
if (dev >= (NR_HD<<6) || block >= hd[dev].nr_sects) {
+#ifdef DEBUG
+ printk("hd%d : attempted read for sector %d past end of device at sector %d.\n",
+ block, hd[dev].nr_sects);
+#endif
end_request(0);
goto repeat;
}
@@ -554,9 +404,15 @@ static void do_hd_request(void)
head = block % hd_info[dev].head;
cyl = block / hd_info[dev].head;
sec++;
+#ifdef DEBUG
+ printk("hd%d : cyl = %d, head = %d, sector = %d, buffer = %08x\n",
+ dev, cyl, head, sec, CURRENT->buffer);
+#endif
+ cli();
if (reset) {
recalibrate = 1;
reset_hd();
+ sti();
return;
}
if (recalibrate) {
@@ -564,23 +420,25 @@ static void do_hd_request(void)
hd_out(dev,hd_info[dev].sect,0,0,0,WIN_RESTORE,&recal_intr);
if (reset)
goto repeat;
+ sti();
return;
}
if (CURRENT->cmd == WRITE) {
hd_out(dev,nsect,sec,head,cyl,WIN_WRITE,&write_intr);
if (reset)
goto repeat;
- for(i=0 ; i<10000 && !(r=inb_p(HD_STATUS)&DRQ_STAT) ; i++)
- /* nothing */ ;
- if (!r) {
+ if (wait_DRQ()) {
+ printk("HD: do_hd_request: no DRQ\n");
bad_rw_intr();
goto repeat;
}
port_write(HD_DATA,CURRENT->buffer,256);
+ sti();
} else if (CURRENT->cmd == READ) {
hd_out(dev,nsect,sec,head,cyl,WIN_READ,&read_intr);
if (reset)
goto repeat;
+ sti();
} else
panic("unknown hd-command");
}
@@ -623,6 +481,79 @@ static void hd_release(struct inode * inode, struct file * file)
sync_dev(inode->i_rdev);
}
+
+static void hd_geninit();
+
+static struct gendisk hd_gendisk = {
+ MAJOR_NR, /* Major number */
+ "hd", /* Major name */
+ 6, /* Bits to shift to get real from partition */
+ 1 << 6, /* Number of partitions per real */
+ MAX_HD, /* maximum number of real */
+ hd_geninit, /* init function */
+ hd, /* hd struct */
+ hd_sizes, /* block sizes */
+ 0, /* number */
+ (void *) hd_info, /* internal */
+ NULL /* next */
+};
+
+static void hd_geninit(void)
+{
+ int drive;
+#ifndef HD_TYPE
+ extern struct drive_info drive_info;
+ void *BIOS = (void *) &drive_info;
+ int cmos_disks, i;
+
+ for (drive=0 ; drive<2 ; drive++) {
+ hd_info[drive].cyl = *(unsigned short *) BIOS;
+ hd_info[drive].head = *(unsigned char *) (2+BIOS);
+ hd_info[drive].wpcom = *(unsigned short *) (5+BIOS);
+ hd_info[drive].ctl = *(unsigned char *) (8+BIOS);
+ hd_info[drive].lzone = *(unsigned short *) (12+BIOS);
+ hd_info[drive].sect = *(unsigned char *) (14+BIOS);
+ BIOS += 16;
+ }
+
+ /*
+ We querry CMOS about hard disks : it could be that
+ we have a SCSI/ESDI/etc controller that is BIOS
+ compatable with ST-506, and thus showing up in our
+ BIOS table, but not register compatable, and therefore
+ not present in CMOS.
+
+ Furthurmore, we will assume that our ST-506 drives
+ <if any> are the primary drives in the system, and
+ the ones reflected as drive 1 or 2.
+
+ The first drive is stored in the high nibble of CMOS
+ byte 0x12, the second in the low nibble. This will be
+ either a 4 bit drive type or 0xf indicating use byte 0x19
+ for an 8 bit type, drive 1, 0x1a for drive 2 in CMOS.
+
+ Needless to say, a non-zero value means we have
+ an AT controller hard disk for that drive.
+
+
+ */
+
+ if ((cmos_disks = CMOS_READ(0x12)) & 0xf0)
+ if (cmos_disks & 0x0f)
+ NR_HD = 2;
+ else
+ NR_HD = 1;
+ else
+ 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;
+
+ hd_gendisk.nr_real = NR_HD;
+}
+
static struct file_operations hd_fops = {
NULL, /* lseek - default */
block_read, /* read - general block-dev read */
@@ -634,7 +565,7 @@ static struct file_operations hd_fops = {
hd_release /* release */
};
-static void hd_interrupt(int cpl)
+static void hd_interrupt(int unused)
{
void (*handler)(void) = DEVICE_INTR;
@@ -643,6 +574,7 @@ static void hd_interrupt(int cpl)
if (!handler)
handler = unexpected_hd_interrupt;
handler();
+ sti();
}
/*
@@ -650,6 +582,9 @@ static void hd_interrupt(int cpl)
* means we run the IRQ-handler with interrupts disabled: this is bad for
* interrupt latency, but anything else has led to problems on some
* machines...
+ *
+ * We enable interrupts in some of the routines after making sure it's
+ * safe.
*/
static struct sigaction hd_sigaction = {
hd_interrupt,
@@ -662,7 +597,11 @@ void hd_init(void)
{
blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
blkdev_fops[MAJOR_NR] = &hd_fops;
+ hd_gendisk.next = gendisk_head;
+ gendisk_head = &hd_gendisk;
if (irqaction(HD_IRQ,&hd_sigaction))
printk("Unable to get IRQ%d for the harddisk driver\n",HD_IRQ);
timer_table[HD_TIMER].fn = hd_times_out;
}
+
+#endif
diff --git a/kernel/blk_drv/ll_rw_blk.c b/kernel/blk_drv/ll_rw_blk.c
index 0ef93b6..0a7005b 100644
--- a/kernel/blk_drv/ll_rw_blk.c
+++ b/kernel/blk_drv/ll_rw_blk.c
@@ -1,16 +1,17 @@
/*
* linux/kernel/blk_dev/ll_rw.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
* This handles all read/write requests to block devices
*/
-#include <errno.h>
-#include <linux/string.h>
#include <linux/sched.h>
#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+
#include <asm/system.h>
#include "blk.h"
@@ -136,6 +137,7 @@ static void add_request(struct blk_dev_struct * dev, struct request * req)
static void make_request(int major,int rw, struct buffer_head * bh)
{
+ unsigned int sector, count;
struct request * req;
int rw_ahead;
@@ -153,8 +155,10 @@ static void make_request(int major,int rw, struct buffer_head * bh)
printk("Bad block dev command, must be R/W/RA/WA\n");
return;
}
+ count = bh->b_size >> 9;
+ sector = bh->b_blocknr * count;
if (blk_size[major])
- if (blk_size[major][MINOR(bh->b_dev)] <= bh->b_blocknr) {
+ if (blk_size[major][MINOR(bh->b_dev)] < (sector + count)>>1) {
bh->b_dirt = bh->b_uptodate = 0;
return;
}
@@ -165,16 +169,16 @@ static void make_request(int major,int rw, struct buffer_head * bh)
}
repeat:
cli();
- if (major == 3 && (req = blk_dev[major].current_request)) {
+ if ((major == 3 || major == 8 )&& (req = blk_dev[major].current_request)) {
while (req = req->next) {
if (req->dev == bh->b_dev &&
!req->waiting &&
req->cmd == rw &&
- req->sector + req->nr_sectors == bh->b_blocknr << 1 &&
+ req->sector + req->nr_sectors == sector &&
req->nr_sectors < 254) {
req->bhtail->b_reqnext = bh;
req->bhtail = bh;
- req->nr_sectors += 2;
+ req->nr_sectors += count;
bh->b_dirt = 0;
sti();
return;
@@ -208,8 +212,9 @@ found: sti();
req->dev = bh->b_dev;
req->cmd = rw;
req->errors = 0;
- req->sector = bh->b_blocknr<<1;
- req->nr_sectors = 2;
+ req->sector = sector;
+ req->nr_sectors = count;
+ req->current_nr_sectors = count;
req->buffer = bh->b_data;
req->waiting = NULL;
req->bh = bh;
@@ -224,7 +229,7 @@ void ll_rw_page(int rw, int dev, int page, char * buffer)
unsigned int major = MAJOR(dev);
if (major >= NR_BLK_DEV || !(blk_dev[major].request_fn)) {
- printk("Trying to read nonexistent block-device\n\r");
+ printk("Trying to read nonexistent block-device %04x (%d)\n",dev,page*8);
return;
}
if (rw!=READ && rw!=WRITE)
@@ -250,6 +255,7 @@ repeat:
req->errors = 0;
req->sector = page<<3;
req->nr_sectors = 8;
+ req->current_nr_sectors = 8;
req->buffer = buffer;
req->waiting = &current->wait;
req->bh = NULL;
@@ -265,9 +271,14 @@ void ll_rw_block(int rw, struct buffer_head * bh)
if (!bh)
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;
+ return;
+ }
if ((major=MAJOR(bh->b_dev)) >= NR_BLK_DEV ||
!(blk_dev[major].request_fn)) {
- printk("ll_rw_block: Trying to read nonexistent block-device\n\r");
+ 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;
return;
}
@@ -331,6 +342,7 @@ repeat:
req->errors = 0;
req->sector = b[i] << 1;
req->nr_sectors = 2;
+ req->current_nr_sectors = 2;
req->buffer = buf;
req->waiting = &current->wait;
req->bh = NULL;
diff --git a/kernel/blk_drv/ramdisk.c b/kernel/blk_drv/ramdisk.c
index 833322f..195146d 100644
--- a/kernel/blk_drv/ramdisk.c
+++ b/kernel/blk_drv/ramdisk.c
@@ -4,9 +4,10 @@
* Written by Theodore Ts'o, 12/2/91
*/
-#include <linux/string.h>
#include <linux/config.h>
+#ifdef RAMDISK
+#include <linux/string.h>
#include <linux/sched.h>
#include <linux/minix_fs.h>
#include <linux/fs.h>
@@ -21,11 +22,12 @@
char *rd_start;
int rd_length = 0;
-void do_rd_request(void)
+static void do_rd_request(void)
{
int len;
char *addr;
+repeat:
INIT_REQUEST;
addr = rd_start + (CURRENT->sector << 9);
len = CURRENT->nr_sectors << 9;
@@ -119,7 +121,7 @@ void rd_load(void)
if (nblocks > 2)
bh = breada(ROOT_DEV, block, block+1, block+2, -1);
else
- bh = bread(ROOT_DEV, block);
+ bh = bread(ROOT_DEV, block, BLOCK_SIZE);
if (!bh) {
printk("I/O error on block %d, aborting load\n",
block);
@@ -136,3 +138,4 @@ void rd_load(void)
printk("\ndone\n");
ROOT_DEV=0x0101;
}
+#endif
diff --git a/kernel/blk_drv/scsi/7000fasst.c b/kernel/blk_drv/scsi/7000fasst.c
new file mode 100644
index 0000000..8a72be4
--- /dev/null
+++ b/kernel/blk_drv/scsi/7000fasst.c
@@ -0,0 +1,465 @@
+/* $Id: 7000fasst.c,v 1.1 1992/07/24 06:27:38 root Exp root $
+ * linux/kernel/7000fasst.c
+ *
+ * Copyright (C) 1992 Thomas Wuensche
+ * closely related to the aha1542 driver from Tommy Thorn
+ * ( as close as different hardware allows on a lowlevel-driver :-) )
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/head.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include "scsi.h"
+#include "hosts.h"
+
+struct mailbox{
+ unchar status;
+ unchar scbptr[3];
+};
+
+/* #define DEBUG */
+
+#include "7000fasst.h"
+#ifdef DEBUG
+#define DEB(x) x
+#else
+#define DEB(x)
+#endif
+
+/*static const char RCSid[] = "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/7000fasst.c,v 1.1 1992/07/24 06:27:38 root Exp root $";*/
+
+static struct scb scbs[OGMB_CNT];
+
+long wd7000fasst_WAITnexttimeout = 3000000;
+
+void (*wd7000fasst_do_done)() = NULL;
+extern void wd7000fasst_interrupt();
+void wd7000fasst_call_buh();
+
+static unchar controlstat = 0;
+static unchar wd7000fasst_hostno;
+
+#define wd7000fasst_intr_reset() outb(0,INTR_ACK)
+#define PC_IMR 0x21
+#define AT_IMR 0xa1
+
+#define wd7000fasst_enable_intr(){\
+ controlstat |= INT_EN;\
+ outb(controlstat,CONTROL);\
+ outb((inb((intr_chan<=7)?PC_IMR:AT_IMR))& ~0xff,(intr_chan<=7)?PC_IMR:AT_IMR);}
+
+#define wd7000fasst_disable_intr() outb(controlstat |= INT_EN, CONTROL)
+#define wd7000fasst_enable_dma() {\
+ controlstat |= DMA_EN;\
+ outb(controlstat,CONTROL);\
+ outb((DMA_CH|CASCADE),DMA_MODE_REG);\
+ outb(DMA_CH,DMA_MASK_REG);}
+
+#define wd7000fasst_disable_dma() {\
+ outb(DMA_CH|S_DMA_MASK,DMA_MASK_REG);\
+ controlstat &= ~DMA_EN;\
+ outb(controlstat,CONTROL);}
+
+#define WAIT(port, mask, allof, noneof) \
+ { register WAITbits; \
+ register WAITtimeout = wd7000fasst_WAITnexttimeout; \
+ while (1) { \
+ WAITbits = inb(port) & (mask); \
+ if ((WAITbits & (allof)) == (allof) && ((WAITbits & (noneof)) == 0)) \
+ break; \
+ if (--WAITtimeout == 0) goto fail; \
+ } \
+ }
+
+static void wd7000fasst_stat(void)
+{
+/* int s = inb(ASC_STAT), i = inb(INTR_STAT);*/
+/* printk("status = %x, intrflags = %x served %d last %x\n", s, i, intr_flag, intr_last);
+ printk("status=%x intrflags=%x\n", s, i);
+*/}
+
+static int wd7000fasst_out(unchar *cmdp, int len)
+{
+ while (len--)
+ {
+ WAIT(ASC_STAT, STATMASK, CMD_RDY, 0);
+ outb(*cmdp++, COMMAND);
+ }
+ return 0;
+ fail:
+ printk("wd7000fasst_out failed(%d): ", len+1); wd7000fasst_stat();
+ return 1;
+}
+
+int wd7000fasst_make_error_code(unsigned hosterr, unsigned scsierr)
+{
+#ifdef DEBUG
+ int in_error=hosterr;
+#endif
+ switch ((hosterr&0xff00)>>8){
+ case 0: /* It is reserved, should never happen */
+ hosterr=DID_ERROR;
+ break;
+ case 1: hosterr=DID_OK;
+ break;
+ case 2: /* Command complete with logged error */
+ /* My actual copies of the manual pages are unreadable
+ * For now we simply tell there is an error */
+ DEB(printk("Hosterror: VUE = %x\n",hosterr&0xff);)
+ switch (hosterr&0xff) {
+ default: DEB(printk("wd7000fasst_make_error_code: unknown hoststatus %x\n", hosterr);)
+ hosterr=DID_ERROR;
+ break;
+ }
+ break;
+ case 4: hosterr=DID_BAD_TARGET; /* Command failed to complete without SCSI status */
+ break;
+ case 5: hosterr=DID_RESET; /* Cmd terminated; Bus reset by external device */
+ break;
+ case 6: hosterr=DID_ERROR;/* Hardware Failure, requires host reset */
+ break;
+ case 7: hosterr=DID_RESET;
+ break;
+ case 8: hosterr=DID_OK;
+ printk("wd7000fasst: Linked command not implemented\n");
+ break;
+ }
+#ifdef DEBUG
+ if (scsierr||hosterr) printk("SCSI-Command error: SCSI %x HOST %x RETURN %x\n",scsierr,in_error,hosterr);
+#endif
+ return scsierr|(hosterr << 16);
+}
+
+/* The following is space for the Mailboxes */
+struct{ struct mailbox ombox[OGMB_CNT];
+ struct mailbox imbox[ICMB_CNT]; } mbstruct;
+
+int wd7000fasst_init(void)
+{ int i;
+ volatile int debug = 0;
+ /* Page 47 */
+ unchar init_block[]={ 1, 7, 0x18, 0x18, 0, 0, 0, 0, OGMB_CNT, ICMB_CNT };
+ /* Reset the adapter. I ought to make a hard reset, but it's not really nessesary */
+
+ DEB(printk("wd7000fasst_init called \n"));
+
+ outb(SCSI_RES|ASC_RES, CONTROL);
+ /* Wait at least 25 us */
+ for (i=0; i< 1000; i++) inb(ASC_STAT);
+ /* Now reset the reset */
+ outb(0,CONTROL);
+ debug = 1;
+ /* Expect Command Port Ready */
+ WAIT(ASC_STAT, STATMASK, CMD_RDY, 0);
+ DEB(printk("wd7000fasst_init: Power on Diagnostics finished\n"));
+ if ((i=inb(INTR_STAT))!=1)
+ printk("Power on Diagnostics error %x\n",i);
+
+ debug = 2;
+ /* Clear mbstruct */
+ memset(&mbstruct,0,sizeof (mbstruct));
+ /* Set up init block */
+ any2scsi(init_block+5,&mbstruct);
+ /* Execute init command */
+ wd7000fasst_out(init_block,sizeof(init_block));
+ DEB(printk("Init-Block :");
+ for (i=0;i<sizeof(init_block);i++) printk(" %x",init_block[i]);
+ printk("\n");)
+ /* Wait until init finished */
+ WAIT(ASC_STAT, STATMASK, CMD_RDY | ASC_INI, 0);
+ outb(2,COMMAND);
+ WAIT(ASC_STAT, STATMASK, CMD_RDY | ASC_INI, 0);
+ /* Enable Interrupt and DMA */
+ wd7000fasst_enable_dma();
+ wd7000fasst_call_buh();
+ DEB(printk("wd7000fasst_detect: enable interrupt channel %d\n", intr_chan));
+ wd7000fasst_enable_intr();
+ printk("wd7000fasst_init: Controller initialized\n");
+ return 1;
+ fail:
+ return 0; /* 0 = not ok */
+}
+
+/* What's this little function for? */
+char *wd7000fasst_info(void)
+{
+ static char buffer[] = "Western Digital 7000-FASST";
+ return buffer;
+}
+
+/* A "high" level interrupt handler */
+void wd7000fasst_intr_handle(void)
+{ struct scb * scbptr;
+ DEB(int len=sizeof (struct scb);)
+ DEB(int k;)
+ unsigned host_error,scsi_error;
+ int flag = inb(INTR_STAT);
+ void (*my_done)() = wd7000fasst_do_done;
+ int errstatus;
+ DEB(printk("WD Interrupt aufgetreten\n"));
+ if (!(inb(ASC_STAT)&0x80)){
+ printk("Interrupt without Interrupt\n");
+ wd7000fasst_intr_reset();
+ return;
+ }
+ wd7000fasst_do_done = NULL;
+ if (!my_done) {
+ printk("wd7000fasst_intr_handle: Unexpected interrupt\n");
+ wd7000fasst_intr_reset();
+ return;
+ }
+
+ /* is there mail for me :-) */
+ if ((flag&0xc0)==0xc0){
+ /* Ok, the interrupt is for an incoming mailbox */
+ /* We make the content available for the starter of the command */
+ DEB(if ((flag&0xc0)==0xc0) printk("INTR_STAT: %x mbstat: %x\n",flag,mbstruct.imbox[flag&0x3f].status));
+ if (mbstruct.imbox[flag&0x3f].status==0){
+ /* Something strange happened */
+ wd7000fasst_intr_reset();
+ return;
+ ;
+ }
+ scbptr=(struct scb *)scsi2int(mbstruct.imbox[flag&0x3f].scbptr);
+ DEB(printk("Datenbereiche aus %x ein %x \n",scbptr,&(scbs[flag&0x3f]));
+ printk("SCB after return:\n");
+ k=0;
+ while (len-- >0){
+ printk("%x ",*((unchar *)scbptr));
+ ((unchar *)scbptr)++;
+ if (++k==16){ printk("\n"); k=0; }
+ });
+ }
+ else { printk("Error in interrupt\n"); return; }
+ /* more error checking left out here */
+
+ scbptr=(struct scb *)scsi2int(mbstruct.imbox[flag&0x3f].scbptr);
+ host_error=scbptr->vue | mbstruct.imbox[flag&0x3f].status<<8;
+ scsi_error=scbptr->sretstat;
+ errstatus=wd7000fasst_make_error_code(host_error,scsi_error);
+ DEB(if (errstatus) printk("Target was %x\n",scbptr->idlun>>5);)
+ DEB(if (errstatus) printk("wd7000fasst_intr_handle: returning %6x\n", errstatus));
+ DEB(printk("wd7000fasst_intr_handle: Status of the finished command: %x\n",mbstruct.imbox[flag&0x3f].status));
+ /* I make a SCSI reset */
+ /* Left out */
+ my_done(wd7000fasst_hostno,errstatus);
+ wd7000fasst_intr_reset();
+ return;
+}
+
+volatile static int internal_done_flag = 0;
+volatile static int internal_done_errcode = 0;
+
+/* The following code queues a SCSI command */
+int wd7000fasst_queuecommand(unchar target, const void *cmnd, void *buff, int bufflen,
+ void (*done)(int, int))
+{
+ int i;
+#ifdef DEBUG
+ int j;
+#endif
+ unchar *cmd = (unchar *) cmnd;
+/* We first look for a free outgoing mailbox */
+ for (i=0;i<OGMB_CNT;i++){
+ if (mbstruct.ombox[i].status==0){
+ /* We found one, now set up the scb */
+ DEB(printk("Found outgoing mbox %x\n",i));
+ memset(&scbs[i], 0, sizeof(struct scb));
+ /* scbs[i].cdblen = (*cmd<=0x1f)?6:10; */ /* SCSI Command Descriptor Block Length */
+ memcpy(scbs[i].scbdata, cmd, (*cmd<=0x1f)?6:10);
+ scbs[i].op = 0; /* SCSI Initiator Command */
+ scbs[i].idlun = (target<<5)&0xe0; /* SCSI Target Id Bit 7-5 Target Id*/
+ any2scsi(scbs[i].dataptr,buff);
+ any2scsi(scbs[i].maxdata,bufflen);
+ scbs[i].direc=0x40; /* Disable direction check */
+ DEB(printk("Kommando fuer target %x ist: ",target);
+ for (j=0;j<12;j++) printk(" %x",scbs[i].scbdata[j]);
+ printk("\n"));
+ /* Now we set up the pointer to scb, then the status of the mbox */
+ any2scsi((mbstruct.ombox[i].scbptr),&(scbs[i]));
+ mbstruct.ombox[i].status=1;
+ /* Everything set up, start the command */
+ break;
+ }
+ }
+ if (i==OGMB_CNT){
+ /* No free mbox, send command "Interrupt on free OGMB" */
+ DEB(printk("No free Mailbox\n"));
+ return 0;
+ }
+ { int len,k;
+ struct scb * scbptr;
+ DEB(printk("Found outgoing mbox %x\n",i));
+ scbptr=&(scbs[i]);
+ len=sizeof(struct scb);
+ k=0;
+ DEB(printk("SCB before execute:\n");
+ while (len-- >0){
+ printk("%x ",*((unchar *)scbptr));
+ ((unchar *)scbptr)++;
+ if (++k==16){ printk("\n"); k=0; }
+ };)
+ }
+ /* Set up the "done" response function */
+ if (done) {
+ DEB(printk("wd7000fasst_queuecommand: now waiting for interrupt ");
+ wd7000fasst_stat());
+ if (wd7000fasst_do_done)
+ printk("wd7000fasst_queuecommand: Two concurrent queuecommand?\n");
+ else
+ wd7000fasst_do_done = done;
+ DEB(wd7000fasst_stat());
+ wd7000fasst_enable_intr();
+ }
+ else{
+ printk("wd7000fasst_queuecommand: done can't be NULL\n");
+ return 0;
+ }
+ /* Now we initialize execution */
+retry: WAIT(ASC_STAT,STATMASK,CMD_RDY,0);
+ outb(0x80+i,COMMAND);
+ WAIT(ASC_STAT,STATMASK,CMD_RDY,0);
+ if (inb(ASC_STAT)&CMD_REJ) goto retry;
+ return 1;
+ /* Wait until done */
+
+fail:
+ return 0;
+}
+
+/* We use this function for queueing a command from wd7000fasst_command */
+static void internal_done(int host, int errcode)
+{
+ internal_done_errcode = errcode;
+ ++internal_done_flag;
+}
+
+int wd7000fasst_command(unchar target, const void *cmnd, void *buff, int bufflen)
+{
+#ifdef DEBUG
+ int k;
+#endif
+ wd7000fasst_queuecommand(target, cmnd, buff, bufflen, internal_done);
+
+ while (!internal_done_flag);
+ internal_done_flag = 0;
+ DEB(printk("wd7000fasst_command finished: ..leaving with errcode %x\n",
+ internal_done_errcode));
+ DEB(for (k=0;k<5000000;k++) inb(INTR_STAT));
+ return internal_done_errcode;
+}
+
+/* a hack to avoid a strange compilation error */
+
+void wd7000fasst_call_buh()
+{
+ set_intr_gate((intr_chan<=7)?intr_chan+8:intr_chan+0x20,&wd7000fasst_interrupt);
+}
+
+/* return non-zero on detection */
+static const char *wd_bases[] = {(char *)0xce000};
+typedef struct {char * signature;
+ unsigned offset;
+ unsigned length;
+ }Signature;
+
+static const Signature signatures[] =
+ {{"SSTBIOS",0xd,0x7}};
+
+#define NUM_SIGNATURES (sizeof(signatures)/sizeof(Signature))
+
+int wd7000fasst_detect(int hostnum) /* hostnum ignored for now */
+{
+ int i,j;
+ char const * base_address = 0;
+ /* Store our host number */
+ wd7000fasst_hostno=hostnum;
+ DEB(printk("wd7000fasst_detect: \n"));
+
+ for(i=0;i<(sizeof(wd_bases)/sizeof(char *));i++){
+ for(j=0;j<NUM_SIGNATURES;j++){
+ if(!memcmp((void *)(wd_bases[i] + signatures[j].offset),
+ (void *) signatures[j].signature,signatures[j].length)){
+ base_address=wd_bases[i];
+ printk("WD 7000-FASST detected\n");
+ }
+ }
+ }
+ if (!base_address) return 0;
+ wd7000fasst_init();
+
+ /* Set the Bus on/off-times as not to ruin floppy performens */
+
+ wd7000fasst_stat();
+
+ printk(" *** READ CAPACITY ***\n");
+
+ { unchar rstat;
+ unchar buf[8];
+ static unchar cmd[] = { READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ int i;
+
+ for (i = 0; i < sizeof(buf); ++i) buf[i] = 0x87;
+ for (i = 0; i < 3; ++i){
+ rstat=0;
+ while (rstat<2){
+ if (wd7000fasst_command(i, cmd, buf, sizeof(buf))) rstat++;
+ else break;
+ }
+ if (rstat<2)
+ printk("wd7000fasst_detect: LU %d sector_size 0x%x device_size 0x%x capacity %d\n",
+ i, xscsi2int(buf+4), xscsi2int(buf), xscsi2int(buf+4)*xscsi2int(buf));
+ }
+ }
+
+ return 1;
+}
+
+int wd7000fasst_abort(int i)
+{
+ printk("wd7000fasst_abort\n");
+ return 0;
+}
+
+int wd7000fasst_reset(void)
+{
+ printk("wd7000fasst_reset called\n");
+ return 0;
+}
+
+__asm__("
+_wd7000fasst_interrupt:
+ cld
+ pushl %eax
+ pushl %ecx
+ pushl %edx
+ push %ds
+ push %es
+ push %fs
+ movl $0x10,%eax
+ mov %ax,%ds
+ mov %ax,%es
+ movl $0x17,%eax
+ mov %ax,%fs
+# Please, someone, change this to use the timer
+# andl $0xfffeffff,_timer_active
+ movl $_wd7000fasst_intr_handle,%edx
+ call *%edx # ``interesting'' way of handling intr.
+# Free the interrupt only after resetting the host interrupt
+ movb $0x20,%al
+ outb %al,$0xA0 # EOI to interrupt controller #1
+ jmp 1f # give port chance to breathe
+1: jmp 1f
+1: outb %al,$0x20
+ pop %fs
+ pop %es
+ pop %ds
+ popl %edx
+ popl %ecx
+ popl %eax
+ iret
+");
diff --git a/kernel/blk_drv/scsi/7000fasst.h b/kernel/blk_drv/scsi/7000fasst.h
new file mode 100644
index 0000000..7411950
--- /dev/null
+++ b/kernel/blk_drv/scsi/7000fasst.h
@@ -0,0 +1,137 @@
+#ifndef _WD7000FASST_H
+
+/* $Id: 7000fasst.h,v 1.1 1992/07/24 06:27:38 root Exp root $
+ *
+ * Header file for the WD 7000-FASST driver for Linux
+ *
+ * $Log: 7000fasst.h,v $
+ * Revision 1.1 1992/07/24 06:27:38 root
+ * Initial revision
+ *
+ * Revision 1.1 1992/07/05 08:32:32 root
+ * Initial revision
+ *
+ * Revision 1.1 1992/05/15 18:38:05 root
+ * Initial revision
+ *
+ * Revision 1.1 1992/04/02 03:23:13 drew
+ * Initial revision
+ *
+ * Revision 1.3 1992/01/27 14:46:29 tthorn
+ * *** empty log message ***
+ *
+ */
+
+#include <linux/types.h>
+
+#undef STATMASK
+#undef CONTROL
+
+#define io_base 0x350
+#define intr_chan 15
+#define dma_chan 6
+#define OGMB_CNT 8
+#define ICMB_CNT 8
+
+/* I/O Port interface 4.2 */
+/* READ */
+#define ASC_STAT io_base
+#define INT_IM 0x80 /* Interrupt Image Flag */
+#define CMD_RDY 0x40 /* Command Port Ready */
+#define CMD_REJ 0x20 /* Command Port Byte Rejected */
+#define ASC_INI 0x10 /* ASC Initialized Flag */
+#define STATMASK 0xf0 /* The lower 4 Bytes are reserved */
+
+/* This register saves two purposes
+ * Diagnostics error
+ * Interrupt Status
+ */
+#define INTR_STAT ASC_STAT+1
+#define ANYINTR 0x80 /* Mailbox Service possible/required */
+#define IMB 0x40 /* 1 Incoming / 0 Outgoing */
+#define MBMASK 0x3f
+/* if MSB is zero, the content of the lower ones keeps Diagnostic State *
+ * 00 Power-on, no diagnostics executed
+ * 01 No diagnostic Error Occured
+ * 02 RAM Failed
+ * 03 FIFO R/W Failed
+ * ...
+*/
+
+/* WRITE */
+#define COMMAND ASC_STAT
+
+#define INTR_ACK ASC_STAT+1
+
+
+#define CONTROL ASC_STAT+2
+#define INT_EN 0x08 /* Interrupt Enable */
+#define DMA_EN 0x04 /* DMA Enable */
+#define SCSI_RES 0x02 /* SCSI Reset */
+#define ASC_RES 0x01 /* ASC Reset */
+
+/* The DMA-Controller */
+#define DMA_MODE_REG 0xd6
+#define DMA_MASK_REG 0xd4
+#define S_DMA_MSK 0x04
+#define DMA_CH 0x02
+#define CASCADE 0xc0
+
+/* Mailbox Definition 5.3 */
+
+/* These belong in scsi.h also */
+#undef any2scsi
+#define any2scsi(up, p) \
+(up)[0] = (((long)(p)) >> 16); \
+(up)[1] = ((long)(p)) >> 8; \
+(up)[2] = ((long)(p));
+
+#define scsi2int(up) ( (((long)*(up)) << 16) + (((long)(up)[1]) << 8) + ((long)(up)[2]) )
+
+#define xany2scsi(up, p) \
+(up)[0] = ((long)(p)) >> 24; \
+(up)[1] = ((long)(p)) >> 16; \
+(up)[2] = ((long)(p)) >> 8; \
+(up)[3] = ((long)(p));
+
+#define xscsi2int(up) ( (((long)(up)[0]) << 24) + (((long)(up)[1]) << 16) \
+ + (((long)(up)[2]) << 8) + ((long)(up)[3]) )
+
+#define MAX_CDB 12
+#define MAX_SENSE 14
+
+struct scb { /* Command Control Block 5.4.1 */
+ unchar op; /* Command Control Block Operation Code */
+ unchar idlun; /* op=0,2:Target Id, op=1:Initiator Id */
+ /* Outbound data transfer, length is checked*/
+ /* Inbound data transfer, length is checked */
+ /* Logical Unit Number */
+ unchar scbdata[12]; /* SCSI Command Block */
+ unchar sretstat; /* SCSI Return Status */
+ unchar vue; /* Vendor Unique Error Code */
+ unchar maxdata[3]; /* Maximum Data Transfer Length */
+ unchar dataptr[3]; /* SCSI Data Block Pointer */
+ unchar linkptr[3]; /* Next Command Link Pointer */
+ unchar direc; /* Transfer Direction */
+ unchar reserved2[6]; /* SCSI Command Descriptor Block */
+ /* REQUEST SENSE */
+};
+
+int wd7000fasst_detect(int);
+int wd7000fasst_command(unsigned char target, const void *cmnd, void *buff, int bufflen);
+int wd7000fasst_queuecommand(unchar target, const void *cmnd, void *buff, int bufflen, void (*done)(int,int));
+int wd7000fasst_abort(int);
+char *wd7000fasst_info(void);
+int wd7000fasst_reset(void);
+
+#ifndef NULL
+ #define NULL 0
+#endif
+
+#define WD7000FASST {"Western Digital 7000FASST", wd7000fasst_detect, \
+ wd7000fasst_info, wd7000fasst_command, \
+ wd7000fasst_queuecommand, \
+ wd7000fasst_abort, \
+ wd7000fasst_reset, \
+ 1, 7, 0}
+#endif
diff --git a/kernel/blk_drv/scsi/Makefile b/kernel/blk_drv/scsi/Makefile
index fd978dd..f9d8e57 100644
--- a/kernel/blk_drv/scsi/Makefile
+++ b/kernel/blk_drv/scsi/Makefile
@@ -10,30 +10,28 @@
.c.s:
$(CC) $(CFLAGS) $(DEBUG) -S $<
+
.s.o:
$(AS) -c -o $*.o $<
+
.c.o:
$(CC) $(CFLAGS) $(DEBUG) -c $<
-LOWLEVELCSRC = aha1542.c seagate.c ultrastor.c
-LOWLEVELHSRC = aha1542.c seagate.h ultrastor.h
+
+LOWLEVELSSRC = seagate2.s
+LOWLEVELCSRC = aha1542.c fdomain.c seagate.c ultrastor.c 7000fasst.c
+LOWLEVELHSRC = aha1542.h fdomain.h seagate.h ultrastor.h 7000fasst.o
-CSRC = hosts.c sd.c st.c scsi.c $(LOWLEVELCSRC)
-HSRC = hosts.h sd.h st.h scsi.h $(LOWLEVELHSRC)
+CSRC = hosts.c sd.c sd_ioctl.c st.c st_ioctl.c scsi.c scsi_ioctl.c $(LOWLEVELCSRC)
+HSRC = hosts.h sd.h st.h scsi.h scsi_ioctl.h $(LOWLEVELHSRC)
OBJS = scsi.o hosts.o scsi_ioctl.o sd.o sd_ioctl.o st.o st_ioctl.o \
- aha1542.o seagate.o ultrastor.o
+ aha1542.o fdomain.o seagate.o seagate2.o ultrastor.o 7000fasst.o
all: scsi.a
-config.out : config.in $(KERNELHDRS)/linux/config.h
- rm -f foo.c
- ln -s config.in foo.c
- $(CPP) foo.c | grep '\.o' > config.out
- rm foo.c
-
-figure : hosts.h $(KERNELHDRS)/linux/config.h hosts.c config.out
- $(HOSTCC) -I$(KERNELHDRS) -DFIGURE_MAX_SCSI_HOSTS hosts.c -o figure
+figure : hosts.h $(KERNELHDRS)/linux/config.h hosts.c
+ $(HOSTCC) -N -DFIGURE_MAX_SCSI_HOSTS hosts.c -o figure
max_hosts.h : figure
(echo "#ifndef _MAX_HOSTS_H"; \
@@ -46,93 +44,124 @@ scsi.a: $(OBJS)
$(AR) rcs scsi.a $(OBJS)
sync
-scsi.shar: Makefile scsi.doc $(CSRC) $(HSRC) ../ll_rw_blk.c ../blk.h all.diff
- (cd ..; shar scsi/scsi.doc scsi/Makefile scsi/*.{c,h} scsi/all.diff blk.h ll_rw_blk.c) > scsi.shar;
-
clean:
- rm -f core *.o *.a tmp_make tmp_max figure config.out Makefile.tag max_hosts.h
+ rm -f core *.o *.a tmp_make tmp_max figure max_hosts.h
+
+seagate2.o : seagate2.s
-seagate.s seagate.o : seagate.c ../../../include/linux/config.h \
- ../../../include/linux/config.dist.h ../../../include/linux/sched.h \
- ../../../include/linux/head.h ../../../include/linux/fs.h \
- ../../../include/sys/types.h ../../../include/linux/mm.h \
- ../../../include/linux/kernel.h ../../../include/signal.h \
- ../../../include/sys/param.h ../../../include/sys/time.h \
- ../../../include/time.h ../../../include/sys/resource.h \
- ../../../include/linux/string.h seagate.h scsi.h hosts.h max_hosts.h
- $(CC) -Wall -c seagate.c $(DEBUG)
+seagate.o: seagate.c
+ $(CC) -Wall -c seagate.c
dep:
+ touch max_hosts.h
sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
- for i in *.c ;do $(CPP) -M $$i;done >> tmp_make
+ for i in *.c;do $(CPP) -M $$i;done >> tmp_make
+ rm max_hosts.h
cp tmp_make Makefile
### Dependencies:
-aha1542.s aha1542.o : aha1542.c ../../../include/linux/config.h ../../../include/linux/config_rel.h \
- ../../../include/linux/config_ver.h ../../../include/linux/config.dist.h ../../../include/linux/kernel.h \
- ../../../include/linux/head.h ../../../include/linux/string.h ../../../include/asm/system.h \
- ../../../include/asm/io.h scsi.h hosts.h max_hosts.h aha1542.h
-hosts.s hosts.o : hosts.c ../../../include/linux/config.h ../../../include/linux/config_rel.h \
- ../../../include/linux/config_ver.h ../../../include/linux/config.dist.h ../../../include/linux/kernel.h \
- scsi.h hosts.h max_hosts.h aha1542.h seagate.h ultrastor.h
-scsi.s scsi.o : scsi.c ../../../include/linux/config.h ../../../include/linux/config_rel.h \
- ../../../include/linux/config_ver.h ../../../include/linux/config.dist.h ../../../include/asm/system.h \
- ../../../include/linux/sched.h ../../../include/linux/head.h ../../../include/linux/fs.h \
- ../../../include/sys/types.h ../../../include/sys/dirent.h ../../../include/limits.h \
- ../../../include/linux/mm.h ../../../include/linux/kernel.h ../../../include/signal.h \
- ../../../include/sys/param.h ../../../include/sys/time.h ../../../include/time.h \
- ../../../include/sys/resource.h ../../../include/linux/timer.h ../../../include/linux/string.h \
- scsi.h hosts.h max_hosts.h sd.h st.h
-scsi_ioctl.s scsi_ioctl.o : scsi_ioctl.c ../../../include/linux/config.h ../../../include/linux/config_rel.h \
- ../../../include/linux/config_ver.h ../../../include/linux/config.dist.h ../../../include/errno.h \
- ../../../include/asm/io.h ../../../include/asm/segment.h ../../../include/asm/system.h \
- ../../../include/linux/kernel.h ../../../include/linux/sched.h ../../../include/linux/head.h \
- ../../../include/linux/fs.h ../../../include/sys/types.h ../../../include/sys/dirent.h \
- ../../../include/limits.h ../../../include/linux/mm.h ../../../include/signal.h \
- ../../../include/sys/param.h ../../../include/sys/time.h ../../../include/time.h \
- ../../../include/sys/resource.h ../../../include/linux/string.h scsi.h hosts.h \
- max_hosts.h scsi_ioctl.h
-sd.s sd.o : sd.c ../../../include/linux/config.h ../../../include/linux/config_rel.h \
- ../../../include/linux/config_ver.h ../../../include/linux/config.dist.h ../../../include/linux/string.h \
- ../../../include/linux/fs.h ../../../include/sys/types.h ../../../include/sys/dirent.h \
- ../../../include/limits.h ../../../include/linux/kernel.h ../../../include/linux/sched.h \
- ../../../include/linux/head.h ../../../include/linux/mm.h ../../../include/signal.h \
- ../../../include/sys/param.h ../../../include/sys/time.h ../../../include/time.h \
- ../../../include/sys/resource.h scsi.h sd.h ../blk.h
-sd_ioctl.s sd_ioctl.o : sd_ioctl.c ../../../include/linux/config.h ../../../include/linux/config_rel.h \
- ../../../include/linux/config_ver.h ../../../include/linux/config.dist.h ../../../include/linux/kernel.h \
- ../../../include/linux/sched.h ../../../include/linux/head.h ../../../include/linux/fs.h \
- ../../../include/sys/types.h ../../../include/sys/dirent.h ../../../include/limits.h \
- ../../../include/linux/mm.h ../../../include/signal.h ../../../include/sys/param.h \
- ../../../include/sys/time.h ../../../include/time.h ../../../include/sys/resource.h \
- scsi.h sd.h
-seagate.s seagate.o : seagate.c ../../../include/linux/config.h ../../../include/linux/config_rel.h \
- ../../../include/linux/config_ver.h ../../../include/linux/config.dist.h ../../../include/linux/sched.h \
- ../../../include/linux/head.h ../../../include/linux/fs.h ../../../include/sys/types.h \
- ../../../include/sys/dirent.h ../../../include/limits.h ../../../include/linux/mm.h \
- ../../../include/linux/kernel.h ../../../include/signal.h ../../../include/sys/param.h \
- ../../../include/sys/time.h ../../../include/time.h ../../../include/sys/resource.h \
+7000fasst.o : 7000fasst.c /usr/src/linux/include/linux/config.h /usr/src/linux/include/linux/config_rel.h \
+ /usr/src/linux/include/linux/config_ver.h /usr/src/linux/include/linux/config.dist.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/types.h \
+ /usr/src/linux/include/linux/string.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/io.h \
+ scsi.h hosts.h max_hosts.h 7000fasst.h
+aha1542.o : aha1542.c /usr/src/linux/include/linux/config.h /usr/src/linux/include/linux/config_rel.h \
+ /usr/src/linux/include/linux/config_ver.h /usr/src/linux/include/linux/config.dist.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/types.h \
+ /usr/src/linux/include/linux/string.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/io.h \
+ scsi.h hosts.h max_hosts.h aha1542.h
+fdomain.o : fdomain.c /usr/src/linux/include/linux/config.h /usr/src/linux/include/linux/config_rel.h \
+ /usr/src/linux/include/linux/config_ver.h /usr/src/linux/include/linux/config.dist.h \
+ /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
+ /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h \
+ /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/asm/io.h fdomain.h scsi.h hosts.h max_hosts.h /usr/src/linux/include/asm/system.h \
+ /usr/src/linux/include/linux/errno.h
+hosts.o : hosts.c /usr/src/linux/include/linux/config.h /usr/src/linux/include/linux/config_rel.h \
+ /usr/src/linux/include/linux/config_ver.h /usr/src/linux/include/linux/config.dist.h \
+ /usr/src/linux/include/linux/kernel.h scsi.h hosts.h max_hosts.h aha1542.h /usr/src/linux/include/linux/types.h \
+ fdomain.h seagate.h ultrastor.h 7000fasst.h
+scsi.o : scsi.c /usr/src/linux/include/linux/config.h /usr/src/linux/include/linux/config_rel.h \
+ /usr/src/linux/include/linux/config_ver.h /usr/src/linux/include/linux/config.dist.h \
+ /usr/src/linux/include/asm/system.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/mm.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/timer.h /usr/src/linux/include/linux/string.h scsi.h \
+ hosts.h max_hosts.h sd.h /usr/src/linux/include/linux/genhd.h st.h
+scsi_ioctl.o : scsi_ioctl.c /usr/src/linux/include/linux/config.h /usr/src/linux/include/linux/config_rel.h \
+ /usr/src/linux/include/linux/config_ver.h /usr/src/linux/include/linux/config.dist.h \
+ /usr/src/linux/include/asm/io.h /usr/src/linux/include/asm/segment.h /usr/src/linux/include/asm/system.h \
+ /usr/src/linux/include/linux/errno.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/sched.h \
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/signal.h /usr/src/linux/include/linux/time.h \
+ /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/string.h scsi.h hosts.h max_hosts.h scsi_ioctl.h
+sd.o : sd.c /usr/src/linux/include/linux/config.h /usr/src/linux/include/linux/config_rel.h \
+ /usr/src/linux/include/linux/config_ver.h /usr/src/linux/include/linux/config.dist.h \
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/kernel.h \
+ /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/mm.h \
+ /usr/src/linux/include/linux/signal.h /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h \
+ /usr/src/linux/include/linux/resource.h /usr/src/linux/include/linux/string.h \
+ scsi.h sd.h /usr/src/linux/include/linux/genhd.h ../blk.h
+sd_ioctl.o : sd_ioctl.c /usr/src/linux/include/linux/config.h /usr/src/linux/include/linux/config_rel.h \
+ /usr/src/linux/include/linux/config_ver.h /usr/src/linux/include/linux/config.dist.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/mm.h \
+ /usr/src/linux/include/linux/signal.h /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h \
+ /usr/src/linux/include/linux/resource.h scsi.h sd.h /usr/src/linux/include/linux/genhd.h
+seagate.o : seagate.c /usr/src/linux/include/linux/config.h /usr/src/linux/include/linux/config_rel.h \
+ /usr/src/linux/include/linux/config_ver.h /usr/src/linux/include/linux/config.dist.h \
+ /usr/src/linux/include/asm/io.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/linux/sched.h \
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
seagate.h scsi.h hosts.h max_hosts.h
-st.s st.o : st.c ../../../include/linux/config.h ../../../include/linux/config_rel.h \
- ../../../include/linux/config_ver.h ../../../include/linux/config.dist.h scsi.h \
- st.h ../../../include/linux/fs.h ../../../include/sys/types.h ../../../include/sys/dirent.h \
- ../../../include/limits.h ../../../include/linux/kernel.h ../../../include/linux/sched.h \
- ../../../include/linux/head.h ../../../include/linux/mm.h ../../../include/signal.h \
- ../../../include/sys/param.h ../../../include/sys/time.h ../../../include/time.h \
- ../../../include/sys/resource.h ../blk.h
-st_ioctl.s st_ioctl.o : st_ioctl.c ../../../include/linux/config.h ../../../include/linux/config_rel.h \
- ../../../include/linux/config_ver.h ../../../include/linux/config.dist.h ../../../include/linux/kernel.h \
- ../../../include/linux/sched.h ../../../include/linux/head.h ../../../include/linux/fs.h \
- ../../../include/sys/types.h ../../../include/sys/dirent.h ../../../include/limits.h \
- ../../../include/linux/mm.h ../../../include/signal.h ../../../include/sys/param.h \
- ../../../include/sys/time.h ../../../include/time.h ../../../include/sys/resource.h \
- st.h scsi.h
-ultrastor.s ultrastor.o : ultrastor.c ../../../include/linux/config.h ../../../include/linux/config_rel.h \
- ../../../include/linux/config_ver.h ../../../include/linux/config.dist.h ../../../include/stddef.h \
- ../../../include/linux/string.h ../../../include/linux/sched.h ../../../include/linux/head.h \
- ../../../include/linux/fs.h ../../../include/sys/types.h ../../../include/sys/dirent.h \
- ../../../include/limits.h ../../../include/linux/mm.h ../../../include/linux/kernel.h \
- ../../../include/signal.h ../../../include/sys/param.h ../../../include/sys/time.h \
- ../../../include/time.h ../../../include/sys/resource.h ../../../include/linux/hdreg.h \
- ../../../include/asm/system.h ../../../include/asm/io.h ../../../include/asm/segment.h \
- ultrastor.h scsi.h hosts.h max_hosts.h
+st.o : st.c /usr/src/linux/include/linux/config.h /usr/src/linux/include/linux/config_rel.h \
+ /usr/src/linux/include/linux/config_ver.h /usr/src/linux/include/linux/config.dist.h \
+ scsi.h st.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/signal.h /usr/src/linux/include/linux/time.h \
+ /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ ../blk.h
+st_ioctl.o : st_ioctl.c /usr/src/linux/include/linux/config.h /usr/src/linux/include/linux/config_rel.h \
+ /usr/src/linux/include/linux/config_ver.h /usr/src/linux/include/linux/config.dist.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/mm.h \
+ /usr/src/linux/include/linux/signal.h /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h \
+ /usr/src/linux/include/linux/resource.h st.h scsi.h
+ultrastor.o : ultrastor.c /usr/src/linux/include/linux/config.h /usr/src/linux/include/linux/config_rel.h \
+ /usr/src/linux/include/linux/config_ver.h /usr/src/linux/include/linux/config.dist.h \
+ /usr/src/linux/include/linux/stddef.h /usr/src/linux/include/linux/string.h \
+ /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
+ /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h \
+ /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/asm/io.h /usr/src/linux/include/asm/system.h ultrastor.h \
+ scsi.h hosts.h max_hosts.h
diff --git a/kernel/blk_drv/scsi/aha1542.c b/kernel/blk_drv/scsi/aha1542.c
index f09a2f2..a616675 100644
--- a/kernel/blk_drv/scsi/aha1542.c
+++ b/kernel/blk_drv/scsi/aha1542.c
@@ -1,17 +1,17 @@
-/* $Id: aha1542.c,v 1.1 1992/04/24 18:01:50 root Exp root $
+/* $Id: aha1542.c,v 1.1 1992/07/24 06:27:38 root Exp root $
* linux/kernel/aha1542.c
*
- * (C) 1992 Tommy Thorn
+ * Copyright (C) 1992 Tommy Thorn
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/head.h>
+#include <linux/types.h>
#include <linux/string.h>
-#include <linux/sched.h>
+
#include <asm/system.h>
#include <asm/io.h>
-#include <sys/types.h>
#include "scsi.h"
#include "hosts.h"
@@ -23,7 +23,7 @@
#endif
/*
-static const char RCSid[] = "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/aha1542.c,v 1.1 1992/04/24 18:01:50 root Exp root $";
+static const char RCSid[] = "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/aha1542.c,v 1.1 1992/07/24 06:27:38 root Exp root $";
*/
#define base 0x330
@@ -34,7 +34,9 @@ static struct ccb ccb;
long WAITtimeout, WAITnexttimeout = 3000000;
-void (*do_done)() = NULL;
+void (*do_done)(int, int) = NULL;
+int aha1542_host = 0;
+extern void aha1542_interrupt();
#define aha1542_intr_reset() outb(IRST, CONTROL)
#define aha1542_enable_intr() outb(inb_p(0xA1) & ~8, 0xA1)
@@ -53,9 +55,8 @@ void (*do_done)() = NULL;
static void aha1542_stat(void)
{
- int s = inb(STATUS), i = inb(INTRFLAGS);
-/* printk("status = %x, intrflags = %x served %d last %x timeout %d\n", s, i, intr_flag, intr_last, WAITtimeout); */
- printk("status=%x intrflags=%x\n", s, i, WAITnexttimeout-WAITtimeout);
+/* int s = inb(STATUS), i = inb(INTRFLAGS);
+ printk("status=%x intrflags=%x\n", s, i, WAITnexttimeout-WAITtimeout); */
}
static int aha1542_out(unchar *cmdp, int len)
@@ -192,15 +193,14 @@ char *aha1542_info(void)
}
/* A "high" level interrupt handler */
-static void aha1542_interrupt(int cpl)
+void aha1542_intr_handle(void)
{
- int flag = inb(INTRFLAGS);
- void (*my_done)() = do_done;
+ void (*my_done)(int, int) = do_done;
int errstatus;
do_done = NULL;
#ifdef DEBUG
- printk("aha1542_interrupt: ");
+ printk("aha1542_intr_handle: ");
if (!(flag&ANYINTR)) printk("no interrupt?");
if (flag&MBIF) printk("MBIF ");
if (flag&MBOA) printk("MBOF ");
@@ -212,15 +212,15 @@ static void aha1542_interrupt(int cpl)
#endif
aha1542_intr_reset();
if (!my_done) {
- printk("aha1542_interrupt: Unexpected interrupt\n");
+ printk("aha1542_intr_handle: Unexpected interrupt\n");
return;
}
/* is there mail :-) */
if (!mb[1].status) {
- DEB(printk("aha1542_interrupt: strange: mbif but no mail!\n"));
- my_done(DID_TIME_OUT << 16);
+ DEB(printk("aha1542_intr_handle: strange: mbif but no mail!\n"));
+ my_done(aha1542_host, DID_TIME_OUT << 16);
return;
}
@@ -235,29 +235,29 @@ static void aha1542_interrupt(int cpl)
if (ccb.tarstat == 2) {
int i;
- DEB(printk("aha1542_interrupt: sense:"));
+ DEB(printk("aha1542_intr_handle: sense:"));
for (i = 0; i < 12; i++)
printk("%02x ", ccb.cdb[ccb.cdblen+i]);
printk("\n");
/*
- DEB(printk("aha1542_interrupt: buf:"));
+ DEB(printk("aha1542_intr_handle: buf:"));
for (i = 0; i < bufflen; i++)
printk("%02x ", ((unchar *)buff)[i]);
printk("\n");
*/
}
- DEB(if (errstatus) printk("aha1542_interrupt: returning %6x\n", errstatus));
- my_done(errstatus);
+ DEB(if (errstatus) printk("aha1542_intr_handle: returning %6x\n", errstatus));
+ my_done(aha1542_host, errstatus);
return;
}
-int aha1542_queuecommand(unchar target, const void *cmnd, void *buff, int bufflen, void (*done)(int))
+int aha1542_queuecommand(unchar target, const void *cmnd, void *buff, int bufflen, void (*done)(int, int))
{
unchar ahacmd = CMD_START_SCSI;
- int i;
unchar *cmd = (unchar *) cmnd;
+ DEB(int i);
- DEB(if (target > 1) {done(DID_TIME_OUT << 16); return 0;});
+ DEB(if (target > 1) {done(aha1542_host, DID_TIME_OUT << 16); return 0;});
#ifdef DEBUG
if (*cmd == READ_10 || *cmd == WRITE_10)
@@ -317,7 +317,7 @@ int aha1542_queuecommand(unchar target, const void *cmnd, void *buff, int buffle
volatile static int internal_done_flag = 0;
volatile static int internal_done_errcode = 0;
-static void internal_done(int errcode)
+static void internal_done(int host, int errcode)
{
internal_done_errcode = errcode;
++internal_done_flag;
@@ -355,18 +355,11 @@ static void setup_mailboxes()
void call_buh()
{
- struct sigaction sa;
-
- sa.sa_handler = aha1542_interrupt;
- sa.sa_flags = SA_INTERRUPT;
- sa.sa_mask = 0;
- sa.sa_restorer = NULL;
- if (irqaction(intr_chan,&sa))
- printk("Unable to allocate IRQ%d for aha controller\n", intr_chan);
+ set_intr_gate(0x2b,&aha1542_interrupt);
}
/* return non-zero on detection */
-int aha1542_detect(int hostnum) /* hostnum ignored for now */
+int aha1542_detect(int hostnum)
{
int i;
@@ -441,6 +434,7 @@ int aha1542_detect(int hostnum) /* hostnum ignored for now */
aha1542_command(0, cmd, buffer, 512);
}
#endif
+ aha1542_host = hostnum;
return 1;
}
@@ -455,3 +449,35 @@ int aha1542_reset(void)
DEB(printk("aha1542_reset called\n"));
return 0;
}
+
+__asm__("
+_aha1542_interrupt:
+ cld
+ pushl %eax
+ pushl %ecx
+ pushl %edx
+ push %ds
+ push %es
+ push %fs
+ movl $0x10,%eax
+ mov %ax,%ds
+ mov %ax,%es
+ movl $0x17,%eax
+ mov %ax,%fs
+ movb $0x20,%al
+ outb %al,$0xA0 # EOI to interrupt controller #1
+ jmp 1f # give port chance to breathe
+1: jmp 1f
+1: outb %al,$0x20
+# Please, someone, change this to use the timer
+# andl $0xfffeffff,_timer_active
+ movl $_aha1542_intr_handle,%edx
+ call *%edx # ``interesting'' way of handling intr.
+ pop %fs
+ pop %es
+ pop %ds
+ popl %edx
+ popl %ecx
+ popl %eax
+ iret
+");
diff --git a/kernel/blk_drv/scsi/aha1542.h b/kernel/blk_drv/scsi/aha1542.h
index 47848d8..5d3640f 100644
--- a/kernel/blk_drv/scsi/aha1542.h
+++ b/kernel/blk_drv/scsi/aha1542.h
@@ -1,10 +1,25 @@
#ifndef _AHA1542_H
-/* $Id: aha1542.h,v 1.1 1992/04/24 18:01:50 root Exp root $
+/* $Id: aha1542.h,v 1.1 1992/07/24 06:27:38 root Exp root $
*
* Header file for the adaptec 1542 driver for Linux
*
* $Log: aha1542.h,v $
+ * Revision 1.1 1992/07/24 06:27:38 root
+ * Initial revision
+ *
+ * Revision 1.2 1992/07/04 18:41:49 root
+ * Replaced distribution with current drivers
+ *
+ * Revision 1.3 1992/06/23 23:58:20 root
+ * Fixes.
+ *
+ * Revision 1.2 1992/05/26 22:13:23 root
+ * Changed bug that prevented DMA above first 2 mbytes.
+ *
+ * Revision 1.1 1992/05/22 21:00:29 root
+ * Initial revision
+ *
* Revision 1.1 1992/04/24 18:01:50 root
* Initial revision
*
@@ -16,6 +31,8 @@
*
*/
+#include <linux/types.h>
+
/* I/O Port interface 4.2 */
/* READ */
#define STATUS base
@@ -64,10 +81,10 @@ struct mailbox {
};
/* These belong in scsi.h also */
-#define any2scsi(up, p) \
-(up)[0] = (((long)(p)) >> 16) & 0xff; \
-(up)[1] = ((long)(p)) >> 8; \
-(up)[2] = ((long)(p));
+#define any2scsi(up, p) \
+(up)[0] = (((unsigned long)(p)) >> 16) ; \
+(up)[1] = (((unsigned long)(p)) >> 8); \
+(up)[2] = ((unsigned long)(p));
#define scsi2int(up) ( (((long)*(up)) << 16) + (((long)(up)[1]) << 8) + ((long)(up)[2]) )
@@ -104,7 +121,7 @@ struct ccb { /* Command Control Block 5.3 */
int aha1542_detect(int);
int aha1542_command(unsigned char target, const void *cmnd, void *buff, int bufflen);
-/*int aha1542_queuecommand(unchar target, const void *cmnd, void *buff, int bufflen, void (*done)(int));*/
+int aha1542_queuecommand(unchar target, const void *cmnd, void *buff, int bufflen, void (*done)(int, int));
int aha1542_abort(int);
char *aha1542_info(void);
int aha1542_reset(void);
@@ -115,8 +132,8 @@ int aha1542_reset(void);
#define AHA1542 {"Adaptec 1542", aha1542_detect, \
aha1542_info, aha1542_command, \
- /*aha1542_queuecommand*/ NULL, \
+ aha1542_queuecommand, \
aha1542_abort, \
aha1542_reset, \
- 0, 7, 0}
+ 1, 7, 0}
#endif
diff --git a/kernel/blk_drv/scsi/config.out b/kernel/blk_drv/scsi/config.out
new file mode 100644
index 0000000..83ce57d
--- /dev/null
+++ b/kernel/blk_drv/scsi/config.out
@@ -0,0 +1,10 @@
+scsi.o
+hosts.o
+scsi_ioctl.o
+sd.o
+sd_ioctl.o
+st.o
+st_ioctl.o
+aha1542.o
+seagate.o
+ultrastor.o
diff --git a/kernel/blk_drv/scsi/fdomain.c b/kernel/blk_drv/scsi/fdomain.c
new file mode 100644
index 0000000..ae05651
--- /dev/null
+++ b/kernel/blk_drv/scsi/fdomain.c
@@ -0,0 +1,1234 @@
+/* fdomain.c -- Future Domain TMC-1660/TMC-1680 driver
+ * Created: Sun May 3 18:53:19 1992
+ * Revised: Tue Jul 28 19:45:25 1992 by root
+ * Author: Rickard E. Faith, faith@cs.unc.edu
+ * Copyright 1992 Rickard E. Faith
+ *
+ * $Log$
+
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+
+ * WARNING: THIS IS A BETA VERSION!
+ * USE AT YOUR OWN RISK!
+ * BACKUP YOUR SYSTEM BEFORE USING!
+
+ * I would like to thank Maxtor, whose *free* 206 page manual on the LXT
+ * drives was very helpful: "LXT SCSI Products: Specifications and OEM
+ * Technical Manual (Revision B/September 1991)"
+
+ * I wish that I could thank Future Domain for the necessary documentation,
+ * but I can't. I used the $25 "TMC-1800 SCSI Chip Specification" document
+ * (FDC-1800T), which documents the *chip* and not the board. Without it,
+ * I would have been totally lost, but it would have been nice to have some
+ * example source. (The DOS BIOS source cost $250 and the UN*X driver
+ * source was $750 [both required a non-disclosure agreement]. Ever wonder
+ * why there are no freely available Future Domain drivers?)
+
+ * Thanks to Todd Carrico (todd@wutc.wustl.edu), Dan Poirier
+ * (poirier@cs.unc.edu ), Ken Corey (kenc@sol.acs.unt.edu), and C. de Bruin
+ * (bruin@dutiba.tudelft.nl) for alpha testing. Also thanks to Drew
+ * Eckhardt (drew@cs.colorado.edu) for answering questions. */
+
+#include <linux/config.h>
+
+#ifdef CONFIG_SCSI_FUTURE_DOMAIN
+
+#include <linux/sched.h>
+#include <asm/io.h>
+#include "fdomain.h"
+#include "scsi.h"
+#include "hosts.h"
+#if QUEUE
+#include <asm/system.h>
+#include <linux/errno.h>
+#endif
+
+#define VERSION "1.9" /* Change with each revision */
+#define DEBUG 1 /* Enable debugging output */
+#define SEND_IDENTIFY 0 /* Send IDENTIFY message -- DOESN'T WORK! */
+#define USE_FIFO 1 /* Use the FIFO buffer for I/O */
+#define FAST_SYNCH 1 /* Enable Fast Synchronous */
+#define ALLOW_ALL_IRQ 0 /* Allow all IRQ's -- NOT RECOMMENDED */
+#define NEW_IRQ 1 /* Enable new IRQ handling */
+#define DECREASE_IL 1 /* Try to decrease interrupt latency */
+
+#if DEBUG
+#define EVERY_ACCESS 0 /* Write a line on every scsi access */
+#define ERRORS_ONLY 1 /* Only write a line if there is an error */
+#define DEBUG_DETECT 0 /* Debug fdomain_16x0_detect() */
+#else
+#define EVERY_ACCESS 0 /* LEAVE THESE ALONE--CHANGE THE ONES ABOVE */
+#define ERRORS_ONLY 0
+#define DEBUG_DETECT 0
+#endif
+
+/* Errors are reported on the line, so we don't need to report them again */
+#if EVERY_ACCESS
+#undef ERRORS_ONLY
+#define ERRORS_ONLY 0
+#endif
+
+static int port_base = 0;
+static void *bios_base = NULL;
+static int interrupt_level = 0;
+static volatile int aborted = 0;
+
+static int Data_Mode_Cntl_port;
+static int FIFO_Data_Count_port;
+static int Interrupt_Cntl_port;
+static int Read_FIFO_port;
+static int Read_SCSI_Data_port;
+static int SCSI_Cntl_port;
+static int SCSI_Status_port;
+static int TMC_Cntl_port;
+static int TMC_Status_port;
+static int Write_FIFO_port;
+static int Write_SCSI_Data_port;
+
+#if QUEUE
+static unsigned char current_target = 0;
+static unsigned char current_cmnd[10] = { 0, };
+static void *current_buff = NULL;
+static int current_bufflen = 0;
+static void (*current_done)(int,int) = NULL;
+
+volatile static int in_command = 0;
+volatile static int current_phase;
+static int this_host = 0;
+
+enum { in_arbitration, in_selection, in_other };
+
+#if NEW_IRQ
+extern void fdomain_16x0_intr( int unused );
+#else
+extern void fdomain_16x0_interrupt();
+#endif
+
+static const char *cmd_pt;
+static const char *the_command;
+static unsigned char *out_buf_pt;
+static unsigned char *in_buf_pt;
+volatile static int Status;
+volatile static int Message;
+volatile static unsigned data_sent;
+volatile static int have_data_in;
+
+volatile static int in_interrupt_code = 0;
+
+#endif
+
+
+enum in_port_type { Read_SCSI_Data = 0, SCSI_Status = 1, TMC_Status = 2,
+ LSB_ID_Code = 5, MSB_ID_Code = 6, Read_Loopback = 7,
+ SCSI_Data_NoACK = 8, Option_Select = 10,
+ Read_FIFO = 12, FIFO_Data_Count = 14 };
+
+enum out_port_type { Write_SCSI_Data = 0, SCSI_Cntl = 1, Interrupt_Cntl = 2,
+ Data_Mode_Cntl = 3, TMC_Cntl = 4, Write_Loopback = 7,
+ Write_FIFO = 12 };
+
+static void *addresses[] = {
+ (void *)0xc8000,
+ (void *)0xca000,
+ (void *)0xce000,
+ (void *)0xde000 };
+#define ADDRESS_COUNT (sizeof( addresses ) / sizeof( unsigned ))
+
+static unsigned short ports[] = { 0x140, 0x150, 0x160, 0x170 };
+#define PORT_COUNT (sizeof( ports ) / sizeof( unsigned short ))
+
+static unsigned short ints[] = { 3, 5, 10, 11, 12, 14, 15, 0 };
+
+/*
+
+ READ THIS BEFORE YOU ADD A SIGNATURE!
+
+ READING THIS SHORT NOTE CAN SAVE YOU LOTS OF TIME!
+
+ READ EVERY WORD, ESPECIALLY THE WORD *NOT*
+
+ This driver works *ONLY* for Future Domain cards using the
+ TMC-1600 chip. This includes models TMC-1660 and TMC-1680
+ *ONLY*.
+
+ The following is a BIOS signature for a TMC-950 board, which
+ looks like it is a 16 bit board (based on card edge), but
+ which only uses the extra lines for IRQ's (not for data):
+
+ FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90
+
+ THIS WILL *NOT* WORK WITH THIS DRIVER!
+
+ Here is another BIOS signature for yet another Future
+ Domain board WHICH WILL *NOT* WORK WITH THIS DRIVER:
+
+ FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90
+
+ Here is another BIOS signature for the TMC-88x series:
+
+ FUTURE DOMAIN COPR. (C) 1986-1989 V6.0A7/28/90
+
+ THIS WILL *NOT* WORK WITH THIS DRIVER, but it *WILL*
+ work with the *SEAGATE* ST-01/ST-02 driver.
+
+ */
+
+struct signature {
+ char *signature;
+ int sig_offset;
+ int sig_length;
+} signatures[] = {
+ { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.0 7/28/89", 5, 50 },
+ { "FUTURE DOMAIN CORP. (C) 1986-1990 1800", 5, 37 },
+ /* READ NOTICE ABOVE *BEFORE* YOU WASTE YOUR TIME ADDING A SIGANTURE */
+};
+
+#define SIGNATURE_COUNT (sizeof( signatures ) / sizeof( struct signature ))
+
+
+/* These functions are based on include/asm/io.h */
+
+#if 1
+static unsigned short inline inw( unsigned short port )
+{
+ unsigned short _v;
+
+ __asm__ volatile ("inw %1,%0"
+ :"=a" (_v):"d" ((unsigned short) port));
+ return _v;
+}
+
+static void inline outw( unsigned short value, unsigned short port )
+{
+ __asm__ volatile ("outw %0,%1"
+ ::"a" ((unsigned short) value),
+ "d" ((unsigned short) port));
+}
+#else
+
+#define inw( port ) \
+ ({ unsigned short _v; \
+ __asm__ volatile ("inw %1,%0" \
+ : "=a" (_v) : "d" ((unsigned short) port)); \
+ _v; })
+
+#define outw( value ) \
+ __asm__ volatile \
+ ("outw %0,%1" : : "a" ((unsigned short) value), \
+ "d" ((unsigned short) port))
+#endif
+
+
+/* These defines are copied from kernel/blk_drv/hd.c */
+
+#define insw( buf, count, port ) \
+ __asm__ volatile \
+ ( "cld;rep;insw"::"d" (port),"D" (buf),"c" (count):"cx","di" )
+
+#define outsw( buf, count, port) \
+ __asm__ volatile \
+ ("cld;rep;outsw"::"d" (port),"S" (buf),"c" (count):"cx","si")
+
+
+static void do_pause( unsigned amount ) /* Pause for amount*10 milliseconds */
+{
+ unsigned long the_time = jiffies + amount; /* 0.01 seconds per jiffy */
+
+ while (jiffies < the_time);
+}
+
+static void inline fdomain_make_bus_idle( void )
+{
+ outb( 0, SCSI_Cntl_port );
+ outb( 0, Data_Mode_Cntl_port );
+ outb( 1, TMC_Cntl_port );
+}
+
+static int fdomain_is_valid_port( int port )
+{
+ int options;
+
+#if DEBUG_DETECT
+ printk( " (%x%x),",
+ inb( port + MSB_ID_Code ), inb( port + LSB_ID_Code ) );
+#endif
+
+ /* The MCA ID is a unique id for each MCA compatible board. We
+ are using ISA boards, but Future Domain provides the MCA ID
+ anyway. We can use this ID to ensure that this is a Future
+ Domain TMC-1660/TMC-1680.
+ */
+
+ if (inb( port + LSB_ID_Code ) != 0xe9) { /* test for 0x6127 id */
+ if (inb( port + LSB_ID_Code ) != 0x27) return 0;
+ if (inb( port + MSB_ID_Code ) != 0x61) return 0;
+ } else { /* test for 0xe960 id */
+ if (inb( port + MSB_ID_Code ) != 0x60) return 0;
+ }
+
+ /* We have a valid MCA ID for a TMC-1660/TMC-1680 Future Domain board.
+ Now, check to be sure the bios_base matches these ports.
+ If someone was unlucky enough to have purchased more than one
+ Future Domain board, then they will have to modify this code, as
+ we only detect one board here. [The one with the lowest bios_base].
+ */
+
+ options = inb( port + Option_Select );
+
+#if DEBUG_DETECT
+ printk( " Options = %x,", options );
+#endif
+
+ if (addresses[ (options & 0xc0) >> 6 ] != bios_base) return 0;
+ interrupt_level = ints[ (options & 0x0e) >> 1 ];
+
+ return 1;
+}
+
+static int fdomain_test_loopback( void )
+{
+ int i;
+ int result;
+
+ for (i = 0; i < 255; i++) {
+ outb( i, port_base + Write_Loopback );
+ result = inb( port_base + Read_Loopback );
+ if (i != result) return 1;
+ }
+ return 0;
+}
+
+#if !NEW_IRQ
+static void fdomain_enable_interrupt( void )
+{
+ if (!interrupt_level) return;
+
+#if ALLOW_ALL_IRQ
+ if (interrupt_level < 8) {
+ outb( inb_p( 0x21 ) & ~(1 << interrupt_level), 0x21 );
+ } else
+#endif
+ {
+ outb( inb_p( 0xa1 ) & ~(1 << (interrupt_level - 8)), 0xa1 );
+ }
+}
+
+static void fdomain_disable_interrupt( void )
+{
+ if (!interrupt_level) return;
+
+#if ALLOW_ALL_IRQ
+ if (interrupt_level < 8) {
+ outb( inb_p( 0x21 ) | (1 << interrupt_level), 0x21 );
+ } else
+#endif
+ {
+ outb( inb_p( 0xa1 ) | (1 << (interrupt_level - 8)), 0xa1 );
+ }
+}
+#endif
+
+int fdomain_16x0_detect( int hostnum )
+{
+ int i, j;
+ int flag;
+ unsigned char do_inquiry[] = { 0x12, 0, 0, 0, 255, 0 };
+ unsigned char do_request_sense[] = { 0x03, 0, 0, 0, 255, 0 };
+ unsigned char do_read_capacity[] = { 0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ unsigned char buf[256];
+ unsigned retcode;
+
+#if DEBUG_DETECT
+ printk( "SCSI: fdomain_16x0_detect()," );
+#endif
+
+ for (i = 0; !bios_base && i < ADDRESS_COUNT; i++) {
+#if DEBUG_DETECT
+ printk( " %x(%x),", (unsigned)addresses[i], (unsigned)bios_base );
+#endif
+ for (j = 0; !bios_base && j < SIGNATURE_COUNT; j++) {
+ if (!memcmp( ((char *)addresses[i] + signatures[j].sig_offset),
+ signatures[j].signature, signatures[j].sig_length )) {
+ bios_base = addresses[i];
+ }
+ }
+ }
+
+ if (!bios_base) {
+#if DEBUG_DETECT
+ printk( " FAILED: NO BIOS\n" );
+#endif
+ return 0;
+ }
+
+ /* The TMC-1660/TMC-1680 has a RAM area just after the BIOS ROM.
+ Assuming the ROM is enabled (otherwise we wouldn't have been
+ able to read the ROM signature :-), then the ROM set up the
+ RAM area with some magic numbers, such as a list of port
+ base addresses and a list of the disk "geometry" reported to
+ DOS (this geometry has nothing to do with physical geometry).
+ */
+
+ port_base = *((char *)bios_base + 0x1fcc)
+ + (*((char *)bios_base + 0x1fcd) << 8);
+
+#if DEBUG_DETECT
+ printk( " %x,", port_base );
+#endif
+
+ for (flag = 0, i = 0; !flag && i < PORT_COUNT; i++) {
+ if (port_base == ports[i]) ++flag;
+ }
+
+ if (flag) flag = fdomain_is_valid_port( port_base );
+
+ if (!flag) { /* Cannot get port base from BIOS RAM */
+
+ /* This is a bad sign. It usually means that someone patched the
+ BIOS signature list (the signatures variable) to contain a BIOS
+ signature for a board *OTHER THAN* the TMC-1660/TMC-1680.
+ */
+
+#if DEBUG_DETECT
+ printk( " RAM FAILED, " );
+#endif
+ /* Anyway, the alternative to finding the address in the RAM is
+ to just search through every possible port address for one
+ that is attached to the Future Domain card. Don't panic,
+ though, about reading all these random port addresses--there
+ are rumors that the Future Domain BIOS does something very
+ similar.
+ */
+
+ for (flag = 0, i = 0; !flag && i < PORT_COUNT; i++) {
+ port_base = ports[i];
+#if DEBUG_DETECT
+ printk( " %x,", port_base );
+#endif
+ flag = fdomain_is_valid_port( port_base );
+ }
+ }
+
+ if (!flag) {
+#if DEBUG_DETECT
+ printk( " FAILED: NO PORT\n" );
+#endif
+ return 0; /* Cannot find valid set of ports */
+ }
+
+#if DEBUG_DETECT
+ printk( "\n" );
+ printk( "SCSI: bios_base = %x, port_base = %x, interrupt_level = %d\n",
+ (unsigned)bios_base, port_base, interrupt_level );
+#endif
+
+ if (interrupt_level) {
+ printk( "Future Domain BIOS at %x; port base at %x; using IRQ %d\n",
+ (unsigned)bios_base, port_base, interrupt_level );
+ } else {
+ printk( "Future Domain BIOS at %x; port base at %x; *NO* IRQ\n",
+ (unsigned)bios_base, port_base );
+ }
+
+ Data_Mode_Cntl_port = port_base + Data_Mode_Cntl;
+ FIFO_Data_Count_port = port_base + FIFO_Data_Count;
+ Interrupt_Cntl_port = port_base + Interrupt_Cntl;
+ Read_FIFO_port = port_base + Read_FIFO;
+ Read_SCSI_Data_port = port_base + Read_SCSI_Data;
+ SCSI_Cntl_port = port_base + SCSI_Cntl;
+ SCSI_Status_port = port_base + SCSI_Status;
+ TMC_Cntl_port = port_base + TMC_Cntl;
+ TMC_Status_port = port_base + TMC_Status;
+ Write_FIFO_port = port_base + Write_FIFO;
+ Write_SCSI_Data_port = port_base + Write_SCSI_Data;
+
+ fdomain_16x0_reset();
+
+ if (fdomain_test_loopback()) {
+#if DEBUG_DETECT
+ printk( "SCSI: LOOPBACK TEST FAILED, FAILING DETECT!\n" );
+#endif
+ return 0;
+ }
+
+ /* These routines are here because of the way the SCSI bus behaves
+ after a reset. This appropriate behavior was not handled correctly
+ by the higher level SCSI routines when I first wrote this driver.
+ */
+
+ printk( "Future Domain detection routine scanning for devices:\n" );
+ for (i = 0; i < 8; i++) {
+ if (i == 6) continue; /* The host adapter is at SCSI ID 6 */
+ retcode = fdomain_16x0_command( i, do_request_sense, buf, 255 );
+ if (!retcode) {
+ retcode = fdomain_16x0_command( i, do_inquiry, buf, 255 );
+ if (!retcode) {
+ printk( " SCSI ID %d: ", i );
+ for (j = 8; j < 32; j++) printk( "%c", buf[j] );
+ retcode = fdomain_16x0_command( i, do_read_capacity, buf, 255 );
+ if (!retcode) {
+ unsigned long blocks, size, capacity;
+
+ blocks = (buf[0] << 24) | (buf[1] << 16)
+ | (buf[2] << 8) | buf[3];
+ size = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
+ capacity = +(blocks * size * 10) / +(1024L * 1024L);
+
+ printk( "%lu MB (%lu byte blocks)",
+ ((capacity + 5L) / 10L), size );
+ }
+ printk ("\n" );
+ }
+ }
+ }
+
+#if QUEUE
+#if !ALLOW_ALL_IRQ
+ if (interrupt_level < 8) {
+ printk( "Future Domain: WILL NOT USE IRQ LESS THAN 8 FOR QUEUEING!\n" );
+ scsi_hosts[hostnum].can_queue = 0;
+ } else
+#endif
+#if NEW_IRQ
+ {
+ int retcode;
+ struct sigaction sa;
+
+ this_host = hostnum;
+
+ sa.sa_handler = fdomain_16x0_intr;
+ sa.sa_flags = SA_INTERRUPT;
+ sa.sa_mask = 0;
+ sa.sa_restorer = NULL;
+
+ retcode = irqaction( interrupt_level, &sa );
+
+ if (retcode < 0) {
+ if (retcode == -EINVAL) {
+ printk( "Future Domain: IRQ %d is bad!\n", interrupt_level );
+ printk( " This shouldn't happen: REPORT TO RIK!\n" );
+ } else if (retcode == -EBUSY) {
+ printk( "Future Domain: IRQ %d is already in use!\n",
+ interrupt_level );
+ printk( " Please use another IRQ for the FD card!\n" );
+ } else {
+ printk( "Future Domain: Error getting IRQ %d\n",
+ interrupt_level );
+ printk( " This shouldn't happen: REPORT TO RIK!\n" );
+ }
+ printk( " IRQs WILL NOT BE USED!\n" );
+
+ scsi_hosts[this_host].can_queue = 0;
+ } else {
+ printk( "Future Domain: IRQ %d selected with retcode = %d\n",
+ interrupt_level, retcode );
+ }
+ }
+#else
+ {
+ this_host = hostnum;
+ set_intr_gate( 0x20 + interrupt_level, &fdomain_16x0_interrupt );
+ fdomain_enable_interrupt();
+ }
+#endif
+#endif
+
+ return 1;
+}
+
+char *fdomain_16x0_info(void)
+{
+ static char buffer[] =
+ "Future Domain TMC-1660/TMC-1680 SCSI driver version "
+ VERSION
+ "\n";
+ return buffer;
+}
+
+static int fdomain_arbitrate( void )
+{
+ int status = 0;
+ unsigned long timeout;
+
+#if VERBOSE
+ printk( "SCSI: fdomain_arbitrate()\n" );
+#endif
+
+ outb( 0x00, SCSI_Cntl_port ); /* Disable data drivers */
+ outb( 0x40, port_base + SCSI_Data_NoACK ); /* Set our id bit */
+ outb( 0x04, TMC_Cntl_port ); /* Start arbitration */
+
+ timeout = jiffies + 50; /* 500 mS */
+ while (jiffies < timeout) {
+ status = inb( TMC_Status_port ); /* Read adapter status */
+ if (status & 0x02) return 0; /* Arbitration complete */
+ }
+
+ /* Make bus idle */
+ fdomain_make_bus_idle();
+
+#if EVERY_ACCESS
+ printk( "Arbitration failed, status = %x\n", status );
+#endif
+#if ERRORS_ONLY
+ printk( "SCSI: Arbitration failed, status = %x", status );
+#endif
+ return 1;
+}
+
+static int fdomain_select( int target )
+{
+ int status;
+ unsigned long timeout;
+
+ outb( 0x80, SCSI_Cntl_port ); /* Bus Enable */
+ outb( 0x8a, SCSI_Cntl_port ); /* Bus Enable + Attention + Select */
+
+ /* Send our address OR'd with target address */
+#if SEND_IDENTIFY
+ outb( 0x40 | (1 << target), port_base + SCSI_Data_NoACK );
+#else
+ outb( (1 << target), port_base + SCSI_Data_NoACK );
+#endif
+
+ /* Stop arbitration (also set FIFO for output and enable parity) */
+ outb( 0xc8, TMC_Cntl_port );
+
+ timeout = jiffies + 25; /* 250mS */
+ while (jiffies < timeout) {
+ status = inb( SCSI_Status_port ); /* Read adapter status */
+ if (status & 1) { /* Busy asserted */
+ /* Enable SCSI Bus (on error, should make bus idle with 0) */
+#if SEND_IDENTIFY
+ /* Also, set ATN so that the drive will make a MESSAGE OUT phase */
+ outb( 0x88, SCSI_Cntl_port );
+#else
+ outb( 0x80, SCSI_Cntl_port );
+#endif
+ return 0;
+ }
+ }
+ /* Make bus idle */
+ fdomain_make_bus_idle();
+#if EVERY_ACCESS
+ if (!target) printk( "Select failed\n" );
+#endif
+#if ERRORS_ONLY
+ if (!target) printk( "SCSI: Select failed" );
+#endif
+ return 1;
+}
+
+#if QUEUE
+
+#if !USE_FIFO
+#pragma error QUEUE requires USE_FIFO
+#endif
+
+void my_done( int error )
+{
+ if (in_command) {
+ in_command = 0;
+ in_interrupt_code = 0;
+ outb( 0x00, Interrupt_Cntl_port );
+ fdomain_make_bus_idle();
+ if (current_done) current_done( this_host, error );
+ else panic( "SCSI (Future Domain): current_done() == NULL" );
+ } else {
+ panic( "SCSI (Future Domain): my_done() called outside of command\n" );
+ }
+}
+
+#if NEW_IRQ
+void fdomain_16x0_intr( int unused )
+#else
+void fdomain_16x0_intr( void )
+#endif
+{
+ int status;
+ int done = 0;
+ unsigned data_count;
+
+#if NEW_IRQ
+ sti();
+#endif
+
+ if (in_interrupt_code)
+ panic( "SCSI (Future Domain): fdomain_16x0_intr() NOT REENTRANT!\n" );
+ else
+ ++in_interrupt_code;
+
+ outb( 0x00, Interrupt_Cntl_port );
+
+#if EVERY_ACCESS
+ printk( "aborted = %d, ", aborted );
+#endif
+
+ if (aborted) {
+ /* Force retry for timeouts after selection complete */
+ if (current_phase == in_other)
+ my_done( DID_BUS_BUSY << 16 );
+ else
+ my_done( aborted << 16 );
+#if NEW_IRQ && !DECREASE_IL
+ cli();
+#endif
+ return;
+ }
+
+ /* We usually have one spurious interrupt after each command. Ignore it. */
+ if (!in_command) { /* Spurious interrupt */
+ in_interrupt_code = 0;
+#if NEW_IRQ && !DECREASE_IL
+ cli();
+#endif
+ return;
+ }
+
+ if (current_phase == in_arbitration) {
+ status = inb( TMC_Status_port ); /* Read adapter status */
+ if (!(status & 0x02)) {
+#if EVERY_ACCESS
+ printk( " AFAIL " );
+#endif
+ my_done( DID_TIME_OUT << 16 );
+#if NEW_IRQ && !DECREASE_IL
+ cli();
+#endif
+ return;
+ }
+ current_phase = in_selection;
+
+ outb( 0x80, SCSI_Cntl_port ); /* Bus Enable */
+ outb( 0x8a, SCSI_Cntl_port ); /* Bus Enable + Attention + Select */
+
+ outb( (1 << current_target), port_base + SCSI_Data_NoACK );
+
+ outb( 0x40, Interrupt_Cntl_port );
+ /* Stop arbitration (also set FIFO for output and enable parity) */
+ in_interrupt_code = 0;
+ outb( 0xd8, TMC_Cntl_port );
+#if NEW_IRQ && !DECREASE_IL
+ cli();
+#endif
+ return;
+ } else if (current_phase == in_selection) {
+ status = inb( SCSI_Status_port );
+ if (!(status & 0x01)) {
+#if EVERY_ACCESS
+ printk( " SFAIL " );
+#endif
+ my_done( DID_NO_CONNECT << 16 );
+#if NEW_IRQ && !DECREASE_IL
+ cli();
+#endif
+ return;
+ }
+ current_phase = in_other;
+#if FAST_SYNCH
+ outb( 0xc0, Data_Mode_Cntl_port );
+#endif
+ in_interrupt_code = 0;
+ outb( 0x90, Interrupt_Cntl_port );
+ outb( 0x80, SCSI_Cntl_port );
+#if NEW_IRQ && !DECREASE_IL
+ cli();
+#endif
+ return;
+ }
+
+ /* current_phase == in_other: this is the body of the routine */
+
+ switch ((unsigned char)*the_command) {
+ case 0x04: case 0x07: case 0x0a: case 0x15: case 0x2a:
+ case 0x2e: case 0x3b: case 0xea: case 0x3f:
+ data_count = 0x2000 - inw( FIFO_Data_Count_port );
+ if (current_bufflen - data_sent < data_count)
+ data_count = current_bufflen - data_sent;
+ if (data_count > 0) {
+/* if (data_count > 512) data_count = 512; */
+#if EVERY_ACCESS
+ printk( "%d OUT, ", data_count );
+#endif
+ if (data_count == 1) {
+ outb( *out_buf_pt++, Write_FIFO_port );
+ ++data_sent;
+ } else {
+ data_count >>= 1;
+ outsw( out_buf_pt, data_count, Write_FIFO_port );
+ out_buf_pt += 2 * data_count;
+ data_sent += 2 * data_count;
+ }
+ }
+ break;
+ default:
+ if (!have_data_in) {
+ outb( 0x98, TMC_Cntl_port );
+ ++have_data_in;
+ } else {
+ data_count = inw( FIFO_Data_Count_port );
+/* if (data_count > 512) data_count = 512; */
+ if (data_count) {
+#if EVERY_ACCESS
+ printk( "%d IN, ", data_count );
+#endif
+ if (data_count == 1) {
+ *in_buf_pt++ = inb( Read_FIFO_port );
+ } else {
+ data_count >>= 1; /* Number of words */
+ insw( in_buf_pt, data_count, Read_FIFO_port );
+ in_buf_pt += 2 * data_count;
+ }
+ }
+ }
+ break;
+ }
+
+ status = inb( SCSI_Status_port );
+
+ if (status & 0x10) { /* REQ */
+
+ switch (status & 0x0e) {
+ case 0x08: /* COMMAND OUT */
+ outb( *cmd_pt++, Write_SCSI_Data_port );
+#if EVERY_ACCESS
+ printk( "CMD = %x,", (unsigned char)cmd_pt[-1] );
+#endif
+ break;
+ case 0x0c: /* STATUS IN */
+ Status = inb( Read_SCSI_Data_port );
+#if EVERY_ACCESS
+ printk( "Status = %x, ", Status );
+#endif
+#if ERRORS_ONLY
+ if (Status) {
+ printk( "SCSI: target = %d, command = %x, Status = %x\n",
+ current_target, (unsigned char)*the_command, Status );
+ }
+#endif
+ break;
+ case 0x0a: /* MESSAGE OUT */
+#if SEND_IDENTIFY
+ /* On the first request, send an Identify message */
+ if (!sent_identify) {
+ outb( 0x80, SCSI_Cntl_port ); /* Lower ATN */
+ outb( 0x80, Write_SCSI_Data_port ); /* Identify */
+ ++sent_identify;
+ } else
+#else
+ outb( 0x07, Write_SCSI_Data_port ); /* Reject */
+#endif
+ break;
+ case 0x0e: /* MESSAGE IN */
+ Message = inb( Read_SCSI_Data_port );
+#if EVERY_ACCESS
+ printk( "Message = %x, ", Message );
+#endif
+ if (!Message) ++done;
+ break;
+ }
+ }
+
+ if (done) {
+#if EVERY_ACCESS
+ printk( " ** IN DONE ** " );
+#endif
+
+ if (have_data_in) {
+ while (data_count = inw( FIFO_Data_Count_port )) {
+ if (data_count == 1) {
+ *in_buf_pt++ = inb( Read_FIFO_port );
+ } else {
+ data_count >>= 1; /* Number of words */
+ insw( in_buf_pt, data_count, Read_FIFO_port );
+ in_buf_pt += 2 * data_count;
+ }
+ }
+ }
+#if EVERY_ACCESS
+ printk( "AFTER DATA GET\n" );
+#endif
+
+#if ERRORS_ONLY
+ if (*the_command == REQUEST_SENSE && !Status) {
+ if ((unsigned char)(*((char *)current_buff + 2)) & 0x0f) {
+ printk( "SCSI REQUEST SENSE: Sense Key = %x, Sense Code = %x\n",
+ (unsigned char)(*((char *)current_buff + 2)) & 0x0f,
+ (unsigned char)(*((char *)current_buff + 12)) );
+ }
+ }
+#endif
+#if EVERY_ACCESS
+ printk( "BEFORE MY_DONE\n" );
+#endif
+ my_done( (Status & 0xff) | ((Message & 0xff) << 8) | (DID_OK << 16) );
+ } else {
+ in_interrupt_code = 0;
+ outb( 0x90, Interrupt_Cntl_port );
+ }
+
+#if NEW_IRQ && !DECREASE_IL
+ cli();
+#endif
+ return;
+}
+
+int fdomain_16x0_queue( unsigned char target, const void *cmnd,
+ void *buff, int bufflen, void (*done)(int,int) )
+{
+ if (in_command) {
+ panic( "SCSI (Future Domain): fdomain_16x0_queue() NOT REENTRANT!\n" );
+ }
+#if EVERY_ACCESS
+ printk( "queue %d %x\n", target, *(unsigned char *)cmnd );
+#endif
+
+ fdomain_make_bus_idle();
+
+ aborted = 0;
+ current_target = target;
+ memcpy( current_cmnd, cmnd, ((*(unsigned char *)cmnd) <= 0x1f ? 6 : 10 ) );
+ current_buff = buff;
+ current_bufflen = bufflen;
+ current_done = done;
+
+ /* Initialize static data */
+ cmd_pt = current_cmnd;
+ the_command = current_cmnd;
+ out_buf_pt = current_buff;
+ in_buf_pt = current_buff;
+
+ Status = 0;
+ Message = 0;
+ data_sent = 0;
+ have_data_in = 0;
+
+ /* Start arbitration */
+ current_phase = in_arbitration;
+ outb( 0x00, Interrupt_Cntl_port );
+ outb( 0x00, SCSI_Cntl_port ); /* Disable data drivers */
+ outb( 0x40, port_base + SCSI_Data_NoACK ); /* Set our id bit */
+ ++in_command;
+ outb( 0x20, Interrupt_Cntl_port );
+ outb( 0x1c, TMC_Cntl_port ); /* Start arbitration */
+
+ return 0;
+}
+#endif
+
+int fdomain_16x0_command( unsigned char target, const void *cmnd,
+ void *buff, int bufflen )
+{
+ const char *cmd_pt = cmnd;
+ const char *the_command = cmnd;
+ unsigned char *out_buf_pt = buff;
+ unsigned char *in_buf_pt = buff;
+ int Status = 0;
+ int Message = 0;
+ int status;
+ int done = 0;
+ unsigned long timeout;
+ unsigned data_sent = 0;
+ unsigned data_count;
+#if USE_FIFO
+ int have_data_in = 0;
+#endif
+#if SEND_IDENTITY
+ int sent_identify = 0;
+#endif
+
+#if EVERY_ACCESS
+ printk( "fdomain_command(%d, %x): ", target, (unsigned char)*the_command );
+#endif
+
+ if (fdomain_arbitrate()) {
+#if ERRORS_ONLY
+ printk( ", target = %d, command = %x\n",
+ target, (unsigned char)*the_command );
+#endif
+ return DID_TIME_OUT << 16;
+ }
+
+ if (fdomain_select( target )) {
+#if ERRORS_ONLY
+ if (!target) printk( ", target = %d, command = %x\n",
+ target, (unsigned char)*the_command );
+#endif
+ return DID_NO_CONNECT << 16;
+ }
+
+ timeout = jiffies + 500; /* 5000 mS -- For Maxtor after a RST */
+ aborted = 0; /* How is this supposed to get reset??? */
+
+#if FAST_SYNCH
+ outb( 0xc0, Data_Mode_Cntl_port );
+#endif
+
+#if USE_FIFO
+ switch ((unsigned char)*the_command) {
+ case 0x04: case 0x07: case 0x0a: case 0x15: case 0x2a:
+ case 0x2e: case 0x3b: case 0xea: case 0x3f:
+ data_count = 0x2000 - inw( FIFO_Data_Count_port );
+ if (bufflen - data_sent < data_count)
+ data_count = bufflen - data_sent;
+ if (data_count == 1) {
+ outb( *out_buf_pt++, Write_FIFO_port );
+ ++data_sent;
+ } else {
+ data_count >>= 1;
+ outsw( out_buf_pt, data_count, Write_FIFO_port );
+ out_buf_pt += 2 * data_count;
+ data_sent += 2 * data_count;
+ }
+ break;
+ default:
+ outb( 0x88, TMC_Cntl_port );
+ ++have_data_in;
+ break;
+ }
+#endif
+
+ while (((status = inb( SCSI_Status_port )) & 1)
+ && !done && !aborted && jiffies < timeout) {
+
+ if (status & 0x10) { /* REQ */
+
+ switch (status & 0x0e) {
+ case 0x00: /* DATA OUT */
+#if USE_FIFO
+ data_count = 0x2000 - inw( FIFO_Data_Count_port );
+ if (bufflen - data_sent < data_count)
+ data_count = bufflen - data_sent;
+ if (data_count == 1) {
+ outb( *out_buf_pt++, Write_FIFO_port );
+ ++data_sent;
+ } else {
+ data_count >>= 1;
+ outsw( out_buf_pt, data_count, Write_FIFO_port );
+ out_buf_pt += 2 * data_count;
+ data_sent += 2 * data_count;
+ }
+#else
+ outb( *out_buf_pt++, Write_SCSI_Data_port );
+#endif
+ break;
+ case 0x04: /* DATA IN */
+#if USE_FIFO
+ if (!have_data_in) {
+ outb( 0x88, TMC_Cntl_port );
+ ++have_data_in;
+ }
+ data_count = inw( FIFO_Data_Count_port );
+ if (data_count == 1) {
+ *in_buf_pt++ = inb( Read_FIFO_port );
+ } else {
+ data_count >>= 1; /* Number of words */
+ insw( in_buf_pt, data_count, Read_FIFO_port );
+ in_buf_pt += 2 * data_count;
+ }
+#else
+ *in_buf_pt++ = inb( Read_SCSI_Data_port );
+#endif
+ break;
+ case 0x08: /* COMMAND OUT */
+ outb( *cmd_pt++, Write_SCSI_Data_port );
+#if EVERY_ACCESS
+ printk( "%x,", (unsigned char)cmd_pt[-1] );
+#endif
+ break;
+ case 0x0c: /* STATUS IN */
+ Status = inb( Read_SCSI_Data_port );
+#if EVERY_ACCESS
+ printk( "Status = %x, ", Status );
+#endif
+#if ERRORS_ONLY
+ if (Status) {
+ printk( "SCSI: target = %d, command = %x, Status = %x\n",
+ target, (unsigned char)*the_command, Status );
+ }
+#endif
+ break;
+ case 0x0a: /* MESSAGE OUT */
+#if SEND_IDENTIFY
+ /* On the first request, send an Identify message */
+ if (!sent_identify) {
+ outb( 0x80, SCSI_Cntl_port ); /* Lower ATN */
+ outb( 0x80, Write_SCSI_Data_port ); /* Identify */
+ ++sent_identify;
+ } else
+#else
+ outb( 0x07, Write_SCSI_Data_port ); /* Reject */
+#endif
+ break;
+ case 0x0e: /* MESSAGE IN */
+ Message = inb( Read_SCSI_Data_port );
+#if EVERY_ACCESS
+ printk( "Message = %x, ", Message );
+#endif
+ if (!Message) ++done;
+ break;
+ }
+ }
+ }
+
+ if (jiffies >= timeout) {
+#if EVERY_ACCESS
+ printk( "Time out, status = %x\n", status );
+#endif
+#if ERRORS_ONLY
+ printk( "SCSI: Time out, status = %x (target = %d, command = %x)\n",
+ status, target, (unsigned char)*the_command );
+#endif
+ fdomain_make_bus_idle();
+ return DID_BUS_BUSY << 16;
+ }
+
+ if (aborted) {
+#if EVERY_ACCESS
+ printk( "Aborted\n" );
+#endif
+#if ONLY_ERRORS
+ printk( "SCSI: Aborted (command = %x)\n", (unsigned char)*the_command );
+#endif
+ fdomain_16x0_reset();
+ return DID_ABORT << 16;
+ }
+
+#if USE_FIFO
+ if (have_data_in) {
+ while (data_count = inw( FIFO_Data_Count_port )) {
+ if (data_count == 1) {
+ *in_buf_pt++ = inb( Read_FIFO_port );
+ } else {
+ data_count >>= 1; /* Number of words */
+ insw( in_buf_pt, data_count, Read_FIFO_port );
+ in_buf_pt += 2 * data_count;
+ }
+ }
+ }
+#endif
+
+ fdomain_make_bus_idle();
+
+#if EVERY_ACCESS
+ printk( "Retcode = %x\n",
+ (Status & 0xff) | ((Message & 0xff) << 8) | (DID_OK << 16) );
+#endif
+#if ERRORS_ONLY
+ if (*the_command == REQUEST_SENSE && !Status) {
+ if ((unsigned char)(*((char *)buff + 2)) & 0x0f) {
+ printk( "SCSI REQUEST SENSE: Sense Key = %x, Sense Code = %x\n",
+ (unsigned char)(*((char *)buff + 2)) & 0x0f,
+ (unsigned char)(*((char *)buff + 12)) );
+ }
+ }
+#endif
+
+ return (Status & 0xff) | ((Message & 0xff) << 8) | (DID_OK << 16);
+}
+
+int fdomain_16x0_abort( int code )
+{
+
+#if EVERY_ACCESS
+ printk( " ABORT " );
+#endif
+
+#if QUEUE
+ cli();
+ if (!in_command) {
+ sti();
+ return 0;
+ }
+
+ aborted = code ? code : DID_ABORT;
+
+ sti();
+ fdomain_make_bus_idle();
+#else
+ aborted = code ? code : DID_ABORT;
+#endif
+
+ return 0;
+}
+
+int fdomain_16x0_reset( void )
+{
+ outb( 1, SCSI_Cntl_port );
+ do_pause( 2 );
+ outb( 0, SCSI_Cntl_port );
+ do_pause( 115 );
+ outb( 0, Data_Mode_Cntl_port );
+ outb( 0, TMC_Cntl_port );
+
+ aborted = DID_RESET;
+
+ return 0;
+}
+
+#if QUEUE && !NEW_IRQ
+
+/* This is copied from kernel/sys_calls.s
+ and from kernel/blk_drv/scsi/aha1542.c */
+
+__asm__("
+_fdomain_16x0_interrupt:
+ cld
+ push %gs
+ push %fs
+ push %es
+ push %ds
+ pushl %eax
+ pushl %ebp
+ pushl %edi
+ pushl %esi
+ pushl %edx
+ pushl %ecx
+ pushl %ebx
+ movl $0x10,%edx
+ mov %dx,%ds
+ mov %dx,%es
+ movl $0x17,%edx
+ mov %dx,%fs
+
+ movl $_fdomain_disable_interrupt,%edx
+ call *%edx
+
+ movb $0x20,%al
+ outb %al,$0xA0 # EOI to interrupt controller #1
+ jmp 1f # give port chance to breathe
+1: jmp 1f
+1: outb %al,$0x20
+
+ sti
+ movl $_fdomain_16x0_intr,%edx
+ call *%edx # ``interesting'' way of handling intr.
+ cli
+
+ movl $_fdomain_enable_interrupt,%edx
+ call *%edx
+
+ popl %ebx
+ popl %ecx
+ popl %edx
+ popl %esi
+ popl %edi
+ popl %ebp
+ popl %eax
+ pop %ds
+ pop %es
+ pop %fs
+ pop %gs
+ iret
+");
+#endif
+
+#endif
diff --git a/kernel/blk_drv/scsi/fdomain.h b/kernel/blk_drv/scsi/fdomain.h
new file mode 100644
index 0000000..78f2b09
--- /dev/null
+++ b/kernel/blk_drv/scsi/fdomain.h
@@ -0,0 +1,45 @@
+/* fdomain.h -- Header for Future Domain TMC-1660/TMC-1680 driver
+ * Created: Sun May 3 18:47:33 1992
+ * Revised: Sat May 23 22:42:55 1992 by root
+ * Author: Rickard E. Faith, faith@cs.unc.edu
+ * Copyright 1992 Rickard E. Faith
+ * This program comes with ABSOLUTELY NO WARRANTY.
+ *
+ * $Log$
+ */
+
+#ifndef _FDOMAIN_H
+#define _FDOMAIN_H
+
+#define QUEUE 1 /* Enable command queueing */
+
+int fdomain_16x0_detect( int );
+int fdomain_16x0_command( unsigned char target, const void *cmnd,
+ void *buff, int bufflen);
+int fdomain_16x0_abort( int );
+char *fdomain_16x0_info( void );
+int fdomain_16x0_reset( void );
+
+#if QUEUE
+int fdomain_16x0_queue( unsigned char target, const void *cmnd,
+ void *buff, int bufflen, void (*done)(int,int) );
+
+#define FDOMAIN_16X0 { "Future Domain TMC-1660/TMC-1680", \
+ fdomain_16x0_detect, \
+ fdomain_16x0_info, \
+ fdomain_16x0_command, \
+ fdomain_16x0_queue, \
+ fdomain_16x0_abort, \
+ fdomain_16x0_reset, \
+ 1, 6, 0 }
+#else
+#define FDOMAIN_16X0 { "Future Domain TMC-1660/TMC-1680", \
+ fdomain_16x0_detect, \
+ fdomain_16x0_info, \
+ fdomain_16x0_command, \
+ NULL, \
+ fdomain_16x0_abort, \
+ fdomain_16x0_reset, \
+ 0, 6, 0 }
+#endif
+#endif
diff --git a/kernel/blk_drv/scsi/hosts.c b/kernel/blk_drv/scsi/hosts.c
index 268bc71..b4f227c 100644
--- a/kernel/blk_drv/scsi/hosts.c
+++ b/kernel/blk_drv/scsi/hosts.c
@@ -8,10 +8,10 @@
/*
- This file contains the medium level SCSI
- host interface initialization, as well as the scsi_hosts array of SCSI
- hosts currently present in the system.
-*/
+ * This file contains the medium level SCSI
+ * host interface initialization, as well as the scsi_hosts array of SCSI
+ * hosts currently present in the system.
+ */
#include <linux/config.h>
@@ -30,10 +30,13 @@
#include "hosts.h"
#ifdef CONFIG_SCSI_AHA1542
-#include <sys/types.h>
#include "aha1542.h"
#endif
+#ifdef CONFIG_SCSI_FUTURE_DOMAIN
+#include "fdomain.h"
+#endif
+
#ifdef CONFIG_SCSI_SEAGATE
#include "seagate.h"
#endif
@@ -42,27 +45,31 @@
#include "ultrastor.h"
#endif
+#ifdef CONFIG_SCSI_7000FASST
+#include "7000fasst.h"
+#endif
+
/*
-static const char RCSid[] = "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/hosts.c,v 1.1 1992/04/24 18:01:50 root Exp root $";
+static const char RCSid[] = "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/hosts.c,v 1.1 1992/07/24 06:27:38 root Exp root $";
*/
/*
- The scsi host entries should be in the order you wish the
- cards to be detected. A driver may appear more than once IFF
- it can deal with being detected (and therefore initialized)
- with more than one simulatenous host number, can handle being
- rentrant, etc.
-
- They may appear in any order, as each SCSI host is told which host number it is
- during detection.
-*/
+ * The scsi host entries should be in the order you wish the
+ * cards to be detected. A driver may appear more than once IFF
+ * it can deal with being detected (and therefore initialized)
+ * with more than one simulatenous host number, can handle being
+ * rentrant, etc.
+ *
+ * They may appear in any order, as each SCSI host is told which host number it is
+ * during detection.
+ */
/*
- When figure is run, we don't want to link to any object code. Since
- the macro for each host will contain function pointers, we cannot
- use it and instead must use a "blank" that does no such
- idiocy.
-*/
+ * When figure is run, we don't want to link to any object code. Since
+ * the macro for each host will contain function pointers, we cannot
+ * use it and instead must use a "blank" that does no such
+ * idiocy.
+ */
#ifdef FIGURE_MAX_SCSI_HOSTS
#define BLANKIFY(what) BLANK_HOST
@@ -76,12 +83,19 @@ Scsi_Host scsi_hosts[] =
BLANKIFY(AHA1542),
#endif
+#ifdef CONFIG_SCSI_FUTURE_DOMAIN
+ BLANKIFY(FDOMAIN_16X0),
+#endif
+
#ifdef CONFIG_SCSI_SEAGATE
BLANKIFY(SEAGATE_ST0X),
#endif
#ifdef CONFIG_SCSI_ULTRASTOR
BLANKIFY(ULTRASTOR_14F),
#endif
+#ifdef CONFIG_SCSI_7000FASST
+ BLANKIFY(WD7000FASST),
+#endif
};
#ifdef FIGURE_MAX_SCSI_HOSTS
@@ -92,20 +106,17 @@ Scsi_Host scsi_hosts[] =
#ifdef FIGURE_MAX_SCSI_HOSTS
#include <stdio.h>
void main (void)
-{
+{
printf("%d", MAX_SCSI_HOSTS);
}
#else
/*
- Our semaphores and timeout counters, where size depends on MAX_SCSI_HOSTS here.
-*/
+ * Our semaphores and timeout counters, where size depends on MAX_SCSI_HOSTS here.
+ */
volatile unsigned char host_busy[MAX_SCSI_HOSTS];
volatile int host_timeout[MAX_SCSI_HOSTS];
volatile Scsi_Cmnd *host_queue[MAX_SCSI_HOSTS];
-/*
- scsi_init initializes the scsi hosts.
-*/
void scsi_init(void)
{
@@ -116,28 +127,31 @@ void scsi_init(void)
called = 1;
for (count = i = 0; i < MAX_SCSI_HOSTS; ++i)
{
- /*
- Initialize our semaphores. -1 is interpreted to mean
- "inactive" - where as 0 will indicate a time out condition.
- */
+/*
+ * Initialize our semaphores. -1 is interpreted to mean
+ * "inactive" - where as 0 will indicate a time out condition.
+ */
host_busy[i] = 0;
host_timeout[i] = 0;
host_queue[i] = NULL;
if ((scsi_hosts[i].detect) && (scsi_hosts[i].present = scsi_hosts[i].detect(i)))
- {
- printk ("Host %d is detected as a(n) %s.\n\r",
- count, scsi_hosts[i].name);
- printk ("%s", scsi_hosts[i].info());
- ++count;
- }
+ {
+ printk ("scsi%d : %s.\n\r",
+ count, scsi_hosts[i].name);
+ printk ("%s", scsi_hosts[i].info());
+ ++count;
+ }
}
- printk ("%d host adapters detected. \n\r", count);
+ printk ("scsi : %d hosts. \n\r", count);
}
}
#endif
-
+#else
+void main(void) {
+ printf("0\n");
+ }
#endif
diff --git a/kernel/blk_drv/scsi/hosts.h b/kernel/blk_drv/scsi/hosts.h
index 468a044..f5504d6 100644
--- a/kernel/blk_drv/scsi/hosts.h
+++ b/kernel/blk_drv/scsi/hosts.h
@@ -14,7 +14,7 @@
#endif
/*
- $Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/hosts.h,v 1.1 1992/04/24 18:01:50 root Exp root $
+ $Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/hosts.h,v 1.1 1992/07/24 06:27:38 root Exp root $
*/
/*
diff --git a/kernel/blk_drv/scsi/scsi.c b/kernel/blk_drv/scsi/scsi.c
index 22f3402..1469ce2 100644
--- a/kernel/blk_drv/scsi/scsi.c
+++ b/kernel/blk_drv/scsi/scsi.c
@@ -4,7 +4,13 @@
* Drew Eckhardt
*
* <drew@colorado.edu>
+ *
+ * Bug correction thanks go to :
+ * Rik Faith <faith@cs.unc.edu>
+ * Tommy Thorn <tthorn>
+ * Thomas Wuensche <tw@fgb1.fgb.mw.tu-meunchen.de>
*/
+
#include <linux/config.h>
#ifdef CONFIG_SCSI
@@ -25,7 +31,7 @@
#endif
/*
-static const char RCSid[] = "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/scsi.c,v 1.1 1992/04/24 18:01:50 root Exp root $";
+static const char RCSid[] = "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/scsi.c,v 1.1 1992/07/24 06:27:38 root Exp root $";
*/
#define INTERNAL_ERROR (printk ("Internal error in file %s, line %s.\n", __FILE__, __LINE__), panic(""))
@@ -48,10 +54,10 @@ Scsi_Device scsi_devices[MAX_SCSI_DEVICE];
#define SENSE_LENGTH 255
/*
- As the scsi do command functions are inteligent, and may need to
- redo a command, we need to keep track of the last command
- executed on each one.
-*/
+ * As the scsi do command functions are inteligent, and may need to
+ * redo a command, we need to keep track of the last command
+ * executed on each one.
+ */
#define WAS_RESET 0x01
#define WAS_TIMEDOUT 0x02
@@ -62,66 +68,70 @@ static Scsi_Cmnd last_cmnd[MAX_SCSI_HOSTS];
static int last_reset[MAX_SCSI_HOSTS];
/*
- This is the number of clock ticks we should wait before we time out
- and abort the command. This is for where the scsi.c module generates
- the command, not where it originates from a higher level, in which
- case the timeout is specified there.
-
+ * This is the number of clock ticks we should wait before we time out
+ * and abort the command. This is for where the scsi.c module generates
+ * the command, not where it originates from a higher level, in which
+ * case the timeout is specified there.
+ *
+ * ABORT_TIMEOUT and RESET_TIMEOUT are the timeouts for RESET and ABORT
+ * respectively.
+ */
- ABORT_TIMEOUT and RESET_TIMEOUT are the timeouts for RESET and ABORT
- respectively.
-*/
#ifdef DEBUG
#define SCSI_TIMEOUT 500
#else
#define SCSI_TIMEOUT 100
#endif
+
#ifdef DEBUG
#define SENSE_TIMEOUT SCSI_TIMEOUT
#define ABORT_TIMEOUT SCSI_TIMEOUT
#define RESET_TIMEOUT SCSI_TIMEOUT
#else
-
#define SENSE_TIMEOUT 50
#define RESET_TIMEOUT 50
#define ABORT_TIMEOUT 50
#define MIN_RESET_DELAY 25
-
#endif
+
/*
- As the actual SCSI command runs in the background, we must set up a
- flag that tells scan_scsis() when the result it has is valid.
- scan_scsis can set the_result to -1, and watch for it to become the
- actual return code for that call. the scan_scsis_done function() is
- our user specified completion function that is passed on to the
- scsi_do_cmd() function.
-*/
+ * As the actual SCSI command runs in the background, we must set up a
+ * flag that tells scan_scsis() when the result it has is valid.
+ * scan_scsis can set the_result to -1, and watch for it to become the
+ * actual return code for that call. the scan_scsis_done function() is
+ * our user specified completion function that is passed on to the
+ * scsi_do_cmd() function.
+ */
+volatile static int in_scan = 0;
static int the_result;
static unsigned char sense_buffer[SENSE_LENGTH];
static void scan_scsis_done (int host, int result)
{
#ifdef DEBUG
- printk ("scan_scsis_done(%d, %06x\n\r", host, result);
+ printk ("scan_scsis_done(%d, %06x)\n\r", host, result);
#endif
the_result = result;
}
/*
- Detecting SCSI devices :
- We scan all present host adapter's busses, from ID 0 to ID 6.
- We use the INQUIRY command, determine device type, and pass the ID /
- lun address of all sequential devices to the tape driver, all random
- devices to the disk driver.
-*/
+ * Detecting SCSI devices :
+ * We scan all present host adapter's busses, from ID 0 to ID 6.
+ * We use the INQUIRY command, determine device type, and pass the ID /
+ * lun address of all sequential devices to the tape driver, all random
+ * devices to the disk driver.
+ */
static void scan_scsis (void)
{
- int host_nr , dev, lun, type, maxed;
+ int host_nr , dev, lun, type, maxed, slave;
static unsigned char scsi_cmd [12];
static unsigned char scsi_result [256];
- for (host_nr = 0; host_nr < MAX_SCSI_HOSTS; ++host_nr)
+ ++in_scan;
+
+ for (slave = host_nr = 0; host_nr < MAX_SCSI_HOSTS; ++host_nr,
+ slave = 0)
if (scsi_hosts[host_nr].present)
{
for (dev = 0; dev < 7; ++dev)
@@ -133,7 +143,9 @@ static void scan_scsis (void)
{
lun = 0;
#endif
- /* Build an INQUIRY command block. */
+/*
+ * Build an INQUIRY command block.
+ */
scsi_cmd[0] = INQUIRY;
scsi_cmd[1] = (lun << 5) & 0xe0;
@@ -143,16 +155,17 @@ static void scan_scsis (void)
scsi_cmd[5] = 0;
the_result = -1;
#ifdef DEBUG
- memset ((void *) scsi_result , 0, 255);
+ memset ((void *) scsi_result , 0, 255);
#endif
scsi_do_cmd (host_nr, dev, (void *) scsi_cmd, (void *)
scsi_result, 256, scan_scsis_done,
SCSI_TIMEOUT, sense_buffer, 3);
- /* Wait for valid result */
+/*
+ * Wait for valid result
+ */
while (the_result < 0);
-
if (!the_result)
{
@@ -165,113 +178,143 @@ static void scan_scsis (void)
scsi_devices[NR_SCSI_DEVICES].
removable = (0x80 &
scsi_result[1]) >> 7;
-
-
-
/*
- Currently, all sequential devices are assumed to be tapes,
- all random devices disk, with the appropriate read only
- flags set for ROM / WORM treated as RO.
-*/
+ * Currently, all sequential devices are assumed to be tapes,
+ * all random devices disk, with the appropriate read only
+ * flags set for ROM / WORM treated as RO.
+ */
switch (type = scsi_result[0])
- {
- case TYPE_TAPE:
- case TYPE_DISK:
- scsi_devices[NR_SCSI_DEVICES].writeable = 1;
- break;
- case TYPE_WORM:
- case TYPE_ROM:
- scsi_devices[NR_SCSI_DEVICES].writeable = 0;
- break;
- default:
- type = -1;
- }
+ {
+ case TYPE_TAPE :
+ case TYPE_DISK :
+ scsi_devices[NR_SCSI_DEVICES].writeable = 1;
+ break;
+ case TYPE_WORM :
+ case TYPE_ROM :
+ scsi_devices[NR_SCSI_DEVICES].writeable = 0;
+ break;
+ default :
+ type = -1;
+ }
scsi_devices[NR_SCSI_DEVICES].random = (type == TYPE_TAPE) ? 0 : 1;
maxed = 0;
switch (type)
- {
- case -1:
- break;
- case TYPE_TAPE:
- printk("Detected scsi tape at host %d, ID %d, lun %d \n", host_nr, dev, lun);
+ {
+ case -1 :
+ break;
+ case TYPE_TAPE :
+#ifdef DEBUG
+ printk("Detected scsi tape at host %d, ID %d, lun %d \n", host_nr, dev, lun);
+#endif
#ifdef CONFIG_BLK_DEV_ST
- if (!(maxed = (NR_ST == MAX_ST)))
- scsi_tapes[NR_ST].device = &scsi_devices[NR_SCSI_DEVICES];
+ if (!(maxed = (NR_ST == MAX_ST)))
+ scsi_tapes[NR_ST].device = &scsi_devices[NR_SCSI_DEVICES];
+#endif
+ break;
+ default :
+#ifdef DEBUG
+ printk("Detected scsi disk at host %d, ID %d, lun %d \n", host_nr, dev, lun);
#endif
- default:
- printk("Detected scsi disk at host %d, ID %d, lun %d \n", host_nr, dev, lun);
#ifdef CONFIG_BLK_DEV_SD
- if (!(maxed = (NR_SD >= MAX_SD)))
- rscsi_disks[NR_SD].device = &scsi_devices[NR_SCSI_DEVICES];
+ if (!(maxed = (NR_SD >= MAX_SD)))
+ rscsi_disks[NR_SD].device = &scsi_devices[NR_SCSI_DEVICES];
#endif
- }
+ }
- if (maxed)
- {
- printk ("Already have detected maximum number of SCSI %ss Unable to \n"
- "add drive at SCSI host %s, ID %d, LUN %d\n\r", (type == TYPE_TAPE) ?
- "tape" : "disk", scsi_hosts[host_nr].name,
- dev, lun);
- type = -1;
- break;
- }
+ if (maxed)
+ {
+ printk ("scsi : already have detected maximum number of SCSI %ss Unable to \n"
+ "add drive at SCSI host %s, ID %d, LUN %d\n\r", (type == TYPE_TAPE) ?
+ "tape" : "disk", scsi_hosts[host_nr].name,
+ dev, lun);
+ type = -1;
+ break;
+ }
- else if (type != -1)
- {
- if (type == TYPE_TAPE)
+ else if (type != -1)
+ {
+ char *p;
+ char str[25];
+memcpy((void *) str, (void *) &scsi_result[8], 8);
+for (p = str; (p < (str + 8)) && (*p != ' '); ++p);
+*p++ = ' ';
+memcpy((void *) p, (void *) &scsi_result[16], 16);
+for (; *p != ' '; ++p);
+*p = 0;
+
+printk("s%c%d at scsi%d, id %d, lun %d : %s\n",
+ (type == TYPE_TAPE) ? 't' : 'd',
+ (type == TYPE_TAPE) ?
#ifdef CONFIG_BLK_DEV_ST
- ++NR_ST;
+ NR_ST
+#else
+ -1
+#endif
+ :
+#ifdef CONFIG_BLK_DEV_SD
+ NR_SD
+#else
+ -1
+#endif
+ ,host_nr , dev, lun, p);
+ if (type == TYPE_TAPE)
+#ifdef CONFIG_BLK_DEV_ST
+ ++NR_ST;
#else
;
#endif
- else
+ else
#ifdef CONFIG_BLK_DEV_SD
- ++NR_SD;
+ ++NR_SD;
#else
;
#endif
}
+ ++slave;
++NR_SCSI_DEVICES;
} /* if result == DID_OK ends */
} /* for lun ends */
} /* if present */
- printk("Detected "
+ printk("scsi : detected "
#ifdef CONFIG_BLK_DEV_SD
-"%d disk%s "
+ "%d SCSI disk%s "
#endif
#ifdef CONFIG_BLK_DEV_ST
-"%d tape%s "
+ "%d tape%s "
#endif
-"total.\n",
+ "total.\n",
#ifdef CONFIG_BLK_DEV_SD
-NR_SD, (NR_SD != 1) ? "s" : ""
+ NR_SD, (NR_SD != 1) ? "s" : ""
#ifdef CONFIG_BLK_DEV_ST
-,
+ ,
#endif
#endif
#ifdef CONFIG_BLK_DEV_ST
-NR_ST, (NR_ST != 1) ? "s" : ""
+ NR_ST, (NR_ST != 1) ? "s" : ""
#endif
-);
+ );
+ in_scan = 0;
} /* scan_scsis ends */
/*
- We handle the timeout differently if it happens when a reset,
- abort, etc are in process.
-*/
+ * We handle the timeout differently if it happens when a reset,
+ * abort, etc are in process.
+ */
static unsigned char internal_timeout[MAX_SCSI_HOSTS];
-/* Flag bits for the internal_timeout array */
+/*
+ * Flag bits for the internal_timeout array
+ */
#define NORMAL_TIMEOUT 0
#define IN_ABORT 1
@@ -288,7 +331,8 @@ static void scsi_times_out (int host)
switch (internal_timeout[host] & (IN_ABORT | IN_RESET))
{
case NORMAL_TIMEOUT:
- printk("SCSI host %d timed out - aborting command \r\n",
+ if (!in_scan)
+ printk("SCSI host %d timed out - aborting command \r\n",
host);
if (!scsi_abort (host, DID_TIME_OUT))
@@ -439,11 +483,11 @@ void scsi_do_cmd (int host, unsigned char target, const void *cmnd ,
{
sti();
#ifdef DEBUG
- printk("Host %d is busy.\n" );
+ printk("Host %d is busy.\n", host);
#endif
while (host_busy[host]);
#ifdef DEBUG
- printk("Host %d is no longer busy.");
+ printk("Host %d is no longer busy.\n", host);
#endif
}
else
@@ -784,8 +828,8 @@ static void scsi_done (int host, int result)
#ifdef DEBUG
printk("Calling done function - at address %08x\n", last_cmnd[host].done);
#endif
- last_cmnd[host].done (host, (result | ((exit & 0xff) << 24)));
host_busy[host] = 0;
+ last_cmnd[host].done (host, (result | ((exit & 0xff) << 24)));
}
@@ -825,11 +869,11 @@ int scsi_abort (int host, int why)
}
else
{
+ oldto = host_timeout[host];
internal_timeout[host] |= IN_ABORT;
host_timeout[host] = ABORT_TIMEOUT;
update_timeout();
- oldto = host_timeout[host];
sti();
if (!host_busy[host] || !scsi_hosts[host].abort(why))
@@ -937,7 +981,7 @@ static int time_start, time_elapsed;
static void update_timeout(void)
{
- int i, least, used;
+ unsigned int i, least, used;
cli();
@@ -992,9 +1036,9 @@ void scsi_dev_init (void)
timer_table[SCSI_TIMER].expires = 0;
scsi_init(); /* initialize all hosts */
- /*
- Set up sense command in each host structure.
- */
+/*
+ * Set up sense command in each host structure.
+ */
for (i = 0; i < MAX_SCSI_HOSTS; ++i)
{
diff --git a/kernel/blk_drv/scsi/scsi.h b/kernel/blk_drv/scsi/scsi.h
index 1a949ab..60ca176 100644
--- a/kernel/blk_drv/scsi/scsi.h
+++ b/kernel/blk_drv/scsi/scsi.h
@@ -9,7 +9,7 @@
#ifndef _SCSI_H
#define _SCSI_H
/*
- $Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/scsi.h,v 1.1 1992/04/24 18:01:50 root Exp root $
+ $Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/scsi.h,v 1.1 1992/07/24 06:27:38 root Exp root $
For documentation on the OPCODES, MESSAGES, and SENSE values,
please consult the SCSI standard.
@@ -71,7 +71,12 @@
#define LINKED_CMD_COMPLETE 0x0a
#define LINKED_FLG_CMD_COMPLETE 0x0b
#define BUS_DEVICE_RESET 0x0c
-#define IDENTIFY 0x80
+#define IDENTIFY_BASE 0x80
+#define IDENTIFY(can_disconnect, lun) (IDENTIFY_BASE |\
+ ((can_disconnect) ? 0x40 : 0) |\
+ ((lun) & 0x07))
+
+
/*
Status codes
*/
@@ -129,6 +134,10 @@
Reset by somebody.
*/
#define DID_RESET 0x08
+/*
+ Got an interrupt we weren't expecting.
+*/
+#define DID_BAD_INTR 0x09
/*
Driver status
@@ -226,7 +235,7 @@ typedef struct scsi_device {
These are the SCSI devices available on the system.
*/
-#define MAX_SCSI_DEVICE 2
+#define MAX_SCSI_DEVICE 4
extern int NR_SCSI_DEVICES;
extern Scsi_Device scsi_devices[MAX_SCSI_DEVICE];
/*
@@ -253,5 +262,5 @@ extern void scsi_do_cmd (int host, unsigned char target, const void *cmnd ,
void *buffer, unsigned bufflen, void (*done)(int,int),
int timeout, unsigned char *sense_buffer, int retries);
-int scsi_reset (int host);
+extern int scsi_reset (int host);
#endif
diff --git a/kernel/blk_drv/scsi/scsi_ioctl.c b/kernel/blk_drv/scsi/scsi_ioctl.c
index b373c3b..8a700b1 100644
--- a/kernel/blk_drv/scsi/scsi_ioctl.c
+++ b/kernel/blk_drv/scsi/scsi_ioctl.c
@@ -1,11 +1,11 @@
#include <linux/config.h>
#ifdef CONFIG_SCSI
-#include <errno.h>
#include <asm/io.h>
#include <asm/segment.h>
#include <asm/system.h>
+#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/string.h>
@@ -16,7 +16,7 @@
#define MAX_RETRIES 5
#define MAX_TIMEOUT 200
-#define MAX_BUF 1024
+#define MAX_BUF 8192
#define max(a,b) (((a) > (b)) ? (a) : (b))
@@ -44,21 +44,23 @@ static int ioctl_probe(int dev, void *buffer)
* The SCSI_IOCTL_SEND_COMMAND ioctl sends a command out to the SCSI host.
* The MAX_TIMEOUT and MAX_RETRIES variables are used.
*
- * dev is the SCSI device number, *(int *) arg the length of the input
- * data, *((int *)arg + 1) the output buffer.
+ * dev is the SCSI device struct ptr, *(int *) arg is the length of the
+ * input data, if any, not including the command string & counts,
+ * *((int *)arg + 1) is the output buffer size in bytes.
*
- * *(char *) ((int *) arg)[1] the actual command.
+ * *(char *) ((int *) arg)[2] the actual command byte.
*
- * Note that no more than MAX_BUF bytes will be transfered. Since
+ * Note that no more than MAX_BUF data bytes will be transfered. Since
* SCSI block device size is 512 bytes, I figured 1K was good.
+ * but (WDE) changed it to 8192 to handle large bad track buffers.
*
- * This size * does * include the initial lengths that were passed.
+ * This size *does not* include the initial lengths that were passed.
*
- * The SCSI command is read from the memory location immediately after the
- * length words, and the out data after the command. The SCSI routines know the
- * command size based on the length byte.
+ * The SCSI command is read from the memory location immediately after the
+ * length words, and the input data is right after the command. The SCSI
+ * routines know the command size based on the opcode decode.
*
- * The area is then filled in from the byte at offset 0.
+ * The output area is then filled in starting from the command byte.
*/
static int the_result[MAX_SCSI_HOSTS];
@@ -80,13 +82,13 @@ static int ioctl_command(Scsi_Device *dev, void *buffer)
return -EINVAL;
inlen = get_fs_long((int *) buffer);
- outlen = get_fs_long(((int *) buffer) + 1);
+ outlen = get_fs_long( ((int *) buffer) + 1);
cmd_in = (char *) ( ((int *)buffer) + 2);
opcode = get_fs_byte(cmd_in);
- memcpy_fromfs ((void *) cmd, cmd_in, cmdlen = COMMAND_SIZE (opcode));
- memcpy_fromfs ((void *) buf, (void *) (cmd_in + cmdlen), inlen);
+ memcpy_fromfs ((void *) cmd, cmd_in, cmdlen = COMMAND_SIZE (opcode));
+ memcpy_fromfs ((void *) buf, (void *) (cmd_in + cmdlen), inlen);
host = dev->host_no;
#ifndef DEBUG_NO_CMD
@@ -103,26 +105,29 @@ static int ioctl_command(Scsi_Device *dev, void *buffer)
}
} while (1);
- scsi_do_cmd(host, dev->id, cmd, buf, ((outlen > MAX_BUF) ?
- MAX_BUF : outlen), scsi_ioctl_done, MAX_TIMEOUT,
- buf, MAX_RETRIES);
+ scsi_do_cmd(host, dev->id, cmd, buf, ((outlen > MAX_BUF) ?
+ MAX_BUF : outlen), scsi_ioctl_done, MAX_TIMEOUT,
+ buf, MAX_RETRIES);
while (the_result[host] == -1)
/* nothing */;
temp = the_result[host];
- the_result[host]=0;
- memcpy_tofs (buffer, buf, (outlen > MAX_BUF) ? MAX_BUF : outlen);
+ the_result[host] = 0;
+ memcpy_tofs ((void *) cmd_in, buf, (outlen > MAX_BUF) ? MAX_BUF : outlen);
return temp;
#else
{
int i;
- printk("scsi_ioctl : device %d. command = ", dev);
+ printk("scsi_ioctl : device %d. command = ", dev->id);
for (i = 0; i < 10; ++i)
printk("%02x ", cmd[i]);
printk("\r\nbuffer =");
for (i = 0; i < 20; ++i)
printk("%02x ", buf[i]);
printk("\r\n");
+ printk("inlen = %d, outlen = %d, cmdlen = %d\n",
+ inlen, outlen, cmdlen);
+ printk("buffer = %d, cmd_in = %d\n", buffer, cmd_in);
}
return 0;
#endif
@@ -132,18 +137,18 @@ static int ioctl_command(Scsi_Device *dev, void *buffer)
/*
the scsi_ioctl() function differs from most ioctls in that it does
not take a major/minor number as the dev filed. Rather, it takes
- an index in scsi_devices[]
+ a pointer to a scsi_devices[] element, a structure.
*/
-int scsi_ioctl (int dev, int cmd, void *arg)
+int scsi_ioctl (Scsi_Device *dev, int cmd, void *arg)
{
- if ((cmd != 0 && dev > NR_SCSI_DEVICES) || dev < 0)
+ if ((cmd != 0 && dev->id > NR_SCSI_DEVICES))
return -ENODEV;
- if ((cmd == 0 && dev > MAX_SCSI_HOSTS))
+ if ((cmd == 0 && dev->host_no > MAX_SCSI_HOSTS))
return -ENODEV;
switch (cmd) {
case SCSI_IOCTL_PROBE_HOST:
- return ioctl_probe(dev, arg);
+ return ioctl_probe(dev->host_no, arg);
case SCSI_IOCTL_SEND_COMMAND:
return ioctl_command((Scsi_Device *) dev, arg);
default :
diff --git a/kernel/blk_drv/scsi/sd.c b/kernel/blk_drv/scsi/sd.c
index 0ad47d3..5e034cc 100644
--- a/kernel/blk_drv/scsi/sd.c
+++ b/kernel/blk_drv/scsi/sd.c
@@ -9,16 +9,18 @@
#include <linux/config.h>
#ifdef CONFIG_BLK_DEV_SD
-#include <linux/string.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/sched.h>
+#include <linux/string.h>
+
#include "scsi.h"
#include "sd.h"
#define MAJOR_NR 8
#include "../blk.h"
+#include <linux/genhd.h>
/*
static const char RCSid[] = "$Header:";
@@ -30,15 +32,18 @@ static const char RCSid[] = "$Header:";
* Time out in seconds
*/
-#define SD_TIMEOUT 100
+#define SD_TIMEOUT 200
-Partition scsi_disks[MAX_SD << 4];
+struct hd_struct sd[MAX_SD << 4];
+
int NR_SD=0;
Scsi_Disk rscsi_disks[MAX_SD];
static int sd_sizes[MAX_SD << 4];
static int this_count;
static int the_result;
+static char sense_buffer[255];
+
extern int sd_ioctl(struct inode *, struct file *, unsigned long, unsigned long);
static void sd_release(struct inode * inode, struct file * file)
@@ -46,6 +51,17 @@ static void sd_release(struct inode * inode, struct file * file)
sync_dev(inode->i_rdev);
}
+static struct gendisk sd_gendisk;
+
+static void sd_geninit (void) {
+ int i;
+ for (i = 0; i < NR_SD; ++i)
+ sd_sizes[i << 4] =
+ (sd[i << 4].nr_sects = rscsi_disks[i].capacity) >>
+ (BLOCK_SIZE_BITS - 9);
+ sd_gendisk.nr_real = NR_SD;
+}
+
static struct file_operations sd_fops = {
NULL, /* lseek - default */
block_read, /* read - general block-dev read */
@@ -57,12 +73,19 @@ static struct file_operations sd_fops = {
sd_release /* release */
};
-/*
- The sense_buffer is where we put data for all mode sense commands
- performed.
-*/
-
-static unsigned char sense_buffer[255];
+static struct gendisk sd_gendisk = {
+ MAJOR_NR, /* Major number */
+ "sd", /* Major name */
+ 4, /* Bits to shift to get real from partition */
+ 1 << 4, /* Number of partitions per real */
+ MAX_SD, /* maximum number of real */
+ sd_geninit, /* init function */
+ sd, /* hd struct */
+ sd_sizes, /* block sizes */
+ 0, /* number */
+ (void *) rscsi_disks, /* internal */
+ NULL /* next */
+};
/*
rw_intr is the interrupt routine for the device driver. It will
@@ -75,30 +98,66 @@ static void rw_intr (int host, int result)
if (HOST != host)
panic ("sd.o : rw_intr() recieving interrupt for different host.");
+#ifdef DEBUG
+ printk("sd%d : rw_intr(%d, %x)\n", MINOR(CURRENT->dev), host, result);
+#endif
+
/*
First case : we assume that the command succeeded. One of two things will
happen here. Either we will be finished, or there will be more
sectors that we were unable to read last time.
*/
- if (!result)
- if (!(CURRENT->nr_sectors -= this_count)) {
- end_request(1);
- do_sd_request();
- } else {
- CURRENT->nr_sectors -= this_count;
+ if (!result) {
+ CURRENT->nr_sectors -= this_count;
+
+#ifdef DEBUG
+ printk("sd%d : %d sectors remain.\n", MINOR(CURRENT->dev), CURRENT->nr_sectors);
+#endif
+
+/*
+ * If multiple sectors are requested in one buffer, then
+ * they will have been finished off by the first command. If
+ * not, then we have a multi-buffer command.
+ */
+ if (CURRENT->nr_sectors)
+ {
+ CURRENT->sector += this_count;
+ CURRENT->errors = 0;
+
+ if (!CURRENT->bh)
+ {
+#ifdef DEBUG
+ printk("sd%d : handling page request, no buffer\n",
+ MINOR(CURRENT->dev));
+#endif
+
/*
The CURRENT->nr_sectors field is always done in 512 byte sectors,
even if this really isn't the case.
*/
-
- (char *) CURRENT->buffer += this_count << 9;
- CURRENT->sector += this_count;
- CURRENT->errors = 0;
- do_sd_request();
+ (char *) CURRENT->buffer += this_count << 9;
+ }
+ else
+ {
+#ifdef DEBUG
+ printk("sd%d : handling linked buffer request\n", MINOR(CURRENT->dev));
+#endif
+ end_request(1);
+ }
+ }
+ else
+ end_request(1);
+ do_sd_request();
}
/*
+ * Of course, the error handling code is a little Fubar down in scsi.c.
+ * Version 2 of the drivers will fix that, and we will *really* recover
+ * from errors.
+ */
+
+/*
Now, if we were good little boys and girls, Santa left us a request
sense buffer. We can extract information from this, so we
can choose a block to remap, etc.
@@ -148,7 +207,7 @@ static void rw_intr (int host, int result)
sense_class(sense_buffer[0]),
sense_error(sense_buffer[0]),
sense_buffer[2] & 0xf);
-
+
end_request(0);
}
}
@@ -159,11 +218,12 @@ static void rw_intr (int host, int result)
them to SCSI commands.
*/
-void do_sd_request (void)
+static void do_sd_request (void)
{
int dev, block;
unsigned char cmd[10];
+repeat:
INIT_REQUEST;
dev = MINOR(CURRENT->dev);
block = CURRENT->sector;
@@ -172,27 +232,31 @@ void do_sd_request (void)
printk("Doing sd request, dev = %d, block = %d\n", dev, block);
#endif
- if (dev >= (NR_SD << 4) || block + 2 > scsi_disks[dev].nr_sects ||
- (dev % 16) > 5)
+ if (dev >= (NR_SD << 4) || block + CURRENT->nr_sectors > sd[dev].nr_sects)
{
end_request(0);
goto repeat;
}
- block += scsi_disks[dev].start_sect;
+ block += sd[dev].start_sect;
dev = DEVICE_NR(dev);
#ifdef DEBUG
- printk("Real dev = %d, block = %d\n", dev, block);
+ printk("sd%d : real dev = /dev/sd%d, block = %d\n", MINOR(CURRENT->dev), dev, block);
#endif
- if (!rscsi_disks[dev].use)
- {
- end_request(0);
- goto repeat;
- }
+
+ if (!CURRENT->bh)
+ this_count = CURRENT->nr_sectors;
+ else
+ this_count = (BLOCK_SIZE / 512);
+
+#ifdef DEBUG
+ printk("sd%d : %s %d/%d 512 byte blocks.\n", MINOR(CURRENT->dev),
+ (CURRENT->cmd == WRITE) ? "writing" : "reading",
+ this_count, CURRENT->nr_sectors);
+#endif
- this_count = CURRENT->nr_sectors;
switch (CURRENT->cmd)
{
case WRITE :
@@ -210,7 +274,7 @@ void do_sd_request (void)
printk ("Unknown sd command %d\r\n", CURRENT->cmd);
panic("");
}
-
+
cmd[1] = (LUN << 5) & 0xe0;
if (((this_count > 0xff) || (block > 0x1fffff)) && rscsi_disks[dev].ten)
@@ -255,23 +319,31 @@ static void sd_init_done (int host, int result)
void sd_init(void)
{
- int i,j,k;
+ int i,j;
unsigned char cmd[10];
unsigned char buffer[513];
-
- Partition *p;
+ int try_again;
for (i = 0; i < NR_SD; ++i)
{
+ try_again=2;
cmd[0] = READ_CAPACITY;
- rscsi_disks[i].use = 1;
cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0;
- memset ((void *) &cmd[2], 0, 8);
+ memset ((void *) &cmd[2], 0, 8);
+
+/*
+ * Super Kludge - since the midlevel error handling code doesn't work
+ * Version 2 will - it's under development 8^)
+ *
+ * We manually retry
+ */
+
+
+ do {
the_result = -1;
#ifdef DEBUG
- printk("Read capacity, disk %d at host = %d, id = %d\n", i,
- rscsi_disks[i].device->host_no, rscsi_disks[i].device->id);
+ printk("sd%d : READ CAPACITY\n ", i);
#endif
scsi_do_cmd (rscsi_disks[i].device->host_no ,
rscsi_disks[i].device->id,
@@ -280,24 +352,25 @@ void sd_init(void)
MAX_RETRIES);
while(the_result < 0);
+ } while (try_again && the_result);
/*
- The SCSI standard says "READ CAPACITY is necessary for self confuring software"
- While not mandatory, support of READ CAPACITY is strongly encouraged.
-
- We used to die if we couldn't successfully do a READ CAPACITY.
- But, now we go on about our way. The side effects of this are
-
- 1. We can't know block size with certainty. I have said "512 bytes is it"
- as this is most common.
-
- 2. Recovery from when some one attempts to read past the end of the raw device will
- be slower.
-*/
-
+ * The SCSI standard says "READ CAPACITY is necessary for self confuring software"
+ * While not mandatory, support of READ CAPACITY is strongly encouraged.
+ * We used to die if we couldn't successfully do a READ CAPACITY.
+ * But, now we go on about our way. The side effects of this are
+ *
+ * 1. We can't know block size with certainty. I have said "512 bytes is it"
+ * as this is most common.
+ *
+ * 2. Recovery from when some one attempts to read past the end of the raw device will
+ * be slower.
+ */
+
if (the_result)
{
- printk ("Warning : SCSI device at host %d, id %d, lun %d failed READ CAPACITY.\n"
- "status = %x, message = %02x, host = %02x, driver = %02x \n",
+ printk ("sd%d : READ CAPACITY failed.\n"
+ "sd%d : status = %x, message = %02x, host = %02x, driver = %02x \n",
+ i,i,
rscsi_disks[i].device->host_no, rscsi_disks[i].device->id,
rscsi_disks[i].device->lun,
status_byte(the_result),
@@ -306,11 +379,11 @@ void sd_init(void)
driver_byte(the_result)
);
if (driver_byte(the_result) & DRIVER_SENSE)
- printk("Extended sense code = %1x \n", sense_buffer[2] & 0xf);
+ printk("sd%d : extended sense code = %1x \n", i, sense_buffer[2] & 0xf);
else
- printk("Sense not available. \n");
+ printk("sd%d : sense not available. \n", i);
- printk("Block size assumed to be 512 bytes, disk size 1GB. \n");
+ printk("sd%d : block size assumed to be 512 bytes, disk size 1GB. \n", i);
rscsi_disks[i].capacity = 0x1fffff;
rscsi_disks[i].sector_size = 512;
}
@@ -326,55 +399,24 @@ void sd_init(void)
(buffer[6] << 8) |
buffer[7]) != 512)
{
- printk ("Unsupported sector size %d for sd %d",
- rscsi_disks[i].sector_size, i);
- rscsi_disks[i].use = 0;
+ printk ("sd%d : unsupported sector size %d.\n",
+ i, rscsi_disks[i].sector_size);
+ printk ("scsi : deleting disk entry.\n");
+ for (j=i; j < NR_SD;)
+ rscsi_disks[j] = rscsi_disks[++j];
+ --i;
+ continue;
}
}
- if (rscsi_disks[i].use)
- {
- scsi_disks[j = (i << 4)].start_sect = 0;
-
- sd_sizes[j]=(scsi_disks[j].nr_sects = rscsi_disks[i].capacity)>>1;
-#ifdef DEBUG
- printk("/dev/sd%1d size = %d\n", j, sd_sizes[j]);
-#endif
- cmd[0] = READ_6;
- cmd[2] = cmd[3] = cmd[5] = 0;
- cmd[4] = 1;
- the_result = -1;
-
- scsi_do_cmd (rscsi_disks[i].device->host_no , rscsi_disks[i].device->id,
- (void *) cmd, (void *) buffer, 512, sd_init_done, SD_TIMEOUT,
- sense_buffer, MAX_RETRIES);
-
- while (the_result < 0);
-
-
- if (the_result || (0xaa55 != *(unsigned short *)(buffer + 510)))
- {
- printk ("Cannot read partition table for sd %d"
- "\n\r",i);
- rscsi_disks[i].use = 0;
- }
- else
- for (++j, k=j+4, p=(Partition *) (buffer + 0x1be); j < k; ++j, ++p)
- {
- memcpy ((void *) &scsi_disks[j], (void *) p, sizeof(Partition));
- sd_sizes[j]=(scsi_disks[j].nr_sects)>>1;
-#ifdef DEBUG
- printk("/dev/sd%1d size = %d (%d blocks), offset = %d\n", j, scsi_disks[j].nr_sects, sd_sizes[j], scsi_disks[j].start_sect);
-#endif
- }
-
- rscsi_disks[i].ten = 1;
- rscsi_disks[i].remap = 1;
- }
+ rscsi_disks[i].ten = 1;
+ rscsi_disks[i].remap = 1;
}
+
blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
blk_size[MAJOR_NR] = sd_sizes;
blkdev_fops[MAJOR_NR] = &sd_fops;
+ sd_gendisk.next = gendisk_head;
+ gendisk_head = &sd_gendisk;
}
#endif
-
diff --git a/kernel/blk_drv/scsi/sd.h b/kernel/blk_drv/scsi/sd.h
index e4c4613..aacb01f 100644
--- a/kernel/blk_drv/scsi/sd.h
+++ b/kernel/blk_drv/scsi/sd.h
@@ -8,32 +8,27 @@
#ifndef _SD_H
#define _SD_H
/*
- $Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/sd.h,v 1.1 1992/04/24 18:01:50 root Exp root $
+ $Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/sd.h,v 1.1 1992/07/24 06:27:38 root Exp root $
*/
#ifndef _SCSI_H
#include "scsi.h"
#endif
-#define MAX_SD 2
-
-typedef struct partition {
- unsigned char boot_ind; /* 0x80 - active (unused) */
- unsigned char head; /* ? */
- unsigned char sector; /* ? */
- unsigned char cyl; /* ? */
- unsigned char sys_ind; /* ? */
- unsigned char end_head; /* ? */
- unsigned char end_sector; /* ? */
- unsigned char end_cyl; /* ? */
- unsigned int start_sect; /* starting sector counting from 0 */
- unsigned int nr_sects; /* nr of sectors in partition */
-} Partition;
+#ifndef _GENDISK_H
+#include <linux/genhd.h>
+#endif
-extern int NR_SD;
+/*
+ This is an arbitrary constant, and may be changed to whatever
+ suits your purposes. Note that smaller will get you a few bytes
+ more in kernel space if that is your thing.
+*/
-extern Partition scsi_disks[MAX_SD << 4] ;
+#define MAX_SD 4
+extern int NR_SD;
+extern struct hd_struct sd[MAX_SD << 4];
typedef struct {
unsigned capacity; /* size in blocks */
@@ -42,9 +37,7 @@ typedef struct {
unsigned char sector_bit_size; /* sector_size = 2 to the bit size power */
unsigned char sector_bit_shift; /* power of 2 sectors per FS block */
unsigned ten:1; /* support ten byte read / write */
- unsigned remap:1; /* support remapping */
- unsigned use:1; /* after the initial inquiry, is
- the device still supported ? */
+ unsigned remap:1; /* support remapping */
} Scsi_Disk;
extern Scsi_Disk rscsi_disks[MAX_SD];
diff --git a/kernel/blk_drv/scsi/sd_ioctl.c b/kernel/blk_drv/scsi/sd_ioctl.c
index 5c55e16..d2f18d2 100644
--- a/kernel/blk_drv/scsi/sd_ioctl.c
+++ b/kernel/blk_drv/scsi/sd_ioctl.c
@@ -3,22 +3,18 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/fs.h>
-#include <asm/segment.h>
-#include "../blk.h"
-#include <errno.h>
#include "scsi.h"
#include "sd.h"
-extern int scsi_ioctl (int dev, int cmd, void *arg);
+extern int scsi_ioctl (Scsi_Device *dev, int cmd, void *arg);
int sd_ioctl(struct inode * inode, struct file * file, unsigned long cmd, unsigned long arg)
{
int dev = inode->i_rdev;
switch (cmd) {
- RO_IOCTLS(dev,arg);
default:
- return scsi_ioctl(rscsi_disks[MINOR(dev) >> 4].device,cmd,(void *) arg);
+ return scsi_ioctl(rscsi_disks[MINOR(dev) >> 4].device, cmd, (void *) arg);
}
}
#endif
diff --git a/kernel/blk_drv/scsi/seagate.c b/kernel/blk_drv/scsi/seagate.c
index 28df162..e36dbec 100644
--- a/kernel/blk_drv/scsi/seagate.c
+++ b/kernel/blk_drv/scsi/seagate.c
@@ -8,13 +8,19 @@
#include <linux/config.h>
-#ifdef CONFIG_SCSI_SEAGATE
+#if defined(CONFIG_SCSI_SEAGATE) || defined(CONFIG_SCSI_FD_88x)
+#include <asm/io.h>
+#include <asm/system.h>
#include <linux/sched.h>
-
#include "seagate.h"
#include "scsi.h"
#include "hosts.h"
+extern void seagate_intr(void);
+static int internal_command(unsigned char target, const void *cmnd,
+ void *buff, int bufflen, int reselect);
+void (*do_seagate)(void) = NULL;
+
static int incommand; /*
set if arbitration has finished and we are
in some command phase.
@@ -27,7 +33,7 @@ static void *base_address = NULL; /*
*/
static volatile int abort_confirm = 0;
-volatile void *st0x_cr_sr; /*
+static volatile void *st0x_cr_sr; /*
control register write,
status register read.
256 bytes in length.
@@ -71,9 +77,33 @@ typedef struct
} Signature;
static const Signature signatures[] = {
+#ifdef CONFIG_SCSI_SEAGATE
{"SCSI BIOS 2.00 (C) Copyright 1987 Seagate", 15, 40},
+
+/*
+ The following two lines are NOT mistakes. One detects
+ ROM revision 3.0.0, the other 3.2. Since seagate
+ has only one type of SCSI adapter, and this is not
+ going to change, the "SEAGATE" and "SCSI" together
+ are probably "good enough"
+*/
+
{"SEAGATE SCSI BIOS ",16, 17},
-{"SEAGATE SCSI BIOS ",17, 17}};
+{"SEAGATE SCSI BIOS ",17, 17},
+#endif
+
+/*
+ This is for the Future Domain 88x series. I've been told that
+ the Seagate controllers are just repackages of these, and seeing
+ early seagate BIOS bearing the Future Domain copyright,
+ I believe it.
+*/
+
+#ifdef CONFIG_SCSI_FD_88x
+{"FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/90", 5, 46},
+#endif
+}
+;
/*
Note that the last signature handles BIOS revisions 3.0.0 and
3.2 - the real ID's are
@@ -86,31 +116,44 @@ SEAGATE SCSI BIOS REVISION 3.2
#define NUM_SIGNATURES (sizeof(signatures) / sizeof(Signature))
#endif
+/*
+ * hostno stores the hostnumber, as told to us by the init routine.
+ */
+
+static int hostno = -1;
+
int seagate_st0x_detect (int hostnum)
{
- #ifndef OVERRIDE
- int i,j;
- #endif
+#ifndef OVERRIDE
+ int i,j;
+#endif
- /*
- First, we try for the manual override.
- */
- #ifdef DEBUG
- printk("Autodetecting seagate ST0x\n");
- #endif
+/*
+ * First, we try for the manual override.
+ */
+#ifdef DEBUG
+ printk("Autodetecting seagate ST0x\n");
+#endif
+
+ if (hostno != -1)
+ {
+ printk ("ERROR : seagate_st0x_detect() called twice.\n");
+ return 0;
+ }
base_address = NULL;
- #ifdef OVERRIDE
- base_address = (void *) OVERRIDE;
- #ifdef DEBUG
- printk("Base address overridden to %x\n", base_address);
- #endif
- #else
- /*
- To detect this card, we simply look for the SEAGATE SCSI
- from the BIOS version notice in all the possible locations
- of the ROM's.
- */
+#ifdef OVERRIDE
+ base_address = (void *) OVERRIDE;
+#ifdef DEBUG
+ printk("Base address overridden to %x\n", base_address);
+#endif
+#else
+/*
+ * To detect this card, we simply look for the signature
+ * from the BIOS version notice in all the possible locations
+ * of the ROM's. This has a nice sideeffect of not trashing
+ * any register locations that might be used by something else.
+ */
for (i = 0; i < (sizeof (seagate_bases) / sizeof (char * )); ++i)
for (j = 0; !base_address && j < NUM_SIGNATURES; ++j)
@@ -118,75 +161,182 @@ int seagate_st0x_detect (int hostnum)
signatures[j].offset), (void *) signatures[j].signature,
signatures[j].length))
base_address = (void *) seagate_bases[i];
- #endif
+ #endif
if (base_address)
{
st0x_cr_sr =(void *) (((unsigned char *) base_address) + 0x1a00);
st0x_dr = (void *) (((unsigned char *) base_address )+ 0x1c00);
- #ifdef DEBUG
- printk("ST0x detected. Base address = %x, cr = %x, dr = %x\n", base_address, st0x_cr_sr, st0x_dr);
- #endif
+#ifdef DEBUG
+ printk("ST0x detected. Base address = %x, cr = %x, dr = %x\n", base_address, st0x_cr_sr, st0x_dr);
+#endif
+ hostno = hostnum;
+
+/*
+ * At all times, we will use IRQ 5.
+ */
+
+#if 1
+ set_intr_gate (0x25, seagate_intr);
+ __asm__("
+ inb $0x21, %%al
+ andb $0xdf, %%al
+ outb %%al, $0x21"::);
+#endif
return -1;
}
else
{
- #ifdef DEBUG
- printk("ST0x not detected.\n");
- #endif
+#ifdef DEBUG
+ printk("ST0x not detected.\n");
+#endif
return 0;
}
}
-
-
char *seagate_st0x_info(void)
{
static char buffer[] = "Seagate ST-0X SCSI driver by Drew Eckhardt \n"
-"$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/seagate.c,v 1.1 1992/04/24 18:01:50 root Exp root $\n";
+"$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/seagate.c,v 1.1 1992/07/24 06:27:38 root Exp root $\n";
return buffer;
}
+/*
+ * These are our saved pointers for the outstanding command that is
+ * waiting for a reconnect
+ */
+
+static unsigned char current_target;
+static unsigned char *current_cmnd, *current_data;
+static int current_bufflen;
+static void (*done_fn)(int, int) = NULL;
+
+/*
+ * These control weather or not disconnect / reconnect will be attempted,
+ * or are being attempted.
+ */
+
+#define NO_RECONNECT 0
+#define RECONNECT_NOW 1
+#define CAN_RECONNECT 2
+
+/*
+ * This determines if we are expecting to reconnect or not.
+ */
+
+static int should_reconnect = 0;
+
+void seagate_unexpected_intr (void)
+ {
+ printk("scsi%d: unexpected interrupt.\n", hostno);
+ }
+
+/*
+ * The seagate_reconnect_intr routine is called when a target reselects the
+ * host adapter. This occurs on the interrupt triggered by the target
+ * asserting SEL.
+ */
+
+void seagate_reconnect_intr (void)
+ {
+ int temp;
+
+#if (DEBUG & PHASE_RESELECT)
+ printk("scsi%d : seagate_reconnect_intr() called\n", hostno);
+#endif
+
+ if (!should_reconnect)
+ seagate_unexpected_intr();
+ else
+ {
+ should_reconnect = 0;
+
+#if (DEBUG & PHASE_RESELECT)
+ printk("scsi%d : internal_command("
+ "%d, %08x, %08x, %d, RECONNECT_NOW\n", hostno,
+ current_target, current_data, current_bufflen);
+#endif
+
+ temp = internal_command (current_target,
+ current_cmnd, current_data, current_bufflen,
+ RECONNECT_NOW);
+
+ if (msg_byte(temp) != DISCONNECT)
+ {
+ if (done_fn)
+ {
+#if (DEBUG & PHASE_RESELECT)
+ printk("scsi%d : done_fn(%d,%08x)", hostno,
+ hostno, temp);
+#endif
+ done_fn (hostno, temp);
+ }
+ else
+ printk("done_fn() not defined.\n");
+ }
+ }
+ }
+/*
+ * The seagate_st0x_queue_command() function provides a queued interface
+ * to the seagate SCSI driver. Basically, it just passes control onto the
+ * seagate_command() function, after fixing it so that the done_fn()
+ * is set to the one passed to the function.
+ */
+
+int seagate_st0x_queue_command (unsigned char target, const void *cmnd,
+ void *buff, int bufflen, void (*fn)(int,
+ int))
+ {
+ int result;
+
+ done_fn = fn;
+ current_target = target;
+ (const void *) current_cmnd = cmnd;
+ current_data = buff;
+ current_bufflen = bufflen;
+
+ result = internal_command (target, cmnd, buff, bufflen,
+ CAN_RECONNECT);
+ if (msg_byte(result) == DISCONNECT)
+ return 0;
+ else
+ {
+ done_fn (hostno, result);
+ return 1;
+ }
+ }
-int seagate_st0x_command(unsigned char target, const void *cmnd,
- void *buff, int bufflen)
+int seagate_st0x_command (unsigned char target, const void *cmnd,
+ void *buff, int bufflen)
+ {
+ return internal_command (target, cmnd, buff, bufflen,
+ (int) NO_RECONNECT);
+ }
+
+static int internal_command(unsigned char target, const void *cmnd,
+ void *buff, int bufflen, int reselect)
{
int len;
unsigned char *data;
+ int clock;
+ int temp;
- int clock; /*
- We use clock for timeouts, etc. This replaces the
- seagate_st0x_timeout that we had been using.
- */
- #if (DEBUG & PHASE_SELECTION)
- int temp;
- #endif
-
- #if (DEBUG & PHASE_EXIT)
- void *retaddr, *realretaddr;
- #endif
- #if ((DEBUG & PHASE_ETC) || (DEBUG & PRINT_COMMAND) || (DEBUG & PHASE_EXIT))
- int i;
- #endif
+#if ((DEBUG & PHASE_ETC) || (DEBUG & PRINT_COMMAND) || (DEBUG & PHASE_EXIT))
+ int i;
+#endif
- #if (DEBUG & PHASE_ETC)
- int phase=0, newphase;
- #endif
+#if (DEBUG & PHASE_ETC)
+ int phase=0, newphase;
+#endif
int done = 0;
unsigned char status = 0;
unsigned char message = 0;
register unsigned char status_read;
- #if (DEBUG & PHASE_EXIT)
- __asm__("
-movl 4(%%ebp), %%eax
-":"=a" (realretaddr):);
- printk("return address = %08x\n", realretaddr);
- #endif
-
+ do_seagate = seagate_unexpected_intr;
len=bufflen;
data=(unsigned char *) buff;
@@ -194,73 +344,201 @@ movl 4(%%ebp), %%eax
incommand = 0;
st0x_aborted = 0;
- #if (DEBUG & PRINT_COMMAND)
- printk ("seagate_st0x_command, target = %d, command = ", target);
- for (i = 0; i < COMMAND_SIZE(((unsigned char *)cmnd)[0]); ++i)
- printk("%02x ", ((unsigned char *) cmnd)[i]);
- printk("\n");
- #endif
+#if (DEBUG & PRINT_COMMAND)
+ printk ("scsi%d : target = %d, command = ", hostno, target);
+ for (i = 0; i < COMMAND_SIZE(((unsigned char *)cmnd)[0]); ++i)
+ printk("%02x ", ((unsigned char *) cmnd)[i]);
+ printk("\n");
+#endif
+
+#if (DEBUG & PHASE_RESELECT)
+ switch (reselect)
+ {
+ case RECONNECT_NOW :
+ printk("scsi%d : reconnecting\n", hostno);
+ break;
+ case CAN_RECONNECT :
+ printk("scsi%d : allowed to reconnect\n", hostno);
+ break;
+ default :
+ printk("scsi%d : not allowed to reconnect\n", hostno);
+ }
+#endif
+
if (target > 6)
+ {
+ if (reselect == RECONNECT_NOW)
+ eoi();
return DID_BAD_TARGET;
+ }
-
- #if (DEBUG & PHASE_BUS_FREE)
- printk ("SCSI PHASE = BUS FREE \n");
- #endif
+/*
+ * We work it differently depending on if this is is "the first time,"
+ * or a reconnect. If this is a reselct phase, then SEL will
+ * be asserted, and we must skip selection / arbitration phases.
+ */
- /*
+ if (reselect == RECONNECT_NOW)
+ {
+#if (DEBUG & PHASE_RESELECT)
+ printk("scsi%d : phase RESELECT \n", hostno);
+#endif
- BUS FREE PHASE
+/*
+ * At this point, we should find the logical or of our ID and the original
+ * target's ID on the BUS, with BSY, SEL, and I/O signals asserted.
+ *
+ * After ARBITRATION phase is completed, only SEL, BSY, and the
+ * target ID are asserted. A valid initator ID is not on the bus
+ * until IO is asserted, so we must wait for that.
+ */
+
+ for (clock = jiffies + 10, temp = 0; (jiffies < clock) &&
+ !(STATUS & STAT_IO););
+
+ if (jiffies >= clock)
+ {
+#if (DEBUG & PHASE_RESELECT)
+ printk("scsi%d : RESELECT timed out while waiting for IO .\n",
+ hostno);
+#endif
+ eoi();
+ return (DID_BAD_INTR << 16);
+ }
- On entry, we make sure that the BUS is in a BUS FREE
- phase, by insuring that both BSY and SEL are low for
- at least one bus settle delay. The standard requires a
- minimum of 400 ns, which is 16 clock cycles on a
- 386-40 .
+/*
+ * After I/O is asserted by the target, we can read our ID and its
+ * ID off of the BUS.
+ */
+
+ if (!((temp = DATA) & 0x80))
+ {
+#if (DEBUG & PHASE_RESELECT)
+ printk("scsi%d : detected reconnect request to different target.\n"
+ "\tData bus = %d\n", hostno, temp);
+#endif
+ eoi();
+ return (DID_BAD_INTR << 16);
+ }
- This doesn't give us much time - so we'll do two several
- reads to be sure be sure.
- */
+ if (!(temp & (1 << current_target)))
+ {
+ printk("scsi%d : Unexpected reselect interrupt. Data bus = %d\n",
+ hostno, temp);
+ eoi();
+ return (DID_BAD_INTR << 16);
+ }
+ data=current_data; /* WDE add */
+ cmnd=current_cmnd; /* WDE add */
+ len=current_bufflen; /* WDE add */
- clock = jiffies + ST0X_BUS_FREE_DELAY;
+/*
+ * We have determined that we have been selected. At this point,
+ * we must respond to the reselection by asserting BSY ourselves
+ */
- while (((STATUS | STATUS | STATUS) &
- (STAT_BSY | STAT_SEL)) &&
- (!st0x_aborted) && (jiffies < clock));
+ CONTROL = (BASE_CMD | CMD_DRVR_ENABLE | CMD_BSY);
- if (jiffies > clock)
- return retcode(DID_BUS_BUSY);
- else if (st0x_aborted)
- return retcode(st0x_aborted);
+/*
+ * The target will drop SEL, and raise BSY, at which time we must drop
+ * BSY.
+ */
- /*
- Bus free has been detected, within BUS settle. I used to support an arbitration
- phase - however, on the seagate, this degraded performance by a factor > 10 - so
- it is no more.
- */
+ for (clock = jiffies + 10; (jiffies < clock) && (STATUS & STAT_SEL););
- /*
- SELECTION PHASE
+ if (jiffies >= clock)
+ {
+ CONTROL = (BASE_CMD | CMD_INTR);
+#if (DEBUG & PHASE_RESELECT)
+ printk("scsi%d : RESELECT timed out while waiting for SEL.\n",
+ hostno);
+#endif
+ eoi();
+ return (DID_BAD_INTR << 16);
+ }
- Now, we select the disk, giving it the SCSI ID at data
- and a command of PARITY if necessary, plus driver enable,
- plus raise select signal.
- */
+ CONTROL = BASE_CMD;
- #if (DEBUG & PHASE_SELECTION)
- printk("SCSI PHASE = SELECTION\n");
- #endif
+/*
+ * At this point, we have connected with the target and can get
+ * on with our lives.
+ */
+ eoi();
+ }
+ else
+ {
+#if (DEBUG & PHASE_BUS_FREE)
+ printk ("scsi%d : phase = BUS FREE \n", hostno);
+#endif
- clock = jiffies + ST0X_SELECTION_DELAY;
- DATA = (unsigned char) (1 << target);
+/*
+ * BUS FREE PHASE
+ *
+ * On entry, we make sure that the BUS is in a BUS FREE
+ * phase, by insuring that both BSY and SEL are low for
+ * at least one bus settle delay. Several reads help
+ * eliminate wire glitch.
+ */
- CONTROL = BASE_CMD | CMD_DRVR_ENABLE | CMD_SEL;
+ clock = jiffies + ST0X_BUS_FREE_DELAY;
- /*
- When the SCSI device decides that we're gawking at it, it will respond by asserting BUSY on the bus.
- */
- while (!((status_read = STATUS) & STAT_BSY) && (jiffies < clock) && !st0x_aborted)
+ while (((STATUS | STATUS | STATUS) &
+ (STAT_BSY | STAT_SEL)) &&
+ (!st0x_aborted) && (jiffies < clock));
+
+ if (jiffies > clock)
+ return retcode(DID_BUS_BUSY);
+ else if (st0x_aborted)
+ return retcode(st0x_aborted);
+
+/*
+ * Bus free has been detected, within BUS settle. I used to
+ * support an arbitration phase - however, on the Seagate, this
+ * degraded performance by a factor > 10 - so it is no more.
+ */
+
+/*
+ * SELECTION PHASE
+ *
+ * Now, we select the disk, giving it the SCSI ID at data
+ * and a command of PARITY if necessary, and we raise SEL.
+ */
+
+#if (DEBUG & PHASE_SELECTION)
+ printk("scsi%d : phase = SELECTION\n", hostno);
+#endif
+
+ clock = jiffies + ST0X_SELECTION_DELAY;
+
+/*
+ * If we wish to disconnect, we should request a MESSAGE OUT
+ * at this point. Technically, ATTN should be raised before
+ * SEL = true and BSY = false (from arbitration), but I think this
+ * should do.
+ */
+ if (reselect)
+ CONTROL = BASE_CMD | CMD_DRVR_ENABLE |
+ CMD_ATTN;
+
+/*
+ * We must assert both our ID and our target's ID on the bus.
+ */
+ DATA = (unsigned char) ((1 << target) | 0x80);
+
+/*
+ * If we are allowing ourselves to reconnect, then I will keep
+ * ATTN raised so we get MSG OUT.
+ */
+ CONTROL = BASE_CMD | CMD_DRVR_ENABLE | CMD_SEL |
+ (reselect ? CMD_ATTN : 0);
+
+/*
+ * When the SCSI device decides that we're gawking at it, it will
+ * respond by asserting BUSY on the bus.
+ */
+ while (!((status_read = STATUS) & STAT_BSY) &&
+ (jiffies < clock) && !st0x_aborted)
#if (DEBUG & PHASE_SELECTION)
{
@@ -271,110 +549,128 @@ movl 4(%%ebp), %%eax
}
printk("Done. \n\r");
- printk("Status = %02x, seagate_st0x_timeout = %d, aborted = %02x \n", status_read, temp,
- st0x_aborted);
+ printk("scsi%d : status = %02x, seagate_st0x_timeout = %d, aborted = %02x \n",
+ hostno, status_read, temp, st0x_aborted);
#else
;
#endif
- if ((jiffies > clock) || (!st0x_aborted & !(status_read & STAT_BSY)))
- {
- #if (DEBUG & PHASE_SELECT)
- printk ("NO CONNECT with target %d, status = %x \n", target, STATUS);
- #endif
- return retcode(DID_NO_CONNECT);
- }
-
- /*
- If we have been aborted, and we have a command in progress, IE the target still has
- BSY asserted, then we will reset the bus, and notify the midlevel driver to
- expect sense.
- */
-
- if (st0x_aborted)
- {
- CONTROL = BASE_CMD;
- if (STATUS & STAT_BSY)
+ if ((jiffies > clock) || (!st0x_aborted &&
+ !(status_read & STAT_BSY)))
{
- seagate_st0x_reset();
- return retcode(DID_RESET);
+#if (DEBUG & PHASE_SELECT)
+ printk ("scsi%d : NO CONNECT with target %d, status = %x \n",
+ hostno, target, STATUS);
+#endif
+ return retcode(DID_NO_CONNECT);
}
-
- return retcode(st0x_aborted);
- }
-
- /*
- COMMAND PHASE
- The device has responded with a BSY, so we may now enter
- the information transfer phase, where we will send / recieve
- data and command as directed by the target.
+/*
+ * If we have been aborted, and we have a command in progress, IE the
+ * target still has BSY asserted, then we will reset the bus, and
+ * notify the midlevel driver to expect sense.
+ */
- The nasty looking read / write inline assembler loops we use for
- DATAIN and DATAOUT phases are approximately 4-5 times as fast as
- the 'C' versions - since we're moving 1024 bytes of data, this
- really adds up.
- */
+ if (st0x_aborted)
+ {
+ CONTROL = BASE_CMD;
+ if (STATUS & STAT_BSY)
+ {
+ seagate_st0x_reset();
+ return retcode(DID_RESET);
+ }
+ return retcode(st0x_aborted);
+ }
+ }
- #if (DEBUG & PHASE_ETC)
- printk("PHASE = information transfer\n");
- #endif
+ CONTROL = BASE_CMD | CMD_DRVR_ENABLE |
+ ((reselect == CAN_RECONNECT) ? CMD_ATTN : 0) ;
+
+/*
+ * INFORMATION TRANSFER PHASE
+ *
+ * The nasty looking read / write inline assembler loops we use for
+ * DATAIN and DATAOUT phases are approximately 4-5 times as fast as
+ * the 'C' versions - since we're moving 1024 bytes of data, this
+ * really adds up.
+ */
- incommand = 1;
+#if (DEBUG & PHASE_ETC)
+ printk("scsi%d : phase = INFORMATION TRANSFER\n", hostno);
+#endif
- /*
- Enable command
- */
+ incommand = 1;
- CONTROL = BASE_CMD | CMD_DRVR_ENABLE;
- /*
- Now, we poll the device for status information,
- and handle any requests it makes. Note that since we are unsure of
- how much data will be flowing across the system, etc and cannot
- make reasonable timeouts, that we will instead have the midlevel
- driver handle any timeouts that occur in this phase.
- */
+/*
+ * Now, we poll the device for status information,
+ * and handle any requests it makes. Note that since we are unsure of
+ * how much data will be flowing across the system, etc and cannot
+ * make reasonable timeouts, that we will instead have the midlevel
+ * driver handle any timeouts that occur in this phase.
+ */
while (((status_read = STATUS) & STAT_BSY) && !st0x_aborted && !done)
+ {
+#ifdef PARITY
+ if (status_read & STAT_PARITY)
{
- #ifdef PARITY
- if (status_read & STAT_PARITY)
- {
- done = 1;
- st0x_aborted = DID_PARITY;
- }
- #endif
+ done = 1;
+ st0x_aborted = DID_PARITY;
+ }
+#endif
- if (status_read & STAT_REQ)
+ if (status_read & STAT_REQ)
+ {
+#if (DEBUG & PHASE_ETC)
+ if ((newphase = (status_read & REQ_MASK)) != phase)
+ {
+ phase = newphase;
+ switch (phase)
{
- #if (DEBUG & PHASE_ETC)
- if ((newphase = (status_read & REQ_MASK)) != phase)
- {
- phase = newphase;
- switch (phase)
- {
- case REQ_DATAOUT : printk("SCSI PHASE = DATA OUT\n"); break;
- case REQ_DATAIN : printk("SCSI PHASE = DATA IN\n"); break;
- case REQ_CMDOUT : printk("SCSI PHASE = COMMAND OUT\n"); break;
- case REQ_STATIN : printk("SCSI PHASE = STATUS IN\n"); break;
- case REQ_MSGOUT : printk("SCSI PHASE = MESSAGE OUT\n"); break;
- case REQ_MSGIN : printk("SCSI PHASE = MESSAGE IN\n"); break;
- default : printk("UNKNOWN PHASE"); st0x_aborted = 1; done = 1;
- }
- }
- #endif
-
- switch (status_read & REQ_MASK)
- {
- case REQ_DATAOUT :
+ case REQ_DATAOUT:
+ printk("scsi%d : phase = DATA OUT\n",
+ hostno);
+ break;
+ case REQ_DATAIN :
+ printk("scsi%d : phase = DATA IN\n",
+ hostno);
+ break;
+ case REQ_CMDOUT :
+ printk("scsi%d : phase = COMMAND OUT\n",
+ hostno);
+ break;
+ case REQ_STATIN :
+ printk("scsi%d : phase = STATUS IN\n",
+ hostno);
+ break;
+ case REQ_MSGOUT :
+ printk("scsi%d : phase = MESSAGE OUT\n",
+ hostno);
+ break;
+ case REQ_MSGIN :
+ printk("scsi%d : phase = MESSAGE IN\n",
+ hostno);
+ break;
+ default :
+ printk("scsi%d : phase = UNKNOWN\n",
+ hostno);
+ st0x_aborted = 1;
+ done = 1;
+ }
+ }
+#endif
- /*
- We loop as long as we are in a data out phase, there is data to send, and BSY is still
- active
- */
- __asm__ ("
+ switch (status_read & REQ_MASK)
+ {
+ case REQ_DATAOUT :
+
+/*
+ * We loop as long as we are in a data out phase, there is data to send,
+ * and BSY is still active.
+ */
+ __asm__ ("
/*
Local variables :
@@ -428,15 +724,15 @@ movl 4(%%ebp), %%eax
/* clobbered */
"ebx", "ecx", "edi", "esi");
- break;
+ break;
- case REQ_DATAIN :
- /*
- We loop as long as we are in a data out phase, there is room to read, and BSY is still
- active
- */
+ case REQ_DATAIN :
+/*
+ * We loop as long as we are in a data in phase, there is room to read,
+ * and BSY is still active
+ */
- __asm__ ("
+ __asm__ ("
/*
Local variables :
ecx = len
@@ -491,71 +787,153 @@ movl 4(%%ebp), %%eax
"0" (data), "1" (len) :
/* clobbered */
"ebx", "ecx", "edi", "esi");
- break;
-
- case REQ_CMDOUT :
- while (((status_read = STATUS) & STAT_BSY) && ((status_read & REQ_MASK) ==
- REQ_CMDOUT))
- DATA = *(unsigned char *) cmnd ++;
- break;
+ break;
+
+ case REQ_CMDOUT :
+ while (((status_read = STATUS) & STAT_BSY) &&
+ ((status_read & REQ_MASK) == REQ_CMDOUT))
+ if (status_read & STAT_REQ)
+ DATA = *(unsigned char *) cmnd ++;
+ break;
- case REQ_STATIN :
- status = DATA;
- break;
+ case REQ_STATIN :
+ status = DATA;
+ break;
- case REQ_MSGOUT :
- DATA = MESSAGE_REJECT;
- break;
+ case REQ_MSGOUT :
+/*
+ * We can only have sent a MSG OUT if we requested to do this
+ * by raising ATTN. So, we must drop ATTN.
+ */
+
+ CONTROL = BASE_CMD | CMD_DRVR_ENABLE;
+/*
+ * If we are reconecting, then we must send an IDENTIFY message in
+ * response to MSGOUT.
+ */
+ if (reselect)
+ {
+ DATA = IDENTIFY(1,0);
+#if (DEBUG & (PHASE_RESELECT | PHASE_MSGOUT))
+ printk("scsi%d : sent IDENTIFY message.\n", hostno);
+#endif
+ }
+ else
+ {
+ DATA = MESSAGE_REJECT;
+
+#if (DEBUG & PHASE_MSGOUT)
+ printk("scsi%d : sent MESSAGE REJECT message.\n", hostno);
+#endif
+ }
+ break;
- case REQ_MSGIN :
- if ((message = DATA) == COMMAND_COMPLETE)
- done=1;
-
- break;
+ case REQ_MSGIN :
+ switch (message = DATA)
+ {
+ case DISCONNECT :
+ should_reconnect = 1;
+ current_data = data; /* WDE add */
+ current_bufflen = len; /* WDE add */
+#if (DEBUG & (PHASE_RESELECT | PHASE_MSGIN))
+ printk("scsi%d : disconnected.\n", hostno);
+ done=1;
+ break;
+#endif
+ case COMMAND_COMPLETE :
+#if (DEBUG & PHASE_MSGIN)
+ printk("scsi%d : command complete.\n", hostno);
+ done=1;
+ break;
+#endif
+ case ABORT :
+#if (DEBUG & PHASE_MSGIN)
+ printk("scsi%d : abort message.\n", hostno);
+#endif
+ done=1;
+ break;
+ case SAVE_POINTERS :
+ current_data = data; /* WDE mod */
+ current_bufflen = len; /* WDE add */
+#if (DEBUG & PHASE_MSGIN)
+ printk("scsi%d : pointers saved.\n", hostno);
+#endif
+ break;
+ case RESTORE_POINTERS:
+ data=current_data; /* WDE mod */
+ cmnd=current_cmnd;
+#if (DEBUG & PHASE_MSGIN)
+ printk("scsi%d : pointers restored.\n", hostno);
+#endif
+ break;
+ default:
- default : printk("UNKNOWN PHASE"); st0x_aborted = DID_ERROR;
+/*
+ * IDENTIFY distinguishes itself from the other messages by setting the
+ * high byte.
+ */
+
+ if (message & 0x80)
+ {
+#if (DEBUG & PHASE_MSGIN)
+ printk("scsi%d : IDENTIFY message received from id %d, lun %d.\n",
+ hostno, target, message & 7);
+#endif
}
- }
+ else
+ {
+
+#if (DEBUG & PHASE_MSGIN)
+ printk("scsi%d : unknown message %d from target %d.\n",
+ hostno, message, target);
+#endif
+ }
+ }
+ break;
- }
+ default :
+ printk("scsi%d : unknown phase.\n", hostno);
+ st0x_aborted = DID_ERROR;
+ }
+ } /* while ends */
+ } /* if ends */
#if (DEBUG & (PHASE_DATAIN | PHASE_DATAOUT | PHASE_EXIT))
printk("Transfered %d bytes, allowed %d additional bytes\n", (bufflen - len), len);
#endif
#if (DEBUG & PHASE_EXIT)
- printk("Buffer : \n");
- for (i = 0; i < 20; ++i)
- printk ("%02x ", ((unsigned char *) buff)[i]);
- printk("\n");
- printk("Status = %02x, message = %02x\n", status, message);
+ printk("Buffer : \n");
+ for (i = 0; i < 20; ++i)
+ printk ("%02x ", ((unsigned char *) data)[i]); /* WDE mod */
+ printk("\n");
+ printk("Status = %02x, message = %02x\n", status, message);
#endif
- if (st0x_aborted)
+ if (st0x_aborted)
+ {
+ if (STATUS & STAT_BSY)
{
- if (STATUS & STAT_BSY)
- {
- seagate_st0x_reset();
- st0x_aborted = DID_RESET;
- }
- abort_confirm = 1;
- }
-
- CONTROL = BASE_CMD;
-
-#if (DEBUG & PHASE_EXIT)
- __asm__("
-mov 4(%%ebp), %%eax
-":"=a" (retaddr):);
+ seagate_st0x_reset();
+ st0x_aborted = DID_RESET;
+ }
+ abort_confirm = 1;
+ }
- printk("Exiting seagate_st0x_command() - return address is %08x \n", retaddr);
- if (retaddr != realretaddr)
- panic ("Corrupted stack : return address on entry != return address on exit.\n");
-
+ if (should_reconnect)
+ {
+#if (DEBUG & PHASE_RESELECT)
+ printk("scsi%d : exiting seagate_st0x_queue_command() with reconnect enabled.\n",
+ hostno);
#endif
+ do_seagate = seagate_reconnect_intr;
+ CONTROL = BASE_CMD | CMD_INTR ;
+ }
+ else
+ CONTROL = BASE_CMD;
- return retcode (st0x_aborted);
+ return retcode (st0x_aborted);
}
int seagate_st0x_abort (int code)
@@ -604,4 +982,6 @@ int seagate_st0x_reset (void)
#endif
return 0;
}
+
#endif
+
diff --git a/kernel/blk_drv/scsi/seagate.h b/kernel/blk_drv/scsi/seagate.h
index d625446..0eb3b30 100644
--- a/kernel/blk_drv/scsi/seagate.h
+++ b/kernel/blk_drv/scsi/seagate.h
@@ -13,7 +13,11 @@
*/
#ifndef ASM
int seagate_st0x_detect(int);
-int seagate_st0x_command(unsigned char target, const void *cmnd, void *buff, int bufflen);
+int seagate_st0x_command(unsigned char target, const void *cmnd, void *buff,
+ int bufflen);
+int seagate_st0x_queue_command(unsigned char target, const void *cmnd,
+ void *buff, int bufflen, void (*done)(int, int));
+
int seagate_st0x_abort(int);
char *seagate_st0x_info(void);
int seagate_st0x_reset(void);
@@ -24,8 +28,8 @@ int seagate_st0x_reset(void);
#define SEAGATE_ST0X {"Seagate ST-01/ST-02", seagate_st0x_detect, \
seagate_st0x_info, seagate_st0x_command, \
- NULL, seagate_st0x_abort, seagate_st0x_reset, \
- 0, 7, 0}
+ seagate_st0x_queue_command, seagate_st0x_abort, \
+ seagate_st0x_reset, 1, 7, 0}
#endif
@@ -111,13 +115,17 @@ extern volatile int seagate_st0x_timeout;
#define PHASE_ETC (PHASE_DATAIN | PHASE_DATA_OUT | PHASE_CMDOUT | PHASE_MSGIN | PHASE_MSGOUT | PHASE_STATUSIN)
#define PRINT_COMMAND 0x200
#define PHASE_EXIT 0x400
+#define PHASE_RESELECT 0x800
/*
- Control options - these are timeouts specified in .01 seconds.
-*/
+ * Control options - these are timeouts specified in .01 seconds.
+ */
#define ST0X_BUS_FREE_DELAY 25
-#define ST0X_SELECTION_DELAY 25
+#define ST0X_SELECTION_DELAY 3
+
+#define eoi() __asm__("push %%eax\nmovb $0x20, %%al\noutb %%al, $0x20\npop %%eax"::)
+
#endif
diff --git a/kernel/blk_drv/scsi/seagate2.s b/kernel/blk_drv/scsi/seagate2.s
new file mode 100644
index 0000000..9b1b6a2
--- /dev/null
+++ b/kernel/blk_drv/scsi/seagate2.s
@@ -0,0 +1,36 @@
+/*
+ * seagate2.S
+ * low level scsi driver for ST01/ST02 by
+ * Drew Eckhardt
+ *
+ * <drew@colorado.edu>
+ */
+.text
+.globl _seagate_intr
+_seagate_intr:
+ cld # GCC thing
+
+ pushal
+ push %ds
+ push %es
+
+ mov $0x10, %ax # switch to kernel space
+ mov %ax, %ds
+ mov %ax, %es
+
+
+
+ xor %eax, %eax
+ xchg _do_seagate, %eax
+ test %eax, %eax
+ jnz 1f
+ mov $_seagate_unexpected_intr, %eax
+1: call *%eax
+
+ mov $0x20, %al # non-specific EOI
+ out %al, $0x20
+
+ pop %es
+ pop %ds
+ popal
+ iret
diff --git a/kernel/blk_drv/scsi/st.c b/kernel/blk_drv/scsi/st.c
index bef3ae8..1f81217 100644
--- a/kernel/blk_drv/scsi/st.c
+++ b/kernel/blk_drv/scsi/st.c
@@ -15,10 +15,6 @@
#include <linux/sched.h>
#include "../blk.h"
-/*
-static const char RCSid[] = "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/st.c,v 1.1 1992/04/24 18:01:50 root Exp root $";
-*/
-
Scsi_Tape scsi_tapes[MAX_ST];
static int st_sizes[MAX_ST];
int NR_ST=0;
diff --git a/kernel/blk_drv/scsi/st.h b/kernel/blk_drv/scsi/st.h
index 1a7c044..9ae0795 100644
--- a/kernel/blk_drv/scsi/st.h
+++ b/kernel/blk_drv/scsi/st.h
@@ -2,7 +2,7 @@
#ifndef _ST_H
#define _ST_H
/*
- $Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/st.h,v 1.1 1992/04/24 18:01:50 root Exp root $
+ $Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/st.h,v 1.1 1992/07/24 06:27:38 root Exp root $
*/
#ifndef _SCSI_H
diff --git a/kernel/blk_drv/scsi/st_ioctl.c b/kernel/blk_drv/scsi/st_ioctl.c
index 4bc7a39..4780989 100644
--- a/kernel/blk_drv/scsi/st_ioctl.c
+++ b/kernel/blk_drv/scsi/st_ioctl.c
@@ -5,15 +5,15 @@
#include <linux/fs.h>
#include "st.h"
-extern int scsi_ioctl(int dev, int cmd, void *arg);
+extern int scsi_ioctl(Scsi_Device *dev, int cmd, void *arg);
-int st_ioctl(struct inode * inode,struct file * file, unsigned long cmd, unsigned long arg)
+int st_ioctl(struct inode * inode, struct file * file, unsigned long cmd, unsigned long arg)
{
int dev = inode->i_rdev;
switch (cmd) {
default:
- return scsi_ioctl(scsi_tapes[MINOR(dev)].device,cmd,(void *) arg);
+ return scsi_ioctl(scsi_tapes[MINOR(dev)].device, cmd, (void *) arg);
}
}
#endif
diff --git a/kernel/blk_drv/scsi/ultrastor.c b/kernel/blk_drv/scsi/ultrastor.c
index ba30f21..279448f 100644
--- a/kernel/blk_drv/scsi/ultrastor.c
+++ b/kernel/blk_drv/scsi/ultrastor.c
@@ -1,5 +1,5 @@
/*
- * ultrastor.c (C) 1991 David B. Gentzel
+ * ultrastor.c Copyright (C) 1991, 1992 David B. Gentzel
* Low-level SCSI driver for UltraStor 14F
* by David B. Gentzel, Whitfield Software Services, Carnegie, PA
* (gentzel@nova.enet.dec.com)
@@ -28,22 +28,21 @@
* commands to complete. I hope to go back and beat it into shape, but
* PLEASE, anyone else who would like to, please make improvements!
*
- * By defining USE_QUEUECOMMAND as TRUE in ultrastor.h, you enable the
- * queueing feature of the mid-level SCSI driver. This should improve
- * performance somewhat. However, it does not seem to work. I believe
- * this is due to a bug in the mid-level driver, but I haven't looked
- * too closely.
+ * By defining NO_QUEUEING in ultrastor.h, you disable the queueing feature
+ * of the mid-level SCSI driver. Once I'm satisfied that the queueing
+ * version is as stable as the non-queueing version, I'll eliminate this
+ * option.
*/
#include <linux/config.h>
#ifdef CONFIG_SCSI_ULTRASTOR
-#include <stddef.h>
-
+#include <linux/stddef.h>
#include <linux/string.h>
#include <linux/sched.h>
#include <linux/kernel.h>
+
#include <asm/io.h>
#include <asm/system.h>
@@ -156,7 +155,7 @@ static const unsigned short ultrastor_ports[] = {
};
#endif
-void ultrastor_interrupt(int cpl);
+void ultrastor_interrupt(void);
static void (*ultrastor_done)(int, int) = 0;
@@ -195,7 +194,7 @@ int ultrastor_14f_detect(int hostnum)
# ifdef PORT_OVERRIDE
printk("US14F: detect: wrong product ID 0 - %02X\n", in_byte);
# else
- printk("US14F: detect: no adapter at port %03X", PORT_ADDRESS);
+ printk("US14F: detect: no adapter at port %03X\n", PORT_ADDRESS);
# endif
#endif
#ifdef PORT_OVERRIDE
@@ -211,7 +210,7 @@ int ultrastor_14f_detect(int hostnum)
# ifdef PORT_OVERRIDE
printk("US14F: detect: wrong product ID 1 - %02X\n", in_byte);
# else
- printk("US14F: detect: no adapter at port %03X", PORT_ADDRESS);
+ printk("US14F: detect: no adapter at port %03X\n", PORT_ADDRESS);
# endif
#endif
#ifdef PORT_OVERRIDE
@@ -292,18 +291,12 @@ int ultrastor_14f_detect(int hostnum)
#endif
host_number = hostnum;
scsi_hosts[hostnum].this_id = config.ha_scsi_id;
-#if USE_QUEUECOMMAND
- {
- struct sigaction sa;
- sa.sa_handler = ultrastor_interrupt;
- sa.sa_flags = SA_INTERRUPT;
- sa.sa_mask = 0;
- sa.sa_restorer = NULL;
- if (irqaction(config.interrupt,&sa)) {
- printk("unable to get IRQ%d for ultrastor controller\n",config.interrupt);
- return FALSE;
- }
- }
+#ifndef NO_QUEUEING
+ set_intr_gate(0x20 + config.interrupt, ultrastor_interrupt);
+ /* gate to PIC 2 */
+ outb_p(inb_p(0x21) & ~BIT(2), 0x21);
+ /* enable the interrupt */
+ outb(inb_p(0xA1) & ~BIT(config.interrupt - 8), 0xA1);
#endif
return TRUE;
}
@@ -341,9 +334,13 @@ int ultrastor_14f_queuecommand(unsigned char target, const void *cmnd,
do
in_byte = inb_p(LCL_DOORBELL_INTR(PORT_ADDRESS));
while (!aborted && (in_byte & 1));
- if (aborted)
+ if (aborted) {
+#if (ULTRASTOR_DEBUG & (UD_COMMAND | UD_ABORT))
+ printk("US14F: queuecommand: aborted\n");
+#endif
/* ??? is this right? */
return (aborted << 16);
+ }
/* Store pointer in OGM address bytes */
outb_p(BYTE(&mscp, 0), OGM_DATA_PTR(PORT_ADDRESS + 0));
@@ -363,7 +360,7 @@ int ultrastor_14f_queuecommand(unsigned char target, const void *cmnd,
return 0;
}
-#if !USE_QUEUECOMMAND
+#ifdef NO_QUEUEING
int ultrastor_14f_command(unsigned char target, const void *cmnd,
void *buff, int bufflen)
{
@@ -379,9 +376,13 @@ int ultrastor_14f_command(unsigned char target, const void *cmnd,
do
in_byte = inb_p(SYS_DOORBELL_INTR(PORT_ADDRESS));
while (!aborted && !(in_byte & 1));
- if (aborted)
+ if (aborted) {
+#if (ULTRASTOR_DEBUG & (UD_COMMAND | UD_ABORT))
+ printk("US14F: command: aborted\n");
+#endif
/* ??? is this right? */
return (aborted << 16);
+ }
/* Clean ICM slot (set ICMINT bit to 0) */
outb_p(0x1, SYS_DOORBELL_INTR(PORT_ADDRESS));
@@ -398,7 +399,16 @@ int ultrastor_14f_command(unsigned char target, const void *cmnd,
int ultrastor_14f_abort(int code)
{
+#if (ULTRASTOR_DEBUG & UD_ABORT)
+ printk("US14F: abort: called\n");
+#endif
+
aborted = (code ? code : DID_ABORT);
+
+#if (ULTRASTOR_DEBUG & UD_ABORT)
+ printk("US14F: abort: returning\n");
+#endif
+
return 0;
}
@@ -426,20 +436,68 @@ int ultrastor_14f_reset(void)
return 0;
}
-#if USE_QUEUECOMMAND
-void ultrastor_interrupt(int cpl)
+#ifndef NO_QUEUEING
+void ultrastor_interrupt_service(void)
{
- if (ultrastor_done == 0) {
- printk("US14F: unexpected ultrastor interrupt\n\r");
- /* ??? Anything else we should do here? Reset? */
- return;
- }
- printk("US14F: got an ultrastor interrupt: %u\n\r",
+#if (ULTRASTOR_DEBUG & UD_INTERRUPT)
+ printk("US14F: interrupt_service: called: status = %08X\n",
(mscp.adapter_status << 16) | mscp.target_status);
- ultrastor_done(host_number,
- (mscp.adapter_status << 16) | mscp.target_status);
- ultrastor_done = 0;
+#endif
+
+ if (ultrastor_done == 0)
+ panic("US14F: interrupt_service: unexpected interrupt!\n");
+ else {
+ void (*done)(int, int);
+
+ /* Save ultrastor_done locally and zero before calling. This is needed
+ as once we call done, we may get another command queued before this
+ interrupt service routine can return. */
+ done = ultrastor_done;
+ ultrastor_done = 0;
+
+ /* Clean ICM slot (set ICMINT bit to 0) */
+ outb_p(0x1, SYS_DOORBELL_INTR(PORT_ADDRESS));
+
+ /* Let the higher levels know that we're done */
+ /* ??? status is wrong here... */
+ done(host_number, (mscp.adapter_status << 16) | mscp.target_status);
+ }
+
+#if (ULTRASTOR_DEBUG & UD_INTERRUPT)
+ printk("US14F: interrupt_service: returning\n");
+#endif
}
+
+__asm__("
+_ultrastor_interrupt:
+ cld
+ pushl %eax
+ pushl %ecx
+ pushl %edx
+ push %ds
+ push %es
+ push %fs
+ movl $0x10,%eax
+ mov %ax,%ds
+ mov %ax,%es
+ movl $0x17,%eax
+ mov %ax,%fs
+ movb $0x20,%al
+ outb %al,$0xA0 # EOI to interrupt controller #1
+ outb %al,$0x80 # give port chance to breathe
+ outb %al,$0x80
+ outb %al,$0x80
+ outb %al,$0x80
+ outb %al,$0x20
+ call _ultrastor_interrupt_service
+ pop %fs
+ pop %es
+ pop %ds
+ popl %edx
+ popl %ecx
+ popl %eax
+ iret
+");
#endif
#endif
diff --git a/kernel/blk_drv/scsi/ultrastor.h b/kernel/blk_drv/scsi/ultrastor.h
index dfe34ee..b881419 100644
--- a/kernel/blk_drv/scsi/ultrastor.h
+++ b/kernel/blk_drv/scsi/ultrastor.h
@@ -17,36 +17,40 @@
# define FALSE 0
#endif
-/* ??? This should go eventually, once the queueing bug is fixed */
-#define USE_QUEUECOMMAND FALSE
+/* ??? This should go eventually, once I'm convinced the queueing stuff is
+ stable enough... */
+/* #define NO_QUEUEING */
int ultrastor_14f_detect(int);
const char *ultrastor_14f_info(void);
int ultrastor_14f_queuecommand(unsigned char target, const void *cmnd,
void *buff, int bufflen,
void (*done)(int, int));
-#if !USE_QUEUECOMMAND
+#ifdef NO_QUEUEING
int ultrastor_14f_command(unsigned char target, const void *cmnd,
void *buff, int bufflen);
#endif
int ultrastor_14f_abort(int);
int ultrastor_14f_reset(void);
-#if !USE_QUEUECOMMAND
-#define ULTRASTOR_14F \
- { "UltraStor 14F", ultrastor_14f_detect, ultrastor_14f_info, \
- ultrastor_14f_command, 0, ultrastor_14f_abort, ultrastor_14f_reset, \
- FALSE, 0, 0 }
-#else
+#ifndef NO_QUEUEING
#define ULTRASTOR_14F \
{ "UltraStor 14F", ultrastor_14f_detect, ultrastor_14f_info, 0, \
ultrastor_14f_queuecommand, ultrastor_14f_abort, ultrastor_14f_reset, \
- TRUE, 0, 0 }
+ 1, 0, 0 }
+ /* ??? What should can_queue be set to? Currently 1... */
+#else
+#define ULTRASTOR_14F \
+ { "UltraStor 14F", ultrastor_14f_detect, ultrastor_14f_info, \
+ ultrastor_14f_command, 0, ultrastor_14f_abort, ultrastor_14f_reset, \
+ 0, 0, 0 }
#endif
-#define UD_DETECT 0x1
-#define UD_COMMAND 0x2
-#define UD_RESET 0x4
+#define UD_ABORT 0x0001
+#define UD_COMMAND 0x0002
+#define UD_DETECT 0x0004
+#define UD_INTERRUPT 0x0008
+#define UD_RESET 0x0010
#ifdef ULTRASTOR_PRIVATE
diff --git a/kernel/chr_drv/Makefile b/kernel/chr_drv/Makefile
index 83fffae..db51601 100644
--- a/kernel/chr_drv/Makefile
+++ b/kernel/chr_drv/Makefile
@@ -37,77 +37,98 @@ dep:
### Dependencies:
console.o : console.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
- /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
- /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
- /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
- /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
- /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/timer.h /usr/src/linux/include/linux/tty.h \
- /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h /usr/src/linux/include/linux/config.h \
- /usr/src/linux/include/linux/config_rel.h /usr/src/linux/include/linux/config_ver.h \
- /usr/src/linux/include/linux/config.dist.h /usr/src/linux/include/asm/io.h /usr/src/linux/include/asm/segment.h \
- /usr/src/linux/include/linux/string.h /usr/src/linux/include/errno.h /usr/src/linux/include/sys/kd.h \
- vt_kern.h
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/mm.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/timer.h /usr/src/linux/include/linux/tty.h /usr/src/linux/include/linux/termios.h \
+ /usr/src/linux/include/asm/system.h /usr/src/linux/include/linux/config.h /usr/src/linux/include/linux/config_rel.h \
+ /usr/src/linux/include/linux/config_ver.h /usr/src/linux/include/linux/config.dist.h \
+ /usr/src/linux/include/linux/string.h /usr/src/linux/include/linux/errno.h /usr/src/linux/include/asm/io.h \
+ /usr/src/linux/include/asm/segment.h /usr/src/linux/include/sys/kd.h vt_kern.h
keyboard.o : keyboard.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
- /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
- /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
- /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
- /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
- /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/ctype.h /usr/src/linux/include/linux/tty.h \
- /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h /usr/src/linux/include/asm/io.h
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/mm.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/ctype.h /usr/src/linux/include/linux/tty.h /usr/src/linux/include/linux/termios.h \
+ /usr/src/linux/include/asm/system.h /usr/src/linux/include/linux/ptrace.h /usr/src/linux/include/asm/io.h
lp.o : lp.c /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
- /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
- /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
- /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
- /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
- /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/lp.h /usr/src/linux/include/errno.h \
- /usr/src/linux/include/asm/io.h /usr/src/linux/include/asm/segment.h
-mem.o : mem.c /usr/src/linux/include/errno.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
- /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
- /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/tty.h \
- /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h /usr/src/linux/include/asm/segment.h \
- /usr/src/linux/include/asm/io.h
-pty.o : pty.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
- /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/tty.h \
- /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h /usr/src/linux/include/linux/fcntl.h \
- /usr/src/linux/include/asm/io.h
-serial.o : serial.c /usr/src/linux/include/signal.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/errno.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \
- /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
- /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/timer.h \
- /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h \
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/mm.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/lp.h /usr/src/linux/include/linux/errno.h /usr/src/linux/include/asm/io.h \
+ /usr/src/linux/include/asm/segment.h
+mem.o : mem.c /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/errno.h \
+ /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
+ /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/tty.h /usr/src/linux/include/linux/termios.h /usr/src/linux/include/asm/system.h \
+ /usr/src/linux/include/linux/mouse.h /usr/src/linux/include/asm/segment.h /usr/src/linux/include/asm/io.h
+mouse.o : mouse.c /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/sched.h \
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/signal.h /usr/src/linux/include/linux/time.h \
+ /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/mouse.h /usr/src/linux/include/linux/tty.h /usr/src/linux/include/linux/termios.h \
+ /usr/src/linux/include/asm/system.h /usr/src/linux/include/linux/errno.h /usr/src/linux/include/asm/io.h \
+ /usr/src/linux/include/asm/segment.h /usr/src/linux/include/asm/irq.h
+pty.o : pty.c /usr/src/linux/include/linux/errno.h /usr/src/linux/include/linux/sched.h \
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/tty.h /usr/src/linux/include/linux/termios.h /usr/src/linux/include/asm/system.h \
+ /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/asm/io.h
+serial.o : serial.c /usr/src/linux/include/linux/errno.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
+ /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h \
+ /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/time.h \
+ /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/timer.h /usr/src/linux/include/linux/tty.h /usr/src/linux/include/linux/termios.h \
+ /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/io.h /usr/src/linux/include/asm/segment.h
+tty_io.o : tty_io.c /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/errno.h \
+ /usr/src/linux/include/linux/signal.h /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/linux/sched.h \
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/mm.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h \
+ /usr/src/linux/include/linux/resource.h /usr/src/linux/include/linux/tty.h /usr/src/linux/include/linux/termios.h \
+ /usr/src/linux/include/asm/system.h /usr/src/linux/include/linux/ctype.h /usr/src/linux/include/asm/io.h \
+ /usr/src/linux/include/asm/segment.h /usr/src/linux/include/sys/kd.h vt_kern.h
+tty_ioctl.o : tty_ioctl.c /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/termios.h \
+ /usr/src/linux/include/linux/errno.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/linux/fcntl.h \
/usr/src/linux/include/asm/io.h /usr/src/linux/include/asm/segment.h
-tty_io.o : tty_io.c /usr/src/linux/include/errno.h /usr/src/linux/include/signal.h \
- /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/fcntl.h \
+vt.o : vt.c /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/errno.h \
/usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
- /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
- /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/sys/param.h \
- /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \
- /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h \
- /usr/src/linux/include/linux/ctype.h /usr/src/linux/include/asm/io.h /usr/src/linux/include/asm/segment.h \
- /usr/src/linux/include/sys/kd.h vt_kern.h
-tty_ioctl.o : tty_ioctl.c /usr/src/linux/include/errno.h /usr/src/linux/include/termios.h \
- /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \
- /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
- /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \
- /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \
- /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/io.h \
- /usr/src/linux/include/asm/segment.h
-vt.o : vt.c /usr/src/linux/include/errno.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/kd.h /usr/src/linux/include/sys/vt.h \
- /usr/src/linux/include/asm/io.h /usr/src/linux/include/asm/segment.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \
- /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
- /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h \
- /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \
- /usr/src/linux/include/linux/tty.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/termios.h \
- /usr/src/linux/include/linux/timer.h vt_kern.h
+ /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/tty.h /usr/src/linux/include/linux/termios.h /usr/src/linux/include/asm/system.h \
+ /usr/src/linux/include/linux/timer.h /usr/src/linux/include/asm/io.h /usr/src/linux/include/asm/segment.h \
+ vt_kern.h /usr/src/linux/include/sys/kd.h /usr/src/linux/include/sys/vt.h
diff --git a/kernel/chr_drv/console.c b/kernel/chr_drv/console.c
index c440e7a..cff8124 100644
--- a/kernel/chr_drv/console.c
+++ b/kernel/chr_drv/console.c
@@ -1,7 +1,7 @@
/*
* linux/kernel/console.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
@@ -37,40 +37,20 @@
#include <linux/tty.h>
#include <linux/config.h>
#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/segment.h>
-#include <linux/string.h>
-#include <errno.h>
-
#include <sys/kd.h>
#include "vt_kern.h"
-/*
- * These are set up by the setup-routine at boot-time:
- */
-
-#define ORIG_X (*(unsigned char *)0x90000)
-#define ORIG_Y (*(unsigned char *)0x90001)
-#define ORIG_VIDEO_PAGE (*(unsigned short *)0x90004)
-#define ORIG_VIDEO_MODE ((*(unsigned short *)0x90006) & 0xff)
-#define ORIG_VIDEO_COLS (((*(unsigned short *)0x90006) & 0xff00) >> 8)
-#define ORIG_VIDEO_LINES ((*(unsigned short *)0x9000e) & 0xff)
-#define ORIG_VIDEO_EGA_AX (*(unsigned short *)0x90008)
-#define ORIG_VIDEO_EGA_BX (*(unsigned short *)0x9000a)
-#define ORIG_VIDEO_EGA_CX (*(unsigned short *)0x9000c)
-
-#define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */
-#define VIDEO_TYPE_CGA 0x11 /* CGA Display */
-#define VIDEO_TYPE_EGAM 0x20 /* EGA/VGA in Monochrome Mode */
-#define VIDEO_TYPE_EGAC 0x21 /* EGA/VGA in Color Mode */
-
#define NPAR 16
extern void vt_init(void);
-extern void keyboard_interrupt(int cpl);
+extern void keyboard_interrupt(int pt_regs);
extern void set_leds(void);
extern unsigned char kapplic;
extern unsigned char ckmode;
@@ -1489,11 +1469,11 @@ void console_print(const char * b)
currcons = 0;
while (c = *(b++)) {
if (c == 10 || c == 13 || need_wrap) {
- cr(currcons);
- if (c == 10 || need_wrap)
+ if (c != 13)
lf(currcons);
- need_wrap = 0;
- continue;
+ cr(currcons);
+ if (c == 10 || c == 13)
+ continue;
}
*(char *) pos = c;
*(char *) (pos+1) = attr;
diff --git a/kernel/chr_drv/keyboard.c b/kernel/chr_drv/keyboard.c
index bd437f1..8e4e521 100644
--- a/kernel/chr_drv/keyboard.c
+++ b/kernel/chr_drv/keyboard.c
@@ -11,6 +11,8 @@
#include <linux/ctype.h>
#include <linux/tty.h>
#include <linux/mm.h>
+#include <linux/ptrace.h>
+
#include <asm/io.h>
#include <asm/system.h>
@@ -58,12 +60,15 @@ static void cur(int);
static void kb_wait(void), kb_ack(void);
static unsigned int handle_diacr(unsigned int);
-void keyboard_interrupt(int cpl)
+static struct pt_regs * pt_regs;
+
+void keyboard_interrupt(int int_pt_regs)
{
static unsigned char rep = 0xff, repke0 = 0;
unsigned char scancode, x;
struct tty_struct * tty = TTY_TABLE(0);
+ pt_regs = (struct pt_regs *) int_pt_regs;
scancode=inb_p(0x60);
x=inb_p(0x61);
outb_p(x|0x80, 0x61);
@@ -229,11 +234,28 @@ static void uncaps(int sc)
kmode &= ~CAPSDOWN;
}
+static void show_ptregs(void)
+{
+ printk("\nEIP: %04x:%08x",0xffff & pt_regs->cs,pt_regs->eip);
+ if (pt_regs->cs & 3)
+ printk(" ESP: %04x:%08x",0xffff & pt_regs->cs,pt_regs->eip);
+ printk(" EFLAGS: %08x",pt_regs->eflags);
+ printk("\nEAX: %08x EBX: %08x ECX: %08x EDX: %08x",
+ pt_regs->orig_eax,pt_regs->ebx,pt_regs->ecx,pt_regs->edx);
+ printk("\nESI: %08x EDI: %08x EBP: %08x",
+ pt_regs->esi, pt_regs->edi, pt_regs->ebp);
+ printk(" DS: %04x ES: %04x FS: %04x GS: %04x\n",
+ 0xffff & pt_regs->ds,0xffff & pt_regs->es,
+ 0xffff & pt_regs->fs,0xffff & pt_regs->gs);
+}
+
static void scroll(int sc)
{
if (kmode & (LSHIFT | RSHIFT))
show_mem();
- else
+ else if (kmode & (ALT | ALTGR))
+ show_ptregs();
+ else if (kmode & (LCTRL | RCTRL))
show_state();
kleds ^= SCRLED;
set_leds();
@@ -776,6 +798,7 @@ static unsigned char alt_map[] = {
0 };
#elif defined KBD_SG
+
static unsigned char key_map[] = {
0, 27, '1', '2', '3', '4', '5', '6',
'7', '8', '9', '0', '\'', '^', 127, 9,
@@ -790,6 +813,7 @@ static unsigned char key_map[] = {
0, 0, 0, 0, 0, 0, '<', 0,
0, 0, 0, 0, 0, 0, 0, 0,
0 };
+
static unsigned char shift_map[] = {
0, 27, '+', '"', '*', 0, '%', '&',
'/', '(', ')', '=', '?', '`', 127, 9,
@@ -804,6 +828,7 @@ static unsigned char shift_map[] = {
0, 0, 0, 0, 0, 0, '>', 0,
0, 0, 0, 0, 0, 0, 0, 0,
0 };
+
static unsigned char alt_map[] = {
0, 0, 0, '@', '#', 0, 0, 0,
'|', 0, 0, 0, '\'', '~', 0, 0,
@@ -818,7 +843,9 @@ static unsigned char alt_map[] = {
0, 0, 0, 0, 0, 0, '\\', 0,
0, 0, 0, 0, 0, 0, 0, 0,
0 };
+
#elif defined KBD_SG_LATIN1
+
static unsigned char key_map[] = {
0, 27, '1', '2', '3', '4', '5', '6',
'7', '8', '9', '0', '\'', '^', 127, 9,
@@ -833,6 +860,7 @@ static unsigned char key_map[] = {
0, 0, 0, 0, 0, 0, '<', 0,
0, 0, 0, 0, 0, 0, 0, 0,
0 };
+
static unsigned char shift_map[] = {
0, 27, '+', '"', '*', 231, '%', '&',
'/', '(', ')', '=', '?', '`', 127, 9,
@@ -847,6 +875,7 @@ static unsigned char shift_map[] = {
0, 0, 0, 0, 0, 0, '>', 0,
0, 0, 0, 0, 0, 0, 0, 0,
0 };
+
static unsigned char alt_map[] = {
0, 0, 0, '@', '#', 0, 0, 172,
'|', 162, 0, 0, '\'', '~', 0, 0,
@@ -861,6 +890,54 @@ static unsigned char alt_map[] = {
0, 0, 0, 0, 0, 0, '\\', 0,
0, 0, 0, 0, 0, 0, 0, 0,
0 };
+
+#elif defined KBD_NO
+
+static unsigned char key_map[] = {
+ 0, 27, '1', '2', '3', '4', '5', '6',
+ '7', '8', '9', '0', '+', '\\', 127, 9,
+ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
+ 'o', 'p', '}', '~', 13, 0, 'a', 's',
+ 'd', 'f', 'g', 'h', 'j', 'k', 'l', '|',
+ '{', '|', 0, '\'', 'z', 'x', 'c', 'v',
+ 'b', 'n', 'm', ',', '.', '-', 0, '*',
+ 0, 32, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, '-', 0, 0, 0, '+', 0,
+ 0, 0, 0, 0, 0, 0, '<', 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0 };
+
+static unsigned char shift_map[] = {
+ 0, 27, '!', '\"', '#', '$', '%', '&',
+ '/', '(', ')', '=', '?', '`', 127, 9,
+ 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I',
+ 'O', 'P', ']', '^', 13, 0, 'A', 'S',
+ 'D', 'F', 'G', 'H', 'J', 'K', 'L', '\\',
+ '[', 0, 0, '*', 'Z', 'X', 'C', 'V',
+ 'B', 'N', 'M', ';', ':', '_', 0, '*',
+ 0, 32, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, '-', 0, 0, 0, '+', 0,
+ 0, 0, 0, 0, 0, 0, '>', 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0 };
+
+static unsigned char alt_map[] = {
+ 0, 0, 0, '@', 0, '$', 0, 0,
+ '{', '[', ']', '}', 0, '\'', 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, '~', 13, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0 };
+
#else
#error "KBD-type not defined"
#endif
diff --git a/kernel/chr_drv/lp.c b/kernel/chr_drv/lp.c
index 4643c27..4270b2d 100644
--- a/kernel/chr_drv/lp.c
+++ b/kernel/chr_drv/lp.c
@@ -9,7 +9,6 @@
*/
#include <linux/sched.h>
-#define __LP_C__
#include <linux/lp.h>
static int lp_reset(int minor)
diff --git a/kernel/chr_drv/mem.c b/kernel/chr_drv/mem.c
index 64d8365..1496239 100644
--- a/kernel/chr_drv/mem.c
+++ b/kernel/chr_drv/mem.c
@@ -1,15 +1,15 @@
/*
* linux/kernel/chr_drv/mem.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
-#include <errno.h>
-#include <sys/types.h>
-
+#include <linux/types.h>
+#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/tty.h>
+#include <linux/mouse.h>
#include <asm/segment.h>
#include <asm/io.h>
@@ -36,17 +36,17 @@ static int read_mem(struct inode * inode, struct file * file,char * buf, int cou
addr = file->f_pos;
tmp = buf;
while (count > 0) {
+ if (current->signal & ~current->blocked)
+ break;
pde = (unsigned long) pg_dir + (addr >> 20 & 0xffc);
- if (!((pte = *((unsigned long *) pde)) & 1))
+ pte = *(unsigned long *) pde;
+ if (!(pte & PAGE_PRESENT))
break;
pte &= 0xfffff000;
pte += (addr >> 10) & 0xffc;
- if (((page = *((unsigned long *) pte)) & 1) == 0)
+ page = *(unsigned long *) pte;
+ if (!(page & 1))
break;
-/*
- if ((page & 2) == 0)
- un_wp_page((unsigned long *) pte);
-*/
page &= 0xfffff000;
page += addr & 0xfff;
i = 4096-(addr & 0xfff);
@@ -73,15 +73,21 @@ static int write_mem(struct inode * inode, struct file * file,char * buf, int co
addr = file->f_pos;
tmp = buf;
while (count > 0) {
+ if (current->signal & ~current->blocked)
+ break;
pde = (unsigned long) pg_dir + (addr >> 20 & 0xffc);
- if (!((pte = *((unsigned long *) pde)) & 1))
+ pte = *(unsigned long *) pde;
+ if (!(pte & PAGE_PRESENT))
break;
pte &= 0xfffff000;
pte += (addr >> 10) & 0xffc;
- if (((page = *((unsigned long *) pte)) & 1) == 0)
+ page = *(unsigned long *) pte;
+ if (!(page & PAGE_PRESENT))
break;
- if ((page & 2) == 0)
- un_wp_page((unsigned long *) pte);
+ if (!(page & 2)) {
+ do_wp_page(0,addr,current,0);
+ continue;
+ }
page &= 0xfffff000;
page += addr & 0xfff;
i = 4096-(addr & 0xfff);
@@ -93,7 +99,11 @@ static int write_mem(struct inode * inode, struct file * file,char * buf, int co
count -= i;
}
file->f_pos = addr;
- return tmp-buf;
+ if (tmp != buf)
+ return tmp-buf;
+ if (current->signal & ~current->blocked)
+ return -ERESTARTSYS;
+ return 0;
}
static int read_kmem(struct inode * inode, struct file * file,char * buf, int count)
@@ -102,10 +112,10 @@ static int read_kmem(struct inode * inode, struct file * file,char * buf, int co
if (count < 0)
return -EINVAL;
- if (p >= HIGH_MEMORY)
+ if (p >= high_memory)
return 0;
- if (count > HIGH_MEMORY - p)
- count = HIGH_MEMORY - p;
+ if (count > high_memory - p)
+ count = high_memory - p;
memcpy_tofs(buf,(void *) p,count);
file->f_pos += count;
return count;
@@ -117,10 +127,10 @@ static int write_kmem(struct inode * inode, struct file * file,char * buf, int c
if (count < 0)
return -EINVAL;
- if (p >= HIGH_MEMORY)
+ if (p >= high_memory)
return 0;
- if (count > HIGH_MEMORY - p)
- count = HIGH_MEMORY - p;
+ if (count > high_memory - p)
+ count = high_memory - p;
memcpy_fromfs((void *) p,buf,count);
file->f_pos += count;
return count;
diff --git a/kernel/chr_drv/mouse.c b/kernel/chr_drv/mouse.c
index 66f0ccc..396e6c2 100644
--- a/kernel/chr_drv/mouse.c
+++ b/kernel/chr_drv/mouse.c
@@ -20,17 +20,17 @@
#include <linux/sched.h>
#include <linux/mouse.h>
#include <linux/tty.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+
#include <asm/io.h>
#include <asm/segment.h>
#include <asm/system.h>
#include <asm/irq.h>
-#include <signal.h>
-#include <errno.h>
-#include <signal.h>
static struct mouse_status mouse;
-static void mouse_interrupt(int cpl)
+static void mouse_interrupt(int unused)
{
char dx, dy, buttons;
@@ -77,8 +77,6 @@ static int open_mouse(struct inode * inode, struct file * file)
return -EBUSY;
if (!mouse.present)
return -EINVAL;
- if (request_irq(MOUSE_IRQ, mouse_interrupt))
- return -EBUSY;
mouse.active = 1;
mouse.ready = 0;
mouse.inode = inode;
@@ -86,6 +84,13 @@ static int open_mouse(struct inode * inode, struct file * file)
mouse.dy = 0;
mouse.buttons = mouse.latch_buttons = 0x80;
MSE_INT_ON();
+ if (request_irq(MOUSE_IRQ, mouse_interrupt)) {
+ MSE_INT_OFF();
+ mouse.active = 0;
+ mouse.ready = 0;
+ mouse.inode = NULL;
+ return -EBUSY;
+ }
return 0;
}
diff --git a/kernel/chr_drv/pty.c b/kernel/chr_drv/pty.c
index 729be84..76a8915 100644
--- a/kernel/chr_drv/pty.c
+++ b/kernel/chr_drv/pty.c
@@ -1,7 +1,7 @@
/*
* linux/kernel/chr_drv/pty.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
@@ -12,8 +12,7 @@
* void spty_write(struct tty_struct * queue);
*/
-#include <errno.h>
-
+#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/tty.h>
#include <linux/fcntl.h>
diff --git a/kernel/chr_drv/serial.c b/kernel/chr_drv/serial.c
index 284f0b6..13e15b8 100644
--- a/kernel/chr_drv/serial.c
+++ b/kernel/chr_drv/serial.c
@@ -1,7 +1,7 @@
/*
* linux/kernel/serial.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
@@ -13,9 +13,8 @@
* and all interrupts pertaining to serial IO.
*/
-#include <signal.h>
-#include <errno.h>
-
+#include <linux/errno.h>
+#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/tty.h>
@@ -33,24 +32,6 @@ struct serial_struct serial_table[NR_SERIALS] = {
{ PORT_UNKNOWN, 3, 0x2E8, 3, NULL},
};
-static void send_intr(struct serial_struct * info);
-
-static void modem_status_intr(struct serial_struct * info)
-{
- unsigned char status = inb(info->port+6);
-
- if (!(info->tty->termios.c_cflag & CLOCAL)) {
- if ((status & 0x88) == 0x08 && info->tty->pgrp > 0)
- kill_pg(info->tty->pgrp,SIGHUP,1);
-
- if (info->tty->termios.c_cflag & CRTSCTS)
- info->tty->stopped = !(status & 0x10);
-
- if (!info->tty->stopped)
- send_intr(info);
- }
-}
-
void send_break(unsigned int line)
{
unsigned short port;
@@ -131,6 +112,22 @@ static void line_status_intr(struct serial_struct * info)
/* printk("line status: %02x\n",status); */
}
+static void modem_status_intr(struct serial_struct * info)
+{
+ unsigned char status = inb(info->port+6);
+
+ if (!(info->tty->termios.c_cflag & CLOCAL)) {
+ if ((status & 0x88) == 0x08 && info->tty->pgrp > 0)
+ kill_pg(info->tty->pgrp,SIGHUP,1);
+
+ if (info->tty->termios.c_cflag & CRTSCTS)
+ info->tty->stopped = !(status & 0x10);
+
+ if (!info->tty->stopped)
+ send_intr(info);
+ }
+}
+
static void (*jmp_table[4])(struct serial_struct *) = {
modem_status_intr,
send_intr,
@@ -173,22 +170,22 @@ static inline void do_rs_write(struct serial_struct * info)
/*
* IRQ routines: one per line
*/
-static void com1_IRQ(int cpl)
+static void com1_IRQ(int unused)
{
check_tty(serial_table+0);
}
-static void com2_IRQ(int cpl)
+static void com2_IRQ(int unused)
{
check_tty(serial_table+1);
}
-static void com3_IRQ(int cpl)
+static void com3_IRQ(int unused)
{
check_tty(serial_table+2);
}
-static void com4_IRQ(int cpl)
+static void com4_IRQ(int unused)
{
check_tty(serial_table+3);
}
@@ -304,16 +301,20 @@ void serial_close(unsigned line, struct file * filp)
static void startup(unsigned short port)
{
+ int i;
+
outb_p(0x03,port+3); /* reset DLAB */
- outb_p(0x0f,port+4); /* set DTR,RTS, OUT_2 */
+ outb_p(0x0b,port+4); /* set DTR,RTS, OUT_2 */
outb_p(0x0f,port+1); /* enable all intrs */
inb_p(port+2);
inb_p(port+6);
inb_p(port+2);
inb_p(port+5);
- do { /* drain all of the stuck characters out of the port */
+ for (i = 0; i < 16 ; i++) {
inb_p(port+0);
- } while (inb_p(port+5) & 1 == 1);
+ if (!(inb_p(port+5) & 1))
+ break;
+ }
inb_p(port+2);
inb_p(port+5);
}
@@ -368,8 +369,12 @@ int serial_open(unsigned line, struct file * filp)
struct serial_struct * info;
int irq,retval;
unsigned short port;
- void (*handler)(int) = serial_handler[line];
+ struct sigaction sa;
+ sa.sa_handler = serial_handler[line];
+ sa.sa_flags = SA_INTERRUPT;
+ sa.sa_mask = 0;
+ sa.sa_restorer = NULL;
if (line >= NR_SERIALS)
return -ENODEV;
info = serial_table + line;
@@ -378,7 +383,7 @@ int serial_open(unsigned line, struct file * filp)
irq = info->irq;
if (irq == 2)
irq = 9;
- if (retval = request_irq(irq,handler))
+ if (retval = irqaction(irq,&sa))
return retval;
startup(port);
return 0;
diff --git a/kernel/chr_drv/tty_io.c b/kernel/chr_drv/tty_io.c
index f50227c..67d4153 100644
--- a/kernel/chr_drv/tty_io.c
+++ b/kernel/chr_drv/tty_io.c
@@ -1,7 +1,7 @@
/*
* linux/kernel/tty_io.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
@@ -11,16 +11,14 @@
* Kill-line thanks to John T Kohl, who also corrected VMIN = VTIME = 0.
*/
-#include <errno.h>
-#include <signal.h>
-
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
#include <linux/fcntl.h>
-
-#define ALRMMASK (1<<(SIGALRM-1))
-
#include <linux/sched.h>
#include <linux/tty.h>
#include <linux/ctype.h>
+
#include <asm/io.h>
#include <asm/segment.h>
#include <asm/system.h>
@@ -28,10 +26,6 @@
#include <sys/kd.h>
#include "vt_kern.h"
-#ifndef MIN
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-#endif
-
#define QUEUES (3*(NR_CONSOLES+NR_SERIALS+2*NR_PTYS))
static struct tty_queue * tty_queues;
struct tty_struct tty_table[256];
@@ -60,7 +54,7 @@ struct tty_struct * redirect = NULL;
*/
struct tty_queue * table_list[] = { NULL, NULL };
-void put_tty_queue(char c, struct tty_queue * queue)
+void inline put_tty_queue(char c, struct tty_queue * queue)
{
int head;
unsigned long flags;
@@ -74,7 +68,7 @@ void put_tty_queue(char c, struct tty_queue * queue)
__asm__ __volatile__("pushl %0 ; popfl"::"r" (flags));
}
-int get_tty_queue(struct tty_queue * queue)
+int inline get_tty_queue(struct tty_queue * queue)
{
int result = -1;
unsigned long flags;
@@ -88,7 +82,7 @@ int get_tty_queue(struct tty_queue * queue)
return result;
}
-void tty_write_flush(struct tty_struct * tty)
+void inline tty_write_flush(struct tty_struct * tty)
{
if (EMPTY(tty->write_q))
return;
@@ -132,6 +126,7 @@ static void sleep_if_empty(struct tty_queue * queue)
void wait_for_keypress(void)
{
sleep_if_empty(tty_table[fg_console].secondary);
+ flush_input(&tty_table[fg_console]);
}
void copy_to_cooked(struct tty_struct * tty)
@@ -177,7 +172,6 @@ void copy_to_cooked(struct tty_struct * tty)
put_tty_queue(8,tty->write_q);
put_tty_queue(' ',tty->write_q);
put_tty_queue(8,tty->write_q);
- TTY_WRITE_FLUSH(tty);
}
DEC(tty->secondary->head);
}
@@ -199,7 +193,6 @@ void copy_to_cooked(struct tty_struct * tty)
put_tty_queue(8,tty->write_q);
put_tty_queue(32,tty->write_q);
put_tty_queue(8,tty->write_q);
- TTY_WRITE_FLUSH(tty);
}
DEC(tty->secondary->head);
continue;
@@ -214,7 +207,6 @@ void copy_to_cooked(struct tty_struct * tty)
if ((START_CHAR(tty) != __DISABLED_CHAR) &&
(c==START_CHAR(tty))) {
tty->stopped=0;
- TTY_WRITE_FLUSH(tty);
continue;
}
}
@@ -241,7 +233,7 @@ void copy_to_cooked(struct tty_struct * tty)
if (c==10 || (EOF_CHAR(tty) != __DISABLED_CHAR &&
c==EOF_CHAR(tty)))
tty->secondary->data++;
- if ((L_ECHO(tty) || (L_CANON(tty) && L_ECHONL(tty))) && (c==10)) {
+ if ((c==10) && (L_ECHO(tty) || (L_CANON(tty) && L_ECHONL(tty)))) {
put_tty_queue(10,tty->write_q);
put_tty_queue(13,tty->write_q);
} else if (L_ECHO(tty)) {
@@ -252,12 +244,11 @@ void copy_to_cooked(struct tty_struct * tty)
put_tty_queue(c,tty->write_q);
}
put_tty_queue(c,tty->secondary);
- TTY_WRITE_FLUSH(tty);
}
TTY_WRITE_FLUSH(tty);
if (!EMPTY(tty->secondary))
wake_up(&tty->secondary->proc_list);
- if (LEFT(tty->write_q) > TTY_BUF_SIZE/2)
+ if (tty->write_q->proc_list && LEFT(tty->write_q) > TTY_BUF_SIZE/2)
wake_up(&tty->write_q->proc_list);
}
diff --git a/kernel/chr_drv/tty_ioctl.c b/kernel/chr_drv/tty_ioctl.c
index d508807..eb213ac 100644
--- a/kernel/chr_drv/tty_ioctl.c
+++ b/kernel/chr_drv/tty_ioctl.c
@@ -1,16 +1,16 @@
/*
* linux/kernel/chr_drv/tty_ioctl.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
-#include <errno.h>
-#include <termios.h>
-#include <sys/types.h>
-
+#include <linux/types.h>
+#include <linux/termios.h>
+#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/tty.h>
+#include <linux/fcntl.h>
#include <asm/io.h>
#include <asm/segment.h>
@@ -391,6 +391,23 @@ int tty_ioctl(struct inode * inode, struct file * file,
if (!IS_A_SERIAL(dev))
return -EINVAL;
return set_serial_info(dev-64,(struct serial_struct *) arg);
+ case FIONBIO:
+ if (arg)
+ file->f_flags |= O_NONBLOCK;
+ else
+ file->f_flags &= ~O_NONBLOCK;
+ return 0;
+ case TIOCNOTTY:
+ if (MINOR(file->f_rdev) != current->tty)
+ return -EINVAL;
+ current->tty = -1;
+ if (current->leader) {
+ if (tty->pgrp > 0)
+ kill_pg(tty->pgrp, SIGHUP, 0);
+ tty->pgrp = -1;
+ tty->session = 0;
+ }
+ return 0;
default:
return vt_ioctl(tty, dev, cmd, arg);
}
diff --git a/kernel/chr_drv/vt.c b/kernel/chr_drv/vt.c
index 407f09b..580e6b5 100644
--- a/kernel/chr_drv/vt.c
+++ b/kernel/chr_drv/vt.c
@@ -1,24 +1,22 @@
/*
* kernel/chr_drv/vt.c
*
- * (C) 1992 obz under the linux copyright
+ * Copyright (C) 1992 obz under the linux copyright
*/
-#include <errno.h>
-
-#include <sys/types.h>
-#include <sys/kd.h>
-#include <sys/vt.h>
-
-#include <asm/io.h>
-#include <asm/segment.h>
-
+#include <linux/types.h>
+#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/tty.h>
#include <linux/timer.h>
#include <linux/kernel.h>
+#include <asm/io.h>
+#include <asm/segment.h>
+
#include "vt_kern.h"
+#include <sys/kd.h>
+#include <sys/vt.h>
/*
* console (vt and kd) routines, as defined by usl svr4 manual
diff --git a/kernel/exit.c b/kernel/exit.c
index 221d142..b31e90e 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -1,19 +1,19 @@
/*
* linux/kernel/exit.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
#define DEBUG_PROC_TREE
-#include <errno.h>
-#include <signal.h>
-#include <sys/wait.h>
-
+#include <linux/wait.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/tty.h>
+
#include <asm/segment.h>
int sys_close(int fd);
diff --git a/kernel/fork.c b/kernel/fork.c
index ca15238..e80abe8 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1,7 +1,7 @@
/*
* linux/kernel/fork.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
@@ -10,15 +10,18 @@
* Fork is rather simple, once you get the hang of it, but the memory
* management can be a bitch. See 'mm/mm.c': 'copy_page_tables()'
*/
-#include <errno.h>
-#include <stddef.h>
+#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
+#include <linux/stddef.h>
+
#include <asm/segment.h>
#include <asm/system.h>
+#define MAX_TASKS_PER_USER ((NR_TASKS/4)*3)
+
long last_pid=0;
void verify_area(void * addr,int size)
@@ -41,8 +44,8 @@ int copy_mem(int nr,struct task_struct * p)
unsigned long old_data_base,new_data_base,data_limit;
unsigned long old_code_base,new_code_base,code_limit;
- code_limit=get_limit(0x0f);
- data_limit=get_limit(0x17);
+ code_limit = get_limit(0x0f);
+ data_limit = get_limit(0x17);
old_code_base = get_base(current->ldt[1]);
old_data_base = get_base(current->ldt[2]);
if (old_data_base != old_code_base) {
@@ -67,14 +70,21 @@ int copy_mem(int nr,struct task_struct * p)
static int find_empty_process(void)
{
int i, task_nr;
+ int this_user_tasks = 0;
- repeat:
- if ((++last_pid) & 0xffff0000)
- last_pid=1;
- for(i=0 ; i<NR_TASKS ; i++)
- if (task[i] && ((task[i]->pid == last_pid) ||
- (task[i]->pgrp == last_pid)))
- goto repeat;
+repeat:
+ if ((++last_pid) & 0xffff0000)
+ last_pid=1;
+ for(i=0 ; i < NR_TASKS ; i++) {
+ if (!task[i])
+ continue;
+ if (task[i]->uid == current->uid)
+ this_user_tasks++;
+ if (task[i]->pid == last_pid || task[i]->pgrp == last_pid)
+ goto repeat;
+ }
+ if (this_user_tasks > MAX_TASKS_PER_USER && !suser())
+ return -EAGAIN;
/* Only the super-user can fill the last available slot */
task_nr = 0;
for(i=1 ; i<NR_TASKS ; i++)
@@ -102,7 +112,7 @@ int sys_fork(long ebx,long ecx,long edx,
int i,nr;
struct file *f;
- p = (struct task_struct *) get_free_page();
+ p = (struct task_struct *) get_free_page(GFP_KERNEL);
if (!p)
return -EAGAIN;
nr = find_empty_process();
@@ -117,6 +127,8 @@ int sys_fork(long ebx,long ecx,long edx,
p->state = TASK_UNINTERRUPTIBLE;
p->flags &= ~PF_PTRACED;
p->pid = last_pid;
+ if (p->pid > 1)
+ p->swappable = 1;
p->p_pptr = p->p_opptr = current;
p->p_cptr = NULL;
SET_LINKS(p);
diff --git a/kernel/ioport.c b/kernel/ioport.c
index 70a77dd..0fde696 100644
--- a/kernel/ioport.c
+++ b/kernel/ioport.c
@@ -7,9 +7,8 @@
#include <linux/sched.h>
#include <linux/kernel.h>
-
-#include <sys/types.h>
-#include <errno.h>
+#include <linux/errno.h>
+#include <linux/types.h>
#define _IODEBUG
diff --git a/kernel/irq.c b/kernel/irq.c
index 8b6cd69..438fb68 100644
--- a/kernel/irq.c
+++ b/kernel/irq.c
@@ -1,7 +1,7 @@
/*
* linux/kernel/irq.c
*
- * (C) 1992 Linus Torvalds
+ * Copyright (C) 1992 Linus Torvalds
*
* This file contains the code used by various IRQ handling routines:
* asking for different IRQ's should be done through these routines
@@ -22,20 +22,15 @@
* sa_restorer is the unused
*/
-#include <signal.h>
-#include <errno.h>
-
-#include <sys/ptrace.h>
-
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
#include <linux/sched.h>
+
#include <asm/system.h>
#include <asm/io.h>
#include <asm/irq.h>
-struct sigaction irq_sigaction[16] = {
- { NULL, 0, 0, NULL },
-};
-
void irq13(void);
/*
@@ -45,6 +40,13 @@ void irq13(void);
* the operations that are needed to keep the AT interrupt-controller
* happy. They are also written to be fast - and to disable interrupts
* as little as humanly possible.
+ *
+ * NOTE! These macros expand to three different handlers for each line: one
+ * complete handler that does all the fancy stuff (including signal handling),
+ * and one fast handler that is meant for simple IRQ's that want to be
+ * atomic. The specific handler is chosen depending on the SA_INTERRUPT
+ * flag when installing a handler. Finally, one "bad interrupt" handler, that
+ * is used when no handler is present.
*/
BUILD_IRQ(FIRST,0,0x01)
BUILD_IRQ(FIRST,1,0x02)
@@ -64,39 +66,77 @@ BUILD_IRQ(SECOND,14,0x40)
BUILD_IRQ(SECOND,15,0x80)
/*
- * This routine gets called at every IRQ request. Interrupts
- * are enabled, the interrupt has been accnowledged and this
- * particular interrupt is disabled when this is called.
- *
- * The routine has to call the appropriate handler (disabling
- * interrupts if needed first). If no handler exists, we return
- * an error value, telling the low-level IRQ routines not to
- * re-enable this IRQ line.
- *
- * Note similarities on a very low level between this and the
- * do_signal() function. Naturally this is simplified, but they
- * get similar arguments, use them similarly etc... Note that
- * unlike the signal-handlers, the IRQ-handlers don't get the IRQ
- * (signal) number as argument, but the cpl value at the time of
- * the interrupt.
+ * Pointers to the low-level handlers: first the general ones, then the
+ * fast ones, then the bad ones.
+ */
+static void (*interrupt[16])(void) = {
+ IRQ0_interrupt, IRQ1_interrupt, IRQ2_interrupt, IRQ3_interrupt,
+ IRQ4_interrupt, IRQ5_interrupt, IRQ6_interrupt, IRQ7_interrupt,
+ IRQ8_interrupt, IRQ9_interrupt, IRQ10_interrupt, IRQ11_interrupt,
+ IRQ12_interrupt, IRQ13_interrupt, IRQ14_interrupt, IRQ15_interrupt
+};
+
+static void (*fast_interrupt[16])(void) = {
+ fast_IRQ0_interrupt, fast_IRQ1_interrupt,
+ fast_IRQ2_interrupt, fast_IRQ3_interrupt,
+ fast_IRQ4_interrupt, fast_IRQ5_interrupt,
+ fast_IRQ6_interrupt, fast_IRQ7_interrupt,
+ fast_IRQ8_interrupt, fast_IRQ9_interrupt,
+ fast_IRQ10_interrupt, fast_IRQ11_interrupt,
+ fast_IRQ12_interrupt, fast_IRQ13_interrupt,
+ fast_IRQ14_interrupt, fast_IRQ15_interrupt
+};
+
+static void (*bad_interrupt[16])(void) = {
+ bad_IRQ0_interrupt, bad_IRQ1_interrupt,
+ bad_IRQ2_interrupt, bad_IRQ3_interrupt,
+ bad_IRQ4_interrupt, bad_IRQ5_interrupt,
+ bad_IRQ6_interrupt, bad_IRQ7_interrupt,
+ bad_IRQ8_interrupt, bad_IRQ9_interrupt,
+ bad_IRQ10_interrupt, bad_IRQ11_interrupt,
+ bad_IRQ12_interrupt, bad_IRQ13_interrupt,
+ bad_IRQ14_interrupt, bad_IRQ15_interrupt
+};
+
+/*
+ * Initial irq handlers.
+ */
+static struct sigaction irq_sigaction[16] = {
+ { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
+ { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
+ { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
+ { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
+ { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
+ { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
+ { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
+ { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }
+};
+
+/*
+ * do_IRQ handles IRQ's that have been installed without the
+ * SA_INTERRUPT flag: it uses the full signal-handling return
+ * and runs with other interrupts disabled. All relatively slow
+ * IRQ's should use this format: notably the keyboard/timer
+ * routines.
*/
int do_IRQ(int irq, struct pt_regs * regs)
{
struct sigaction * sa = irq + irq_sigaction;
- void (*handler)(int);
- unsigned int esp;
-
- if (!(handler = sa->sa_handler))
- return -1; /* the irq isn't re-enabled */
- __asm__ __volatile__("movl %%esp,%0":"=r" (esp));
- if (esp < 200+(unsigned long)(current+1)) {
- printk("Stack overflow on IRQ%d: shutting down\n",irq);
- return -1;
- }
- if (sa->sa_flags & SA_INTERRUPT)
- cli();
- handler(regs->cs & 3);
- sti();
+
+ sa->sa_handler((int) regs);
+ return 0; /* re-enable the irq when returning */
+}
+
+/*
+ * do_fast_IRQ handles IRQ's that don't need the fancy interrupt return
+ * stuff - the handler is also running with interrupts disabled unless
+ * it explicitly enables them later.
+ */
+int do_fast_IRQ(int irq)
+{
+ struct sigaction * sa = irq + irq_sigaction;
+
+ sa->sa_handler(0);
return 0; /* re-enable the irq when returning */
}
@@ -107,18 +147,24 @@ int irqaction(unsigned int irq, struct sigaction * new)
if (irq > 15)
return -EINVAL;
- if (irq == 2)
- irq = 9;
sa = irq + irq_sigaction;
if (sa->sa_mask)
return -EBUSY;
+ if (!new->sa_handler)
+ return -EINVAL;
__asm__ __volatile__("pushfl ; popl %0 ; cli":"=r" (flags));
*sa = *new;
sa->sa_mask = 1;
+ if (sa->sa_flags & SA_INTERRUPT)
+ set_intr_gate(0x20+irq,fast_interrupt[irq]);
+ else
+ set_intr_gate(0x20+irq,interrupt[irq]);
if (irq < 8)
outb(inb_p(0x21) & ~(1<<irq),0x21);
- else
+ else {
+ outb(inb_p(0x21) & ~(1<<2),0x21);
outb(inb_p(0xA1) & ~(1<<(irq-8)),0xA1);
+ }
__asm__ __volatile__("pushl %0 ; popfl"::"r" (flags));
return 0;
}
@@ -152,6 +198,7 @@ void free_irq(unsigned int irq)
outb(inb_p(0x21) | (1<<irq),0x21);
else
outb(inb_p(0xA1) | (1<<(irq-8)),0xA1);
+ set_intr_gate(0x20+irq,bad_interrupt[irq]);
sa->sa_handler = NULL;
sa->sa_flags = 0;
sa->sa_mask = 0;
@@ -159,32 +206,31 @@ void free_irq(unsigned int irq)
__asm__ __volatile__("pushl %0 ; popfl"::"r" (flags));
}
-extern void math_error(void);
+extern void do_coprocessor_error(long,long);
static void math_error_irq(int cpl)
{
outb(0,0xF0);
- math_error();
+ do_coprocessor_error(0,0);
}
+static void no_action(int cpl) { }
+
+static struct sigaction ignore_IRQ = {
+ no_action,
+ 0,
+ SA_INTERRUPT,
+ NULL
+};
+
void init_IRQ(void)
{
- set_trap_gate(0x20,IRQ0_interrupt);
- set_trap_gate(0x21,IRQ1_interrupt);
- set_trap_gate(0x22,IRQ2_interrupt);
- set_trap_gate(0x23,IRQ3_interrupt);
- set_trap_gate(0x24,IRQ4_interrupt);
- set_trap_gate(0x25,IRQ5_interrupt);
- set_trap_gate(0x26,IRQ6_interrupt);
- set_trap_gate(0x27,IRQ7_interrupt);
- set_trap_gate(0x28,IRQ8_interrupt);
- set_trap_gate(0x29,IRQ9_interrupt);
- set_trap_gate(0x2a,IRQ10_interrupt);
- set_trap_gate(0x2b,IRQ11_interrupt);
- set_trap_gate(0x2c,IRQ12_interrupt);
- set_trap_gate(0x2d,IRQ13_interrupt);
- set_trap_gate(0x2e,IRQ14_interrupt);
- set_trap_gate(0x2f,IRQ15_interrupt);
+ int i;
+
+ for (i = 0; i < 16 ; i++)
+ set_intr_gate(0x20+i,bad_interrupt[i]);
+ if (irqaction(2,&ignore_IRQ))
+ printk("Unable to get IRQ2 for cascade\n");
if (request_irq(13,math_error_irq))
printk("Unable to get IRQ13 for math-error handler\n");
}
diff --git a/kernel/itimer.c b/kernel/itimer.c
index d04e2e7..b69e1da 100644
--- a/kernel/itimer.c
+++ b/kernel/itimer.c
@@ -1,18 +1,18 @@
/*
* linux/kernel/itimer.c
*
- * (C) 1992 Darren Senn
+ * Copyright (C) 1992 Darren Senn
*/
/* These are all the functions necessary to implement itimers */
+#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/string.h>
-#include <asm/segment.h>
+#include <linux/errno.h>
+#include <linux/time.h>
-#include <signal.h>
-#include <sys/time.h>
-#include <errno.h>
+#include <asm/segment.h>
static unsigned long tvtojiffies(struct timeval *value)
{
diff --git a/kernel/math/Makefile b/kernel/math/Makefile
index 67828ab..5b2a163 100644
--- a/kernel/math/Makefile
+++ b/kernel/math/Makefile
@@ -13,7 +13,7 @@
.c.o:
$(CC) $(CFLAGS) $(MATH_EMULATION) -c $<
-OBJS = emulate.o error.o convert.o ea.o get_put.o \
+OBJS = emulate.o convert.o ea.o get_put.o \
add.o mul.o div.o compare.o sqrt.o
math.a: $(OBJS)
@@ -31,62 +31,67 @@ dep:
### Dependencies:
add.o : add.c /usr/src/linux/include/linux/math_emu.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
- /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h
compare.o : compare.c /usr/src/linux/include/linux/math_emu.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
- /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h
convert.o : convert.c /usr/src/linux/include/linux/math_emu.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
- /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h
div.o : div.c /usr/src/linux/include/linux/math_emu.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
- /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h
-ea.o : ea.c /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/math_emu.h \
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h
+ea.o : ea.c /usr/src/linux/include/linux/stddef.h /usr/src/linux/include/linux/math_emu.h \
/usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
- /usr/src/linux/include/sys/types.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
- /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/segment.h
-emulate.o : emulate.c /usr/src/linux/include/signal.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
- /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
- /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
- /usr/src/linux/include/sys/resource.h
-error.o : error.c /usr/src/linux/include/signal.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
- /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
- /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
- /usr/src/linux/include/sys/resource.h
-get_put.o : get_put.c /usr/src/linux/include/signal.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/linux/math_emu.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \
- /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
- /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/segment.h
+ /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h \
+ /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/asm/segment.h
+emulate.o : emulate.c /usr/src/linux/include/linux/signal.h /usr/src/linux/include/linux/sched.h \
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/time.h \
+ /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h
+get_put.o : get_put.c /usr/src/linux/include/linux/signal.h /usr/src/linux/include/linux/math_emu.h \
+ /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
+ /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h \
+ /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/time.h \
+ /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/asm/segment.h
mul.o : mul.c /usr/src/linux/include/linux/math_emu.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
- /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h
sqrt.o : sqrt.c /usr/src/linux/include/linux/math_emu.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
- /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h
diff --git a/kernel/math/add.c b/kernel/math/add.c
index 5cf84ef..563ec69 100644
--- a/kernel/math/add.c
+++ b/kernel/math/add.c
@@ -1,7 +1,7 @@
/*
* linux/kernel/math/add.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
diff --git a/kernel/math/compare.c b/kernel/math/compare.c
index 4f1dfac..e3d676c 100644
--- a/kernel/math/compare.c
+++ b/kernel/math/compare.c
@@ -1,7 +1,7 @@
/*
* linux/kernel/math/compare.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
diff --git a/kernel/math/convert.c b/kernel/math/convert.c
index e938324..3f5bbdf 100644
--- a/kernel/math/convert.c
+++ b/kernel/math/convert.c
@@ -1,7 +1,7 @@
/*
* linux/kernel/math/convert.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
#include <linux/math_emu.h>
diff --git a/kernel/math/div.c b/kernel/math/div.c
index e485fd9..55ee711 100644
--- a/kernel/math/div.c
+++ b/kernel/math/div.c
@@ -1,7 +1,7 @@
/*
* linux/kernel/math/div.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
diff --git a/kernel/math/ea.c b/kernel/math/ea.c
index 571dc1e..dba41ff 100644
--- a/kernel/math/ea.c
+++ b/kernel/math/ea.c
@@ -1,16 +1,16 @@
/*
* linux/kernel/math/ea.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
* Calculate the effective address.
*/
-#include <stddef.h>
-
+#include <linux/stddef.h>
#include <linux/math_emu.h>
+
#include <asm/segment.h>
static int __regoffset[] = {
diff --git a/kernel/math/emulate.c b/kernel/math/emulate.c
index f3a6829..1df0691 100644
--- a/kernel/math/emulate.c
+++ b/kernel/math/emulate.c
@@ -1,7 +1,7 @@
/*
* linux/kernel/math/emulate.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
@@ -32,7 +32,7 @@
#ifdef KERNEL_MATH_EMULATION
-#include <signal.h>
+#include <linux/signal.h>
#define __ALIGNED_TEMP_REAL 1
#include <linux/math_emu.h>
@@ -537,7 +537,7 @@ static temp_real_unaligned * __st(int i)
#else /* no math emulation */
-#include <signal.h>
+#include <linux/signal.h>
#include <linux/sched.h>
void math_emulate(long ___false)
diff --git a/kernel/math/error.c b/kernel/math/error.c
deleted file mode 100644
index a4218a2..0000000
--- a/kernel/math/error.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * linux/kernel/math/error.c
- *
- * (C) 1991 Linus Torvalds
- */
-
-#include <signal.h>
-
-#include <linux/sched.h>
-
-void math_error(void)
-{
- if (last_task_used_math)
- send_sig(SIGFPE,last_task_used_math,1);
- __asm__("fnclex");
-}
diff --git a/kernel/math/get_put.c b/kernel/math/get_put.c
index 39063fe..bb603cb 100644
--- a/kernel/math/get_put.c
+++ b/kernel/math/get_put.c
@@ -1,7 +1,7 @@
/*
* linux/kernel/math/get_put.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
@@ -9,8 +9,7 @@
* ints/reals/BCD etc. This is the only part that concerns itself with
* other than temporary real format. All other cals are strictly temp_real.
*/
-#include <signal.h>
-
+#include <linux/signal.h>
#include <linux/math_emu.h>
#include <linux/kernel.h>
#include <asm/segment.h>
diff --git a/kernel/math/mul.c b/kernel/math/mul.c
index ae85e70..506f418 100644
--- a/kernel/math/mul.c
+++ b/kernel/math/mul.c
@@ -1,7 +1,7 @@
/*
* linux/kernel/math/mul.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
diff --git a/kernel/math/sqrt.c b/kernel/math/sqrt.c
index 8982d75..8522224 100644
--- a/kernel/math/sqrt.c
+++ b/kernel/math/sqrt.c
@@ -1,7 +1,7 @@
/*
* linux/kernel/math/sqrt.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
diff --git a/kernel/mktime.c b/kernel/mktime.c
index a67db96..5de9c67 100644
--- a/kernel/mktime.c
+++ b/kernel/mktime.c
@@ -1,7 +1,7 @@
/*
* linux/kernel/mktime.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
#include <time.h>
diff --git a/kernel/panic.c b/kernel/panic.c
index 7d8a06b..2459e76 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -1,7 +1,7 @@
/*
* linux/kernel/panic.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
diff --git a/kernel/printk.c b/kernel/printk.c
index 1d5ef8d..2e0a7a1 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -1,16 +1,15 @@
/*
* linux/kernel/printk.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
#include <stdarg.h>
-#include <stddef.h>
-#include <errno.h>
#include <asm/segment.h>
#include <asm/system.h>
+#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
@@ -39,7 +38,7 @@ int sys_syslog(int type, char * buf, int len)
wake_up(&log_wait);
return 0;
case 1:
- i = get_free_page();
+ i = get_free_page(GFP_KERNEL);
if (log_page) {
free_page(i);
return 0;
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 4cfc7c8..07f3a8d 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -6,13 +6,12 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
#include <asm/segment.h>
#include <asm/system.h>
-#include <errno.h>
-#include <sys/ptrace.h>
-
/*
* does not yet catch signals sent when the child dies.
* in exit.c or in signal.c.
@@ -31,9 +30,6 @@
*/
#define MAGICNUMBER 68
-void do_no_page(unsigned long, unsigned long, struct task_struct *, unsigned long);
-void write_verify(unsigned long);
-
/* change a pid into a task struct. */
static inline struct task_struct * get_task(int pid)
{
@@ -135,7 +131,7 @@ repeat:
goto repeat;
}
if (!(page & PAGE_RW)) {
- write_verify(addr);
+ do_wp_page(0,addr,tsk,0);
goto repeat;
}
page &= 0xfffff000;
diff --git a/kernel/sched.c b/kernel/sched.c
index f8ad4ad..208aefb 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -1,7 +1,7 @@
/*
* linux/kernel/sched.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
@@ -13,18 +13,19 @@
#define TIMER_IRQ 0
+#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/kernel.h>
#include <linux/sys.h>
#include <linux/fdreg.h>
+#include <linux/errno.h>
+#include <linux/time.h>
+#include <linux/ptrace.h>
+
#include <asm/system.h>
#include <asm/io.h>
#include <asm/segment.h>
-#include <sys/time.h>
-
-#include <signal.h>
-#include <errno.h>
int need_resched = 0;
@@ -381,7 +382,13 @@ void update_avg(void)
unsigned long timer_active = 0;
struct timer_struct timer_table[32];
-static void do_timer(int cpl)
+/*
+ * The int argument is really a (struct pt_regs *), in case the
+ * interrupt wants to know from where it was called. The timer
+ * irq uses this to decide if it should update the user or system
+ * times.
+ */
+static void do_timer(int regs)
{
unsigned long mask;
struct timer_struct *tp = timer_table+0;
@@ -389,10 +396,16 @@ static void do_timer(int cpl)
static int avg_cnt = 0;
jiffies++;
- if (!cpl)
- current->stime++;
- else
+ if (3 & ((struct pt_regs *) regs)->cs)
current->utime++;
+ else {
+ current->stime++;
+ /* Update ITIMER_VIRT for current task if not in a system call */
+ if (current->it_virt_value && !(--current->it_virt_value)) {
+ current->it_virt_value = current->it_virt_incr;
+ send_sig(SIGVTALRM,current,1);
+ }
+ }
if (--avg_cnt < 0) {
avg_cnt = 500;
update_avg();
@@ -414,11 +427,6 @@ static void do_timer(int cpl)
current->it_prof_value = current->it_prof_incr;
send_sig(SIGPROF,current,1);
}
- /* Update ITIMER_VIRT for current task if not in a system call */
- if (current->it_virt_value && !(--current->it_virt_value)) {
- current->it_virt_value = current->it_virt_incr;
- send_sig(SIGVTALRM,current,1);
- }
for (mask = 1 ; mask ; tp++,mask += mask) {
if (mask > timer_active)
break;
diff --git a/kernel/signal.c b/kernel/signal.c
index ea33ca1..ca850fa 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1,17 +1,17 @@
/*
* linux/kernel/signal.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
#include <linux/sched.h>
#include <linux/kernel.h>
-#include <asm/segment.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
-#include <signal.h>
-#include <sys/wait.h>
-#include <sys/ptrace.h>
-#include <errno.h>
+#include <asm/segment.h>
extern int core_dump(long signr,struct pt_regs * regs);
@@ -122,6 +122,11 @@ int sys_sigaction(int signum, const struct sigaction * action,
extern int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options);
+/*
+ * Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ */
int do_signal(long signr,struct pt_regs * regs)
{
unsigned long sa_handler;
@@ -154,6 +159,8 @@ int do_signal(long signr,struct pt_regs * regs)
return(1); /* Ignore, see if there are more signals... */
}
if (!sa_handler) {
+ if (current->pid == 1)
+ return 1;
switch (signr) {
case SIGCONT:
case SIGCHLD:
diff --git a/kernel/sys.c b/kernel/sys.c
index 013b6d4..94a8de5 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1,22 +1,22 @@
/*
* linux/kernel/sys.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
-#include <errno.h>
-
+#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/tty.h>
#include <linux/kernel.h>
#include <linux/config.h>
-#include <asm/segment.h>
-#include <sys/times.h>
+#include <linux/times.h>
#include <linux/utsname.h>
-#include <sys/param.h>
-#include <sys/resource.h>
+#include <linux/param.h>
+#include <linux/resource.h>
#include <linux/string.h>
+#include <asm/segment.h>
+
/*
* this indicates wether you can reboot with ctrl-alt-del: the deault is yes
*/
@@ -165,8 +165,7 @@ void ctrl_alt_del(void)
if (C_A_D)
hard_reset_now();
else
- if (task[1])
- send_sig(SIGINT,task[1],1);
+ send_sig(SIGINT,task[1],1);
}
diff --git a/kernel/sys_call.S b/kernel/sys_call.S
index 410f3fe..735a795 100644
--- a/kernel/sys_call.S
+++ b/kernel/sys_call.S
@@ -1,7 +1,7 @@
/*
* linux/kernel/sys_call.S
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
@@ -168,27 +168,6 @@ ret_from_sys_call:
iret
.align 2
-_coprocessor_error:
- pushl $-1 # mark this as an int.
- SAVE_ALL
- pushl $ret_from_sys_call
- jmp _math_error
-
-.align 2
-_device_not_available:
- pushl $-1 # mark this as an int
- SAVE_ALL
- pushl $ret_from_sys_call
- clts # clear TS so that we can use math
- movl %cr0,%eax
- testl $0x4,%eax # EM (math emulation bit)
- je _math_state_restore
- pushl $0 # temporary storage for ORIG_EIP
- call _math_emulate
- addl $4,%esp
- ret
-
-.align 2
_sys_execve:
lea (EIP+4)(%esp),%eax # don't forget about the return address.
pushl %eax
@@ -228,9 +207,29 @@ error_code:
addl $8,%esp
jmp ret_from_sys_call
+.align 2
+_coprocessor_error:
+ pushl $0
+ pushl $_do_coprocessor_error
+ jmp error_code
+
+.align 2
+_device_not_available:
+ pushl $-1 # mark this as an int
+ SAVE_ALL
+ pushl $ret_from_sys_call
+ clts # clear TS so that we can use math
+ movl %cr0,%eax
+ testl $0x4,%eax # EM (math emulation bit)
+ je _math_state_restore
+ pushl $0 # temporary storage for ORIG_EIP
+ call _math_emulate
+ addl $4,%esp
+ ret
+
_debug:
pushl $0
- pushl $_do_int3 # _do_debug
+ pushl $_do_debug
jmp error_code
_nmi:
diff --git a/kernel/traps.c b/kernel/traps.c
index 9931015..8d7d039 100644
--- a/kernel/traps.c
+++ b/kernel/traps.c
@@ -1,7 +1,7 @@
/*
* linux/kernel/traps.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
@@ -10,16 +10,15 @@
* to mainly kill the offending process (probably by giving it a signal,
* but possibly by killing it outright if necessary).
*/
-#include <linux/string.h>
-
#include <linux/head.h>
#include <linux/sched.h>
#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+
#include <asm/system.h>
#include <asm/segment.h>
#include <asm/io.h>
-#include <errno.h>
-
#define get_seg_byte(seg,addr) ({ \
register char __res; \
@@ -59,57 +58,53 @@ void coprocessor_error(void);
void reserved(void);
void alignment_check(void);
-static void die(char * str,long esp_ptr,long nr)
+static void die_if_kernel(char * str,long esp_ptr,long nr)
{
long * esp = (long *) esp_ptr;
int i;
+ if ((0xffff & esp[1]) == 0xf)
+ return;
printk("%s: %04x\n\r",str,nr&0xffff);
printk("EIP: %04x:%p\nEFLAGS: %p\n", 0xffff & esp[1],esp[0],esp[2]);
- if ((0xffff & esp[1]) == 0xf)
- printk("ESP: %04x:%p\n",0xffff & esp[4],esp[3]);
printk("fs: %04x\n",_fs());
printk("base: %p, limit: %p\n",get_base(current->ldt[1]),get_limit(0x17));
- if ((0xffff & esp[1]) == 0xf) {
- printk("Stack: ");
- for (i=0;i<4;i++)
- printk("%p ",get_seg_long(0x17,i+(long *)esp[3]));
- printk("\n");
- }
str(i);
printk("Pid: %d, process nr: %d\n\r",current->pid,0xffff & i);
for(i=0;i<10;i++)
printk("%02x ",0xff & get_seg_byte(esp[1],(i+(char *)esp[0])));
printk("\n\r");
- if ((0xffff & esp[1]) == 0xf)
- send_sig(SIGSEGV, current, 0);
- else
- do_exit(SIGSEGV);
+ do_exit(SIGSEGV);
}
void do_double_fault(long esp, long error_code)
{
- die("double fault",esp,error_code);
+ send_sig(SIGSEGV, current, 1);
+ die_if_kernel("double fault",esp,error_code);
}
void do_general_protection(long esp, long error_code)
{
- die("general protection",esp,error_code);
+ send_sig(SIGSEGV, current, 1);
+ die_if_kernel("general protection",esp,error_code);
}
void do_alignment_check(long esp, long error_code)
{
- die("alignment check",esp,error_code);
+ send_sig(SIGSEGV, current, 1);
+ die_if_kernel("alignment check",esp,error_code);
}
void do_divide_error(long esp, long error_code)
{
- die("divide error",esp,error_code);
+ send_sig(SIGFPE, current, 1);
+ die_if_kernel("divide error",esp,error_code);
}
void do_int3(long esp, long error_code)
{
- send_sig(SIGTRAP, current, 0);
+ send_sig(SIGTRAP, current, 1);
+ die_if_kernel("int3",esp,error_code);
}
void do_nmi(long esp, long error_code)
@@ -119,59 +114,68 @@ void do_nmi(long esp, long error_code)
void do_debug(long esp, long error_code)
{
- send_sig(SIGTRAP, current, 0);
+ send_sig(SIGTRAP, current, 1);
+ die_if_kernel("debug",esp,error_code);
}
void do_overflow(long esp, long error_code)
{
- die("overflow",esp,error_code);
+ send_sig(SIGSEGV, current, 1);
+ die_if_kernel("overflow",esp,error_code);
}
void do_bounds(long esp, long error_code)
{
- die("bounds",esp,error_code);
+ send_sig(SIGSEGV, current, 1);
+ die_if_kernel("bounds",esp,error_code);
}
void do_invalid_op(long esp, long error_code)
{
- die("invalid operand",esp,error_code);
+ send_sig(SIGILL, current, 1);
+ die_if_kernel("invalid operand",esp,error_code);
}
void do_device_not_available(long esp, long error_code)
{
- die("device not available",esp,error_code);
+ send_sig(SIGSEGV, current, 1);
+ die_if_kernel("device not available",esp,error_code);
}
void do_coprocessor_segment_overrun(long esp, long error_code)
{
- die("coprocessor segment overrun",esp,error_code);
+ send_sig(SIGFPE, last_task_used_math, 1);
+ die_if_kernel("coprocessor segment overrun",esp,error_code);
}
void do_invalid_TSS(long esp,long error_code)
{
- die("invalid TSS",esp,error_code);
+ send_sig(SIGSEGV, current, 1);
+ die_if_kernel("invalid TSS",esp,error_code);
}
void do_segment_not_present(long esp,long error_code)
{
- die("segment not present",esp,error_code);
+ send_sig(SIGSEGV, current, 1);
+ die_if_kernel("segment not present",esp,error_code);
}
void do_stack_segment(long esp,long error_code)
{
- die("stack segment",esp,error_code);
+ send_sig(SIGSEGV, current, 1);
+ die_if_kernel("stack segment",esp,error_code);
}
void do_coprocessor_error(long esp, long error_code)
{
- if (last_task_used_math != current)
- return;
- die("coprocessor error",esp,error_code);
+ send_sig(SIGFPE, last_task_used_math, 1);
+ __asm__("fnclex");
}
void do_reserved(long esp, long error_code)
{
- die("reserved (15,17-47) error",esp,error_code);
+ send_sig(SIGSEGV, current, 1);
+ die_if_kernel("reserved (15,17-47) error",esp,error_code);
}
void trap_init(void)
diff --git a/kernel/vsprintf.c b/kernel/vsprintf.c
index 8ce9873..3613e38 100644
--- a/kernel/vsprintf.c
+++ b/kernel/vsprintf.c
@@ -1,7 +1,7 @@
/*
* linux/kernel/vsprintf.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
@@ -10,6 +10,7 @@
*/
#include <stdarg.h>
+#include <linux/types.h>
#include <linux/string.h>
/* we use this so that we can do without the ctype library */
diff --git a/lib/Makefile b/lib/Makefile
index 698c50d..b86a6d4 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -37,15 +37,13 @@ dup.o : dup.c /usr/src/linux/include/linux/unistd.h
errno.o : errno.c
execve.o : execve.c /usr/src/linux/include/linux/unistd.h
malloc.o : malloc.c /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/mm.h \
- /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
- /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
- /usr/src/linux/include/signal.h /usr/src/linux/include/asm/system.h
+ /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h \
+ /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h \
+ /usr/src/linux/include/linux/minix_fs_sb.h /usr/src/linux/include/linux/ext_fs_sb.h \
+ /usr/src/linux/include/linux/msdos_fs_sb.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/asm/system.h
open.o : open.c /usr/src/linux/include/linux/unistd.h /usr/src/linux/include/stdarg.h
-setsid.o : setsid.c /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h \
- /usr/src/linux/include/linux/unistd.h
-string.o : string.c /usr/src/linux/include/linux/string.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h
-wait.o : wait.c /usr/src/linux/include/linux/unistd.h /usr/src/linux/include/sys/wait.h \
- /usr/src/linux/include/sys/types.h /usr/src/linux/include/stddef.h
-write.o : write.c /usr/src/linux/include/linux/unistd.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h
+setsid.o : setsid.c /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/unistd.h
+string.o : string.c /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/string.h
+wait.o : wait.c /usr/src/linux/include/linux/unistd.h /usr/src/linux/include/linux/types.h
+write.o : write.c /usr/src/linux/include/linux/unistd.h /usr/src/linux/include/linux/types.h
diff --git a/lib/_exit.c b/lib/_exit.c
index a1630f4..b0b77e7 100644
--- a/lib/_exit.c
+++ b/lib/_exit.c
@@ -1,7 +1,7 @@
/*
* linux/lib/_exit.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
#define __LIBRARY__
diff --git a/lib/close.c b/lib/close.c
index 31bb780..2c3f436 100644
--- a/lib/close.c
+++ b/lib/close.c
@@ -1,7 +1,7 @@
/*
* linux/lib/close.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
#define __LIBRARY__
diff --git a/lib/ctype.c b/lib/ctype.c
index f1103a9..d3613be 100644
--- a/lib/ctype.c
+++ b/lib/ctype.c
@@ -1,7 +1,7 @@
/*
* linux/lib/ctype.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
#include <linux/ctype.h>
diff --git a/lib/dup.c b/lib/dup.c
index fddb3c3..6d5ed11 100644
--- a/lib/dup.c
+++ b/lib/dup.c
@@ -1,7 +1,7 @@
/*
* linux/lib/dup.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
#define __LIBRARY__
diff --git a/lib/errno.c b/lib/errno.c
index 50aca2e..41cb9d7 100644
--- a/lib/errno.c
+++ b/lib/errno.c
@@ -1,7 +1,7 @@
/*
* linux/lib/errno.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
int errno;
diff --git a/lib/execve.c b/lib/execve.c
index 996b0ea..32a93f0 100644
--- a/lib/execve.c
+++ b/lib/execve.c
@@ -1,7 +1,7 @@
/*
* linux/lib/execve.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
#define __LIBRARY__
diff --git a/lib/itimer.c b/lib/itimer.c
deleted file mode 100644
index 69cf1eb..0000000
--- a/lib/itimer.c
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * linux/lib/itimer.c
- *
- * (C) 1992 Darren Senn
- */
-
-#define __LIBRARY__
-#include <linux/unistd.h>
-#include <sys/time.h>
-
-_syscall2(int,getitimer,int,which,struct itimerval *,value)
-_syscall3(int,setitimer,int,which,struct itimerval *,value,struct itimerval *,ovalue)
diff --git a/lib/malloc.c b/lib/malloc.c
index 42723a7..e841689 100644
--- a/lib/malloc.c
+++ b/lib/malloc.c
@@ -99,7 +99,7 @@ static inline void init_bucket_desc()
struct bucket_desc *bdesc, *first;
int i;
- first = bdesc = (struct bucket_desc *) get_free_page();
+ first = bdesc = (struct bucket_desc *) get_free_page(GFP_KERNEL);
if (!bdesc)
panic("Out of memory in init_bucket_desc()");
for (i = PAGE_SIZE/sizeof(struct bucket_desc); i > 1; i--) {
@@ -153,7 +153,7 @@ void *malloc(unsigned int len)
free_bucket_desc = bdesc->next;
bdesc->refcnt = 0;
bdesc->bucket_size = bdir->size;
- bdesc->page = bdesc->freeptr = (void *) cp = get_free_page();
+ bdesc->page = bdesc->freeptr = (void *) cp = get_free_page(GFP_KERNEL);
if (!cp)
panic("Out of memory in kernel malloc()");
/* Set up the chain of free objects */
diff --git a/lib/open.c b/lib/open.c
index 55c82ec..b69d2b5 100644
--- a/lib/open.c
+++ b/lib/open.c
@@ -1,7 +1,7 @@
/*
* linux/lib/open.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
#define __LIBRARY__
diff --git a/lib/setsid.c b/lib/setsid.c
index f9f056f..c157b71 100644
--- a/lib/setsid.c
+++ b/lib/setsid.c
@@ -1,11 +1,11 @@
/*
* linux/lib/setsid.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
#define __LIBRARY__
-#include <sys/types.h>
+#include <linux/types.h>
#include <linux/unistd.h>
_syscall0(pid_t,setsid)
diff --git a/lib/string.c b/lib/string.c
index ebbdfff..4f4722f 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -1,13 +1,15 @@
/*
* linux/lib/string.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
#ifndef __GNUC__
#error I want gcc!
#endif
+#include <linux/types.h>
+
#define extern
#define inline
#define __LIBRARY__
diff --git a/lib/wait.c b/lib/wait.c
index 114ef33..727a271 100644
--- a/lib/wait.c
+++ b/lib/wait.c
@@ -1,12 +1,12 @@
/*
* linux/lib/wait.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
#define __LIBRARY__
#include <linux/unistd.h>
-#include <sys/wait.h>
+#include <linux/types.h>
_syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
diff --git a/lib/write.c b/lib/write.c
index 5269cc6..9336ed9 100644
--- a/lib/write.c
+++ b/lib/write.c
@@ -1,12 +1,12 @@
/*
* linux/lib/write.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
#define __LIBRARY__
#include <linux/unistd.h>
-#include <sys/types.h>
+#include <linux/types.h>
_syscall3(int,write,int,fd,const char *,buf,off_t,count)
diff --git a/mm/Makefile b/mm/Makefile
index c5ad9d3..9523711 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -29,23 +29,28 @@ dep:
cp tmp_make Makefile
### Dependencies:
-memory.o : memory.c /usr/src/linux/include/signal.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \
- /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
- /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h
+memory.o : memory.c /usr/src/linux/include/asm/system.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
+ /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h \
+ /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/time.h \
+ /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/string.h
mmap.o : mmap.c /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h \
- /usr/src/linux/include/signal.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/asm/segment.h \
- /usr/src/linux/include/asm/system.h /usr/src/linux/include/errno.h /usr/src/linux/include/sys/mman.h
-swap.o : swap.c /usr/src/linux/include/errno.h /usr/src/linux/include/linux/stat.h \
- /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h \
- /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/signal.h \
- /usr/src/linux/include/linux/string.h /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h \
- /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h \
- /usr/src/linux/include/sys/resource.h
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/time.h /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/errno.h /usr/src/linux/include/asm/segment.h /usr/src/linux/include/asm/system.h \
+ /usr/src/linux/include/sys/mman.h
+swap.o : swap.c /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/fs.h \
+ /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h \
+ /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/signal.h \
+ /usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/time.h \
+ /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/errno.h /usr/src/linux/include/linux/string.h /usr/src/linux/include/linux/stat.h
diff --git a/mm/memory.c b/mm/memory.c
index 6fea346..209641e 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1,7 +1,7 @@
/*
* linux/mm/memory.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
@@ -28,43 +28,59 @@
* 20.12.91 - Ok, making the swap-device changeable like the root.
*/
-#include <signal.h>
-
#include <asm/system.h>
+#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/head.h>
#include <linux/kernel.h>
+#include <linux/string.h>
#define CODE_SPACE(addr) ((((addr)+4095)&~4095) < \
current->start_code + current->end_code)
-unsigned long HIGH_MEMORY = 0;
+unsigned long low_memory = 0;
+unsigned long high_memory = 0;
+unsigned long paging_pages = 0;
#define copy_page(from,to) \
__asm__("cld ; rep ; movsl"::"S" (from),"D" (to),"c" (1024):"cx","di","si")
-#define CHECK_LAST_NR 16
-
-static unsigned long last_pages[CHECK_LAST_NR] = { 0, };
+unsigned char * mem_map = NULL;
-unsigned char mem_map [ PAGING_PAGES ] = {0,};
+/*
+ * oom() prints a message (so that the user knows why the process died),
+ * and gives the process an untrappable SIGSEGV.
+ */
+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);
+}
+int nr_free_pages = 0;
/*
* Free a page of memory at physical address 'addr'. Used by
* 'free_page_tables()'
*/
void free_page(unsigned long addr)
{
- if (addr < LOW_MEM) return;
- if (addr < HIGH_MEMORY) {
- addr -= LOW_MEM;
- addr >>= 12;
- if (mem_map[addr]--)
+ unsigned long i;
+
+ if (addr < low_memory)
+ return;
+ if (addr < high_memory) {
+ i = addr - low_memory;
+ i >>= 12;
+ if (mem_map[i] == 1)
+ ++nr_free_pages;
+ if (mem_map[i]--)
return;
- mem_map[addr]=0;
+ mem_map[i] = 0;
}
- printk("trying to free free page: memory probably corrupted");
+ printk("trying to free free page (%08x): memory probably corrupted\n",addr);
}
/*
@@ -105,8 +121,6 @@ int free_page_tables(unsigned long from,unsigned long size)
free_page(0xfffff000 & page_dir);
}
invalidate();
- for (page = 0; page < CHECK_LAST_NR ; page++)
- last_pages[page] = 0;
return 0;
}
@@ -154,30 +168,36 @@ int copy_page_tables(unsigned long from,unsigned long to,long size)
continue;
}
from_page_table = (unsigned long *) (0xfffff000 & *from_dir);
- if (!(to_page_table = (unsigned long *) get_free_page()))
+ if (!(to_page_table = (unsigned long *) get_free_page(GFP_KERNEL)))
return -1; /* Out of memory, see freeing */
*to_dir = ((unsigned long) to_page_table) | 7;
nr = (from==0)?0xA0:1024;
for ( ; nr-- > 0 ; from_page_table++,to_page_table++) {
+repeat:
this_page = *from_page_table;
if (!this_page)
continue;
if (!(1 & this_page)) {
- if (!(new_page = get_free_page()))
+ if (!(new_page = get_free_page(GFP_KERNEL)))
return -1;
++current->rss;
read_swap_page(this_page>>1, (char *) new_page);
+ if (*from_page_table != this_page) {
+ free_page(new_page);
+ goto repeat;
+ }
*to_page_table = this_page;
*from_page_table = new_page | (PAGE_DIRTY | 7);
continue;
}
this_page &= ~2;
*to_page_table = this_page;
- if (this_page > LOW_MEM) {
+ if (this_page > low_memory) {
*from_page_table = this_page;
- this_page -= LOW_MEM;
+ this_page -= low_memory;
this_page >>= 12;
- mem_map[this_page]++;
+ if (!mem_map[this_page]++)
+ --nr_free_pages;
}
}
}
@@ -236,8 +256,6 @@ int unmap_page_range(unsigned long from, unsigned long size)
}
}
invalidate();
- for (page = 0; page < CHECK_LAST_NR ; page++)
- last_pages[page] = 0;
return 0;
}
@@ -260,6 +278,7 @@ int remap_page_range(unsigned long from, unsigned long to, unsigned long size,
{
unsigned long *page_table, *dir;
unsigned long poff, pcnt;
+ unsigned long page;
if ((from & 0xfff) || (to & 0xfff))
panic("remap_page_range called with wrong alignment");
@@ -271,7 +290,7 @@ int remap_page_range(unsigned long from, unsigned long to, unsigned long size,
while (size > 0) {
if (!(1 & *dir)) {
- if (!(page_table = (unsigned long *)get_free_page())) {
+ if (!(page_table = (unsigned long *)get_free_page(GFP_KERNEL))) {
invalidate();
return -1;
}
@@ -299,12 +318,13 @@ int remap_page_range(unsigned long from, unsigned long to, unsigned long size,
if (permiss & 4)
mask |= 1;
- if (*page_table) {
+ if (page = *page_table) {
+ *page_table = 0;
--current->rss;
- if (1 & *page_table)
- free_page(0xfffff000 & *page_table);
+ if (1 & page)
+ free_page(0xfffff000 & page);
else
- swap_free(*page_table >> 1);
+ swap_free(page >> 1);
}
/*
@@ -314,16 +334,17 @@ int remap_page_range(unsigned long from, unsigned long to, unsigned long size,
* when the page is referenced. current assumptions
* cause it to be treated as demand allocation.
*/
- if (mask == 4 || to >= HIGH_MEMORY)
+ if (mask == 4 || to >= high_memory)
*page_table++ = 0; /* not present */
else {
++current->rss;
*page_table++ = (to | mask);
- if (to > LOW_MEM) {
+ if (to > low_memory) {
unsigned long frame;
- frame = to - LOW_MEM;
+ frame = to - low_memory;
frame >>= 12;
- mem_map[frame]++;
+ if (!mem_map[frame]++)
+ --nr_free_pages;
}
}
to += PAGE_SIZE;
@@ -331,8 +352,6 @@ int remap_page_range(unsigned long from, unsigned long to, unsigned long size,
pcnt = (size > 1024 ? 1024 : size);
}
invalidate();
- for (to = 0; to < CHECK_LAST_NR ; to++)
- last_pages[to] = 0;
return 0;
}
@@ -348,11 +367,11 @@ static unsigned long put_page(unsigned long page,unsigned long address)
/* NOTE !!! This uses the fact that _pg_dir=0 */
- if (page < LOW_MEM || page >= HIGH_MEMORY) {
+ if (page >= high_memory) {
printk("put_page: trying to put page %p at %p\n",page,address);
return 0;
}
- if (mem_map[(page-LOW_MEM)>>12] != 1) {
+ if (page >= low_memory && mem_map[(page-low_memory)>>12] != 1) {
printk("put_page: mem_map disagrees with %p at %p\n",page,address);
return 0;
}
@@ -360,10 +379,13 @@ static unsigned long put_page(unsigned long page,unsigned long address)
if ((*page_table)&1)
page_table = (unsigned long *) (0xfffff000 & *page_table);
else {
- if (!(tmp=get_free_page()))
- return 0;
+ tmp = get_free_page(GFP_KERNEL);
+ if (!tmp) {
+ oom(current);
+ tmp = BAD_PAGETABLE;
+ }
*page_table = tmp | 7;
- page_table = (unsigned long *) tmp;
+ return 0;
}
page_table += (address>>12) & 0x3ff;
if (*page_table) {
@@ -388,15 +410,15 @@ unsigned long put_dirty_page(unsigned long page, unsigned long address)
/* NOTE !!! This uses the fact that _pg_dir=0 */
- if (page < LOW_MEM || page >= HIGH_MEMORY)
+ if (page < low_memory || page >= high_memory)
printk("put_dirty_page: trying to put page %p at %p\n",page,address);
- if (mem_map[(page-LOW_MEM)>>12] != 1)
+ if (mem_map[(page-low_memory)>>12] != 1)
printk("mem_map disagrees with %p at %p\n",page,address);
page_table = (unsigned long *) ((address>>20) & 0xffc);
if ((*page_table)&1)
page_table = (unsigned long *) (0xfffff000 & *page_table);
else {
- if (!(tmp=get_free_page()))
+ if (!(tmp=get_free_page(GFP_KERNEL)))
return 0;
*page_table = tmp|7;
page_table = (unsigned long *) tmp;
@@ -412,7 +434,7 @@ unsigned long put_dirty_page(unsigned long page, unsigned long address)
return page;
}
-void un_wp_page(unsigned long * table_entry)
+static void un_wp_page(unsigned long * table_entry, struct task_struct * task)
{
unsigned long old_page;
unsigned long new_page = 0;
@@ -420,32 +442,36 @@ void un_wp_page(unsigned long * table_entry)
repeat:
old_page = *table_entry;
- dirty = old_page & PAGE_DIRTY;
if (!(old_page & 1)) {
if (new_page)
free_page(new_page);
return;
}
+ dirty = old_page & PAGE_DIRTY;
old_page &= 0xfffff000;
- if (old_page >= HIGH_MEMORY) {
+ if (old_page >= high_memory) {
if (new_page)
free_page(new_page);
printk("bad page address\n\r");
- do_exit(SIGSEGV);
+ send_sig(SIGSEGV, task, 1);
+ *table_entry = BAD_PAGE | 7;
+ return;
}
- if (old_page >= LOW_MEM && mem_map[MAP_NR(old_page)]==1) {
+ if (old_page >= low_memory && mem_map[MAP_NR(old_page)]==1) {
*table_entry |= 2;
invalidate();
if (new_page)
free_page(new_page);
return;
}
- if (!new_page) {
- if (!(new_page=get_free_page()))
- oom();
+ if (!new_page && (new_page=get_free_page(GFP_KERNEL)))
goto repeat;
+ if (new_page)
+ copy_page(old_page,new_page);
+ else {
+ new_page = BAD_PAGE;
+ send_sig(SIGSEGV,task,1);
}
- copy_page(old_page,new_page);
*table_entry = new_page | dirty | 7;
free_page(old_page);
invalidate();
@@ -458,32 +484,49 @@ repeat:
*
* If it's in code space we exit with a segment error.
*/
-void do_wp_page(unsigned long error_code,unsigned long address)
+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 = (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;
+ }
if (address < TASK_SIZE) {
- printk("\n\rBAD! KERNEL MEMORY WP-ERR!\n\r");
- do_exit(SIGSEGV);
+ printk("do_wp_page: kernel WP error at address %08x (%08x)\n",address,pte);
+ *(unsigned long *) pde = BAD_PAGETABLE | 7;
+ send_sig(SIGSEGV, tsk, 1);
+ return;
}
- if (address - current->start_code >= TASK_SIZE) {
- printk("Bad things happen: page error in do_wp_page\n\r");
- do_exit(SIGSEGV);
+ 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;
}
++current->min_flt;
- un_wp_page((unsigned long *)
- (((address>>10) & 0xffc) + (0xfffff000 &
- *((unsigned long *) ((address>>20) &0xffc)))));
+ un_wp_page((unsigned long *) pte, tsk);
}
void write_verify(unsigned long address)
{
unsigned long page;
- if (!( (page = *((unsigned long *) ((address>>20) & 0xffc)) )&1))
+ page = *(unsigned long *) ((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);
+ un_wp_page((unsigned long *) page, current);
return;
}
@@ -491,10 +534,13 @@ static void get_empty_page(unsigned long address)
{
unsigned long tmp;
- if (!(tmp=get_free_page()) || !put_page(tmp,address)) {
- free_page(tmp); /* 0 is ok - ignored */
- oom();
+ tmp = get_free_page(GFP_KERNEL);
+ if (!tmp) {
+ oom(current);
+ tmp = BAD_PAGE;
}
+ if (!put_page(tmp,address))
+ free_page(tmp);
}
/*
@@ -527,14 +573,14 @@ static int try_to_share(unsigned long address, struct task_struct * p)
if ((phys_addr & 0x41) != 0x01)
return 0;
phys_addr &= 0xfffff000;
- if (phys_addr >= HIGH_MEMORY || phys_addr < LOW_MEM)
+ if (phys_addr >= high_memory || phys_addr < low_memory)
return 0;
to = *(unsigned long *) to_page;
if (!(to & 1)) {
- if (to = get_free_page())
- *(unsigned long *) to_page = to | 7;
- else
- oom();
+ to = get_free_page(GFP_KERNEL);
+ if (!to)
+ return 0;
+ *(unsigned long *) to_page = to | 7;
}
to &= 0xfffff000;
to_page = to + ((address>>10) & 0xffc);
@@ -544,9 +590,10 @@ static int try_to_share(unsigned long address, struct task_struct * p)
*(unsigned long *) from_page &= ~2;
*(unsigned long *) to_page = *(unsigned long *) from_page;
invalidate();
- phys_addr -= LOW_MEM;
+ phys_addr -= low_memory;
phys_addr >>= 12;
- mem_map[phys_addr]++;
+ if (!mem_map[phys_addr]++)
+ --nr_free_pages;
return 1;
}
@@ -587,9 +634,9 @@ static int share_page(struct inode * inode, unsigned long address)
}
/*
- * fill in an empty page or directory if none exists
+ * fill in an empty page-table if none exists
*/
-static unsigned long get_empty(unsigned long * p)
+static unsigned long get_empty_pgtable(unsigned long * p)
{
unsigned long page = 0;
@@ -599,38 +646,29 @@ repeat:
return *p;
}
if (*p) {
- printk("get_empty: bad page entry \n");
+ printk("get_empty_pgtable: bad page-directory entry \n");
*p = 0;
}
if (page) {
*p = page | 7;
return *p;
}
- if (!(page = get_free_page()))
- oom();
- goto repeat;
+ if (page = get_free_page(GFP_KERNEL))
+ goto repeat;
+ oom(current);
+ *p = BAD_PAGETABLE | 7;
+ return 0;
}
void do_no_page(unsigned long error_code, unsigned long address,
struct task_struct *tsk, unsigned long user_esp)
{
- static unsigned int last_checked = 0;
int nr[4];
unsigned long tmp;
unsigned long page;
unsigned int block,i;
struct inode * inode;
- /* Thrashing ? Make it interruptible, but don't penalize otherwise */
- for (i = 0; i < CHECK_LAST_NR; i++)
- if ((address & 0xfffff000) == last_pages[i]) {
- current->counter = 0;
- schedule();
- }
- last_checked++;
- if (last_checked >= CHECK_LAST_NR)
- last_checked = 0;
- last_pages[last_checked] = address & 0xfffff000;
if (address < TASK_SIZE) {
printk("\n\rBAD!! KERNEL PAGE MISSING\n\r");
do_exit(SIGSEGV);
@@ -639,7 +677,9 @@ void do_no_page(unsigned long error_code, unsigned long address,
printk("Bad things happen: nonexistent page error in do_no_page\n\r");
do_exit(SIGSEGV);
}
- page = get_empty((unsigned long *) ((address >> 20) & 0xffc));
+ page = get_empty_pgtable((unsigned long *) ((address >> 20) & 0xffc));
+ if (!page)
+ return;
page &= 0xfffff000;
page += (address >> 10) & 0xffc;
tmp = *(unsigned long *) page;
@@ -691,8 +731,12 @@ void do_no_page(unsigned long error_code, unsigned long address,
return;
}
++tsk->maj_flt;
- if (!(page = get_free_page()))
- oom();
+ page = get_free_page(GFP_KERNEL);
+ if (!page) {
+ oom(current);
+ put_page(BAD_PAGE,address);
+ return;
+ }
for (i=0 ; i<4 ; block++,i++)
nr[i] = bmap(inode,block);
bread_page(page,inode->i_dev,nr);
@@ -707,26 +751,7 @@ void do_no_page(unsigned long error_code, unsigned long address,
if (put_page(page,address))
return;
free_page(page);
- oom();
-}
-
-void mem_init(long start_mem, long end_mem)
-{
- int i;
-
- end_mem &= 0xfffff000;
- start_mem += 0xfff;
- start_mem &= 0xfffff000;
- swap_device = 0;
- swap_file = NULL;
- HIGH_MEMORY = end_mem;
- for (i=0 ; i<PAGING_PAGES ; i++)
- mem_map[i] = USED;
- i = MAP_NR(start_mem);
- end_mem -= start_mem;
- end_mem >>= 12;
- while (end_mem-->0)
- mem_map[i++]=0;
+ oom(current);
}
void show_mem(void)
@@ -736,9 +761,10 @@ void show_mem(void)
unsigned long * pg_tbl;
printk("Mem-info:\n\r");
- for(i=0 ; i<PAGING_PAGES ; i++) {
- if (mem_map[i] == USED)
- continue;
+ printk("Free pages: %6d\n",nr_free_pages);
+ printk("Buffer heads: %6d\n",nr_buffer_heads);
+ printk("Buffer blocks: %6d\n",nr_buffers);
+ for (i = 0 ; i < paging_pages ; i++) {
total++;
if (!mem_map[i])
free++;
@@ -747,21 +773,22 @@ void show_mem(void)
}
printk("%d free pages of %d\n\r",free,total);
printk("%d pages shared\n\r",shared);
+ printk("%d free pages via nr_free_pages\n\r", nr_free_pages);
k = 0;
for(i=4 ; i<1024 ;) {
if (1&pg_dir[i]) {
- if (pg_dir[i]>HIGH_MEMORY) {
+ if (pg_dir[i]>high_memory) {
printk("page directory[%d]: %08X\n\r",
i,pg_dir[i]);
i++;
continue;
}
- if (pg_dir[i]>LOW_MEM)
+ if (pg_dir[i]>low_memory)
free++,k++;
pg_tbl=(unsigned long *) (0xfffff000 & pg_dir[i]);
for(j=0 ; j<1024 ; j++)
- if ((pg_tbl[j]&1) && pg_tbl[j]>LOW_MEM)
- if (pg_tbl[j]>HIGH_MEMORY)
+ if ((pg_tbl[j]&1) && pg_tbl[j]>low_memory)
+ if (pg_tbl[j]>high_memory)
printk("page_dir[%d][%d]: %08X\n\r",
i,j, pg_tbl[j]);
else
@@ -796,7 +823,25 @@ void do_page_fault(unsigned long *esp, unsigned long error_code)
do_no_page(error_code, address, current, user_esp);
return;
} else {
- do_wp_page(error_code, address);
+ do_wp_page(error_code, address, current, user_esp);
return;
}
}
+
+unsigned long mem_init(unsigned long start_mem, unsigned long end_mem)
+{
+ end_mem &= 0xfffff000;
+ high_memory = end_mem;
+ mem_map = (char *) start_mem;
+ paging_pages = (end_mem - start_mem) >> 12;
+ start_mem += paging_pages;
+ start_mem += 0xfff;
+ start_mem &= 0xfffff000;
+ low_memory = start_mem;
+ paging_pages = (high_memory - low_memory) >> 12;
+ swap_device = 0;
+ swap_file = NULL;
+ memset(mem_map,0,paging_pages);
+ nr_free_pages = paging_pages;
+ return start_mem;
+}
diff --git a/mm/mmap.c b/mm/mmap.c
index 281da97..38dc07d 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -7,9 +7,11 @@
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
+#include <linux/errno.h>
+
#include <asm/segment.h>
#include <asm/system.h>
-#include <errno.h>
+
#include <sys/mman.h>
/*
@@ -57,7 +59,7 @@ mmap_chr(unsigned long addr, size_t len, int prot, int flags,
return (caddr_t)-ENODEV;
/*
- * we only allow mappings from address 0 to HIGH_MEMORY, since thats
+ * we only allow mappings from address 0 to high_memory, since thats
* the range of our memory [actually this is a lie. the buffer cache
* and ramdisk occupy higher memory, but the paging stuff won't
* let us map to it anyway, so we break it here].
@@ -71,7 +73,7 @@ mmap_chr(unsigned long addr, size_t len, int prot, int flags,
* truly useful.
*/
- if (len > HIGH_MEMORY || off > HIGH_MEMORY - len) /* avoid overflow */
+ if (len > high_memory || off > high_memory - len) /* avoid overflow */
return (caddr_t)-ENXIO;
if (remap_page_range(addr, off, len, PERMISS(flags, prot)))
diff --git a/mm/swap.c b/mm/swap.c
index f968e05..b582eb4 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -1,7 +1,7 @@
/*
* linux/mm/swap.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
@@ -9,14 +9,22 @@
* Started 18.12.91
*/
-#include <errno.h>
-
-#include <linux/stat.h>
#include <linux/mm.h>
-#include <linux/string.h>
#include <linux/sched.h>
#include <linux/head.h>
#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/stat.h>
+
+static int lowest_bit = 0;
+static int highest_bit = 0;
+
+/*
+ * The following are used to make sure we don't thrash too much...
+ */
+#define NR_LAST_FREE_PAGES 32
+static unsigned long last_free_pages[NR_LAST_FREE_PAGES] = {0,};
#define SWAP_BITS (4096<<3)
@@ -35,98 +43,118 @@ bitop(setbit,"s")
bitop(clrbit,"r")
static char * swap_bitmap = NULL;
+static char * swap_lockmap = NULL;
unsigned int swap_device = 0;
struct inode * swap_file = NULL;
void rw_swap_page(int rw, unsigned int nr, char * buf)
{
- unsigned int zones[4];
- int i;
+ static struct wait_queue * lock_queue = NULL;
- if (swap_device) {
- ll_rw_page(rw,swap_device,nr,buf);
+ if (!swap_lockmap) {
+ printk("No swap lock-map\n");
return;
}
- if (swap_file) {
- nr <<= 2;
+ while (setbit(swap_lockmap,nr))
+ sleep_on(&lock_queue);
+ if (swap_device) {
+ ll_rw_page(rw,swap_device,nr,buf);
+ } else if (swap_file) {
+ unsigned int zones[4];
+ unsigned int block = nr << 2;
+ int i;
+
for (i = 0; i < 4; i++)
- if (!(zones[i] = bmap(swap_file,nr++))) {
+ if (!(zones[i] = bmap(swap_file,block++))) {
printk("rw_swap_page: bad swap file\n");
return;
}
ll_rw_swap_file(rw,swap_file->i_dev, zones,4,buf);
- return;
- }
- printk("ll_swap_page: no swap file or device\n");
+ } else
+ printk("re_swap_page: no swap file or device\n");
+ if (!clrbit(swap_lockmap,nr))
+ printk("rw_swap_page: lock already cleared\n");
+ wake_up(&lock_queue);
}
-/*
- * We never page the pages in task[0] - kernel memory.
- * We page all other pages.
- */
-#define FIRST_VM_PAGE (TASK_SIZE>>12)
-#define LAST_VM_PAGE (1024*1024)
-#define VM_PAGES (LAST_VM_PAGE - FIRST_VM_PAGE)
-
-static int get_swap_page(void)
+static unsigned int get_swap_page(void)
{
- int nr;
+ unsigned int nr;
if (!swap_bitmap)
return 0;
- for (nr = 1; nr < SWAP_BITS ; nr++)
- if (clrbit(swap_bitmap,nr))
- return nr;
+ for (nr = lowest_bit; nr <= highest_bit ; nr++)
+ if (clrbit(swap_bitmap,nr)) {
+ if (nr == highest_bit)
+ highest_bit--;
+ return lowest_bit = nr;
+ }
return 0;
}
-void swap_free(int swap_nr)
+void swap_free(unsigned int swap_nr)
{
if (!swap_nr)
return;
- if (swap_bitmap && swap_nr < SWAP_BITS)
+ if (swap_bitmap && swap_nr < SWAP_BITS) {
+ if (swap_nr < lowest_bit)
+ lowest_bit = swap_nr;
+ if (swap_nr > highest_bit)
+ highest_bit = swap_nr;
if (!setbit(swap_bitmap,swap_nr))
return;
- printk("swap_free: swap-space bitmap bad\n");
+ }
+ printk("swap_free: swap-space bitmap bad (bit %d)\n",swap_nr);
return;
}
void swap_in(unsigned long *table_ptr)
{
- int swap_nr;
+ unsigned long swap_nr;
unsigned long page;
- if (!swap_bitmap) {
- printk("Trying to swap in without swap bit-map");
- return;
- }
- if (1 & *table_ptr) {
+ swap_nr = *table_ptr;
+ if (1 & swap_nr) {
printk("trying to swap in present page\n\r");
return;
}
- swap_nr = *table_ptr >> 1;
if (!swap_nr) {
printk("No swap page in swap_in\n\r");
return;
}
- if (!(page = get_free_page()))
- oom();
- read_swap_page(swap_nr, (char *) page);
- if (setbit(swap_bitmap,swap_nr))
- printk("swapping in multiply from same page\n\r");
+ if (!swap_bitmap) {
+ printk("Trying to swap in without swap bit-map");
+ *table_ptr = BAD_PAGE;
+ return;
+ }
+ page = get_free_page(GFP_KERNEL);
+ if (!page) {
+ oom(current);
+ page = BAD_PAGE;
+ } else
+ read_swap_page(swap_nr>>1, (char *) page);
+ if (*table_ptr != swap_nr) {
+ free_page(page);
+ return;
+ }
+ swap_free(swap_nr>>1);
*table_ptr = page | (PAGE_DIRTY | 7);
}
int try_to_swap_out(unsigned long * table_ptr)
{
+ int i;
unsigned long page;
unsigned long swap_nr;
page = *table_ptr;
if (!(PAGE_PRESENT & page))
return 0;
- if (page - LOW_MEM > PAGING_MEMORY)
+ if (page < low_memory || page >= high_memory)
return 0;
+ for (i = 0; i < NR_LAST_FREE_PAGES; i++)
+ if (last_free_pages[i] == (page & 0xfffff000))
+ return 0;
if (PAGE_DIRTY & page) {
page &= 0xfffff000;
if (mem_map[MAP_NR(page)] != 1)
@@ -147,14 +175,20 @@ int try_to_swap_out(unsigned long * table_ptr)
}
/*
+ * We never page the pages in task[0] - kernel memory.
+ * We page all other pages.
+ */
+#define FIRST_VM_PAGE (TASK_SIZE>>12)
+#define LAST_VM_PAGE (1024*1024)
+#define VM_PAGES (LAST_VM_PAGE - FIRST_VM_PAGE)
+
+/*
* Go through the page tables, searching for a user page that
* we can swap out.
*
- * Here it's easy to add a check for tasks that may not be swapped out:
- * loadable device drivers or similar. Just add an entry to the task-struct
- * and check it at the same time you check for the existence of the task.
- * The code assumes tasks are page-table aligned, but so do other parts
- * of the memory manager...
+ * We now check that the process is swappable (normally only 'init'
+ * is un-swappable), allowing high-priority processes which cannot be
+ * swapped out (things like user-level device drivers (Not implemented)).
*/
int swap_out(void)
{
@@ -195,8 +229,9 @@ check_table:
dir_entry++;
goto check_dir;
}
- if (try_to_swap_out(page_entry + (unsigned long *) pg_table)) {
+ if (p->swappable && try_to_swap_out(page_entry + (unsigned long *) pg_table)) {
p->rss--;
+ dir_entry++;
return 1;
}
goto check_table;
@@ -209,9 +244,10 @@ no_swap:
* Get physical address of first (actually last :-) free page, and mark it
* used. If no free pages left, return 0.
*/
-unsigned long get_free_page(void)
+unsigned long get_free_page(int priority)
{
unsigned long result;
+ static unsigned long index = 0;
repeat:
__asm__("std ; repne ; scasb\n\t"
@@ -226,18 +262,39 @@ repeat:
"movl %%edx,%%eax\n"
"1:\tcld"
:"=a" (result)
- :"0" (0),"i" (LOW_MEM),"c" (PAGING_PAGES),
- "D" (mem_map+PAGING_PAGES-1)
+ :"0" (0),"b" (low_memory),"c" (paging_pages),
+ "D" (mem_map+paging_pages-1)
:"di","cx","dx");
- if (result >= HIGH_MEMORY)
+ if (result >= high_memory)
goto repeat;
- if ((result && result < LOW_MEM) || (result & 0xfff)) {
+ if ((result && result < low_memory) || (result & 0xfff)) {
printk("weird result: %08x\n",result);
result = 0;
}
- if (!result && swap_out())
+ if (result) {
+ --nr_free_pages;
+ if (index >= NR_LAST_FREE_PAGES)
+ index = 0;
+ last_free_pages[index] = result;
+ index++;
+ return result;
+ }
+ if (nr_free_pages) {
+ printk("Damn. mm_free_page count is off by %d\r\n",
+ nr_free_pages);
+ nr_free_pages = 0;
+ }
+ if (priority <= GFP_BUFFER)
+ return 0;
+ if (shrink_buffers()) {
+ schedule();
+ goto repeat;
+ }
+ if (swap_out()) {
+ schedule();
goto repeat;
- return result;
+ }
+ return 0;
}
/*
@@ -255,7 +312,7 @@ int sys_swapon(const char * specialfile)
return -EPERM;
if (!(swap_inode = namei(specialfile)))
return -ENOENT;
- if (swap_file || swap_device || swap_bitmap) {
+ if (swap_file || swap_device || swap_bitmap || swap_lockmap) {
iput(swap_inode);
return -EBUSY;
}
@@ -268,36 +325,51 @@ int sys_swapon(const char * specialfile)
iput(swap_inode);
return -EINVAL;
}
- tmp = (char *) get_free_page();
- if (!tmp) {
+ tmp = (char *) get_free_page(GFP_USER);
+ swap_lockmap = (char *) get_free_page(GFP_USER);
+ if (!tmp || !swap_lockmap) {
+ printk("Unable to start swapping: out of memory :-)\n");
+ free_page((long) tmp);
+ free_page((long) swap_lockmap);
iput(swap_file);
swap_device = 0;
swap_file = NULL;
- printk("Unable to start swapping: out of memory :-)\n");
+ swap_bitmap = NULL;
+ swap_lockmap = NULL;
return -ENOMEM;
}
read_swap_page(0,tmp);
if (strncmp("SWAP-SPACE",tmp+4086,10)) {
printk("Unable to find swap-space signature\n\r");
free_page((long) tmp);
+ free_page((long) swap_lockmap);
iput(swap_file);
swap_device = 0;
swap_file = NULL;
swap_bitmap = NULL;
+ swap_lockmap = NULL;
return -EINVAL;
}
memset(tmp+4086,0,10);
j = 0;
+ lowest_bit = 0;
+ highest_bit = 0;
for (i = 1 ; i < SWAP_BITS ; i++)
- if (bit(tmp,i))
+ if (bit(tmp,i)) {
+ if (!lowest_bit)
+ lowest_bit = i;
+ highest_bit = i;
j++;
+ }
if (!j) {
printk("Empty swap-file\n");
free_page((long) tmp);
+ free_page((long) swap_lockmap);
iput(swap_file);
swap_device = 0;
swap_file = NULL;
swap_bitmap = NULL;
+ swap_lockmap = NULL;
return -EINVAL;
}
swap_bitmap = tmp;
diff --git a/net/Makefile b/net/Makefile
index 1292340..daada70 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -29,21 +29,24 @@ dep:
cp tmp_make Makefile
### Dependencies:
-socket.o : socket.c /usr/src/linux/include/signal.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/errno.h /usr/src/linux/include/linux/sched.h \
- /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/sys/dirent.h \
- /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h /usr/src/linux/include/linux/mm.h \
- /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/sys/param.h /usr/src/linux/include/sys/time.h \
- /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h /usr/src/linux/include/linux/stat.h \
- /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/segment.h /usr/src/linux/include/sys/socket.h \
- /usr/src/linux/include/linux/fcntl.h /usr/src/linux/include/termios.h kern_sock.h \
- socketcall.h
-unix.o : unix.c /usr/src/linux/include/signal.h /usr/src/linux/include/sys/types.h \
- /usr/src/linux/include/stddef.h /usr/src/linux/include/errno.h /usr/src/linux/include/linux/string.h \
+socket.o : socket.c /usr/src/linux/include/linux/signal.h /usr/src/linux/include/linux/errno.h \
/usr/src/linux/include/linux/sched.h /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h \
- /usr/src/linux/include/sys/dirent.h /usr/src/linux/include/limits.h /usr/src/linux/include/sys/vfs.h \
- /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/sys/param.h \
- /usr/src/linux/include/sys/time.h /usr/src/linux/include/time.h /usr/src/linux/include/sys/resource.h \
- /usr/src/linux/include/linux/stat.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/segment.h \
- /usr/src/linux/include/sys/socket.h /usr/src/linux/include/sys/un.h /usr/src/linux/include/linux/fcntl.h \
- /usr/src/linux/include/termios.h kern_sock.h
+ /usr/src/linux/include/linux/limits.h /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h \
+ /usr/src/linux/include/linux/dirent.h /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/time.h \
+ /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/stat.h /usr/src/linux/include/linux/socket.h /usr/src/linux/include/linux/fcntl.h \
+ /usr/src/linux/include/linux/termios.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/segment.h \
+ kern_sock.h socketcall.h
+unix.o : unix.c /usr/src/linux/include/linux/signal.h /usr/src/linux/include/linux/sched.h \
+ /usr/src/linux/include/linux/head.h /usr/src/linux/include/linux/fs.h /usr/src/linux/include/linux/limits.h \
+ /usr/src/linux/include/linux/wait.h /usr/src/linux/include/linux/types.h /usr/src/linux/include/linux/dirent.h \
+ /usr/src/linux/include/linux/vfs.h /usr/src/linux/include/linux/minix_fs_sb.h \
+ /usr/src/linux/include/linux/ext_fs_sb.h /usr/src/linux/include/linux/msdos_fs_sb.h \
+ /usr/src/linux/include/linux/mm.h /usr/src/linux/include/linux/kernel.h /usr/src/linux/include/linux/time.h \
+ /usr/src/linux/include/linux/param.h /usr/src/linux/include/linux/resource.h \
+ /usr/src/linux/include/linux/errno.h /usr/src/linux/include/linux/string.h /usr/src/linux/include/linux/stat.h \
+ /usr/src/linux/include/linux/socket.h /usr/src/linux/include/linux/un.h /usr/src/linux/include/linux/fcntl.h \
+ /usr/src/linux/include/linux/termios.h /usr/src/linux/include/asm/system.h /usr/src/linux/include/asm/segment.h \
+ kern_sock.h
diff --git a/net/socket.c b/net/socket.c
index ec3cd35..ffea8a2 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1,13 +1,15 @@
-#include <signal.h>
-#include <errno.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/stat.h>
+#include <linux/socket.h>
+#include <linux/fcntl.h>
+#include <linux/termios.h>
+
#include <asm/system.h>
#include <asm/segment.h>
-#include <sys/socket.h>
-#include <linux/fcntl.h>
-#include <termios.h>
+
#include "kern_sock.h"
#include "socketcall.h"
diff --git a/net/unix.c b/net/unix.c
index 64a5eb6..8e956b5 100644
--- a/net/unix.c
+++ b/net/unix.c
@@ -1,15 +1,17 @@
-#include <signal.h>
-#include <errno.h>
-#include <linux/string.h>
+#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
#include <linux/stat.h>
+#include <linux/socket.h>
+#include <linux/un.h>
+#include <linux/fcntl.h>
+#include <linux/termios.h>
+
#include <asm/system.h>
#include <asm/segment.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <linux/fcntl.h>
-#include <termios.h>
+
#include "kern_sock.h"
static struct unix_proto_data {
@@ -169,7 +171,7 @@ unix_proto_create(struct socket *sock, int protocol)
printk("unix_proto_create: can't allocate buffer\n");
return -ENOMEM;
}
- if (!(upd->buf = (char *)get_free_page())) {
+ if (!(upd->buf = (char *)get_free_page(GFP_USER))) {
printk("unix_proto_create: can't get page!\n");
unix_data_deref(upd);
return -ENOMEM;
diff --git a/tools/build.c b/tools/build.c
index 24ab216..5169ce3 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -1,7 +1,7 @@
/*
* linux/tools/build.c
*
- * (C) 1991 Linus Torvalds
+ * Copyright (C) 1991, 1992 Linus Torvalds
*/
/*
@@ -25,7 +25,7 @@
#include <stdlib.h> /* contains exit */
#include <sys/types.h> /* unistd.h needs this */
#include <sys/stat.h>
-#include <linux/fs.h>
+#include <sys/sysmacros.h>
#include <unistd.h> /* contains read/write */
#include <fcntl.h>
@@ -69,8 +69,8 @@ int main(int argc, char ** argv)
perror(argv[4]);
die("Couldn't stat root device.");
}
- major_root = MAJOR(sb.st_rdev);
- minor_root = MINOR(sb.st_rdev);
+ major_root = major(sb.st_rdev);
+ minor_root = minor(sb.st_rdev);
} else {
major_root = 0;
minor_root = 0;