aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@cc.helsinki.fi>1992-12-13 19:38:12 +0000
committerNicolas Pitre <nico@cam.org>2007-08-19 14:19:10 -0400
commitca87352f20470de289c53a58c877df452e8b982c (patch)
treec88656d2481bffb6c03617ae22910aac6454fa9e
parent3412f7ea7c0414a6191cf5b5d474e8a7f6137fc5 (diff)
downloadarchive-ca87352f20470de289c53a58c877df452e8b982c.tar.gz
[ANNOUNCE]: linux version 0.99v0.99
Linux version 0.99 is now available at nic.funet.fi, in the directory pub/OS/Linux/PEOPLE/Linus as both full source and patches against 0.98.6. It will probably show up on the other major sites soon. NOTE!! The context diffs aren't very good. The makefiles have changed, and due to the new setup they changed radically enough that I couldn't edit away the dependancy changes like I usually do. This means that the diffs are unlikely to patch cleanly, and I'd suggest people get the full source unless you feel comfortable about patching by hand. Also, if you get the full source, I'd suggest you remove (or move elsewhere) all of the old kernel to make sure you don't have any dead files from older versions lying around. 0.99 has no major new features: the NFS client code is now in the standard distribution, and the kernel configuration has changed, but most of the rest of the changes are fixes - especially the tcp code should now be pretty stable (knock wood). Changes: - NFS is in. As are some stubs for the soud drivers, although it's only stubs right now. - various fixes around the place: the serial problems are hopefully gone, and there are patches to both TCP/IP and SCSI to make them more stable. - Minor fixes: the keyboard buglet introduced in 0.98pl6 should be gone, and some other bugs are also corrected. The optimized read-ahead code in the filesystems (and the raw device read code) was too complicated and seemed to have problems with bad blocks, so I rewrote it, and it should hopefully work correctly now (this may have been the reason "mkfs -c" didn't work in all cases). Thanks for some good bug-reports I've gotten: I've tried to correct all the problems I got reports on. - The kernel configuration has been re-thought: I decided to take advantage of the possibilities offered by GNU make etc. This means that you no longer can compile the kernel using any other make, but there probably aren't many (if any) people doing that anyway. This way I got rid of the extremely ugly SCSI setup, so it was probably worth it. To configure the kernel for your setup, do a make config and answer the yes/no questions. After that, do a make dep to make the dependencies match your setup. After that you should still go edit the top-level Makefile for some of the configuration information as before, but the remaining config things are pretty simple. Then you can make the kernel with a simple "make Image". The new configuration utility (essentially a stupid shell script coupled with some smarts in the Makefiles) tries to minimize compilations: if you disable the SCSI code the scsi drivers won't even be compiled, much less linked in. This should be a win on slower machines. NOTE!!! Use LILO-0.7 to load the 0.98pl5 and newer kernels: any older version of lilo is liable to result in weird problems. Linus
-rw-r--r--Configure75
-rw-r--r--Makefile76
-rw-r--r--README63
-rw-r--r--boot/setup.S10
-rw-r--r--config.in77
-rw-r--r--fs/Makefile207
-rw-r--r--fs/block_dev.c142
-rw-r--r--fs/buffer.c2
-rw-r--r--fs/exec.c3
-rw-r--r--fs/ext/Makefile116
-rw-r--r--fs/ext/file.c137
-rw-r--r--fs/filesystems.c24
-rw-r--r--fs/inode.c9
-rw-r--r--fs/isofs/Makefile103
-rw-r--r--fs/isofs/dir.c2
-rw-r--r--fs/isofs/fifo.c27
-rw-r--r--fs/isofs/file.c14
-rw-r--r--fs/isofs/inode.c15
-rw-r--r--fs/isofs/rock.c15
-rw-r--r--fs/minix/Makefile116
-rw-r--r--fs/minix/file.c139
-rw-r--r--fs/msdos/Makefile73
-rw-r--r--fs/namei.c17
-rw-r--r--fs/nfs/Makefile34
-rw-r--r--fs/nfs/blkdev.c62
-rw-r--r--fs/nfs/chrdev.c63
-rw-r--r--fs/nfs/dir.c641
-rw-r--r--fs/nfs/fifo.c27
-rw-r--r--fs/nfs/file.c147
-rw-r--r--fs/nfs/inode.c210
-rw-r--r--fs/nfs/proc.c667
-rw-r--r--fs/nfs/sock.c163
-rw-r--r--fs/nfs/symlink.c110
-rw-r--r--fs/open.c2
-rw-r--r--fs/proc/Makefile85
-rw-r--r--fs/proc/array.c78
-rw-r--r--fs/proc/root.c5
-rw-r--r--include/asm/irq.h2
-rw-r--r--include/linux/autoconf.h33
-rw-r--r--include/linux/config.dist.h35
-rw-r--r--include/linux/config.h54
-rw-r--r--include/linux/config.site.h9
-rw-r--r--include/linux/errno.h2
-rw-r--r--include/linux/fs.h4
-rw-r--r--include/linux/interrupt.h24
-rw-r--r--include/linux/iso_fs.h2
-rw-r--r--include/linux/mouse.h5
-rw-r--r--include/linux/mtio.h12
-rw-r--r--include/linux/nfs.h164
-rw-r--r--include/linux/nfs_fs.h122
-rw-r--r--include/linux/nfs_fs_i.h13
-rw-r--r--include/linux/nfs_fs_sb.h31
-rw-r--r--include/linux/nfs_mount.h48
-rw-r--r--include/linux/sched.h8
-rw-r--r--include/linux/soundcard.h234
-rw-r--r--include/linux/termios.h1
-rw-r--r--include/linux/tty.h4
-rw-r--r--init/main.c6
-rw-r--r--kernel/FPU-emu/Makefile166
-rw-r--r--kernel/FPU-emu/fpu_entry.c6
-rw-r--r--kernel/Makefile151
-rw-r--r--kernel/blk_drv/Makefile67
-rw-r--r--kernel/blk_drv/floppy.c2
-rw-r--r--kernel/blk_drv/hd.c1
-rw-r--r--kernel/blk_drv/ll_rw_blk.c3
-rw-r--r--kernel/blk_drv/scsi/Makefile344
-rw-r--r--kernel/blk_drv/scsi/Makefile.in121
-rw-r--r--kernel/blk_drv/scsi/aha1542.c6
-rw-r--r--kernel/blk_drv/scsi/aha1740.c6
-rw-r--r--kernel/blk_drv/scsi/fdomain.c65
-rw-r--r--kernel/blk_drv/scsi/hosts.c55
-rw-r--r--kernel/blk_drv/scsi/scsi.c19
-rw-r--r--kernel/blk_drv/scsi/scsi.h24
-rw-r--r--kernel/blk_drv/scsi/scsi_ioctl.c18
-rw-r--r--kernel/blk_drv/scsi/sd.c20
-rw-r--r--kernel/blk_drv/scsi/sd_ioctl.c4
-rw-r--r--kernel/blk_drv/scsi/seagate.c16
-rw-r--r--kernel/blk_drv/scsi/sr.c7
-rw-r--r--kernel/blk_drv/scsi/st.c339
-rw-r--r--kernel/blk_drv/scsi/st.h4
-rw-r--r--kernel/blk_drv/scsi/ultrastor.c7
-rw-r--r--kernel/blk_drv/scsi/wd7000.c198
-rw-r--r--kernel/blk_drv/scsi/wd7000.h26
-rw-r--r--kernel/chr_drv/Makefile182
-rw-r--r--kernel/chr_drv/console.c13
-rw-r--r--kernel/chr_drv/mem.c2
-rw-r--r--kernel/chr_drv/mouse.c17
-rw-r--r--kernel/chr_drv/psaux.c2
-rw-r--r--kernel/chr_drv/pty.c4
-rw-r--r--kernel/chr_drv/serial.c303
-rw-r--r--kernel/chr_drv/sound/Makefile44
-rw-r--r--kernel/chr_drv/sound/sound_stub.c15
-rw-r--r--kernel/chr_drv/tty_io.c184
-rw-r--r--kernel/exit.c27
-rw-r--r--kernel/irq.c72
-rw-r--r--kernel/sched.c9
-rw-r--r--kernel/traps.c2
-rw-r--r--lib/Makefile33
-rw-r--r--mm/Makefile45
-rw-r--r--net/Makefile51
-rw-r--r--net/socket.c22
-rw-r--r--net/tcp/Makefile200
-rw-r--r--net/tcp/Space.c16
-rw-r--r--net/tcp/arp.c55
-rw-r--r--net/tcp/arp.h11
-rw-r--r--net/tcp/dev.c328
-rw-r--r--net/tcp/dev.h32
-rw-r--r--net/tcp/eth.c7
-rw-r--r--net/tcp/icmp.c38
-rw-r--r--net/tcp/ip.c47
-rw-r--r--net/tcp/loopback.c13
-rw-r--r--net/tcp/pack_type.c10
-rw-r--r--net/tcp/packet.c15
-rw-r--r--net/tcp/raw.c54
-rw-r--r--net/tcp/sock.c180
-rw-r--r--net/tcp/sock.h24
-rw-r--r--net/tcp/tcp.c921
-rw-r--r--net/tcp/tcp.h43
-rw-r--r--net/tcp/timer.c83
-rw-r--r--net/tcp/udp.c62
-rw-r--r--net/tcp/we.c46
-rw-r--r--net/unix.c15
-rw-r--r--tools/version.h6
123 files changed, 6226 insertions, 3251 deletions
diff --git a/Configure b/Configure
new file mode 100644
index 0000000..4167e59
--- /dev/null
+++ b/Configure
@@ -0,0 +1,75 @@
+#! /bin/sh
+#
+# This script is used to configure the linux kernel.
+# It's a fast hack - feel free to do something better.
+CONFIG=.config
+CONFIG_H=include/linux/autoconf.h
+echo "#" > $CONFIG
+echo "# Automatically generated make config: don't edit" >> $CONFIG
+echo "#" >> $CONFIG
+
+echo "/*" > $CONFIG_H
+echo " * Automatically generated C config: don't edit" >> $CONFIG_H
+echo " */" >> $CONFIG_H
+
+next="y"
+old="y"
+
+while read i
+do
+ echo >> $CONFIG
+ echo >> $CONFIG_H
+ echo
+ echo "#" >> $CONFIG
+ echo "/*" >> $CONFIG_H
+ echo "**"
+ while [ "$i" != "." -a "$i" != ":" ]
+ do
+ echo "# "$i >> $CONFIG
+ echo " * "$i >> $CONFIG_H
+ echo "**" $i
+ read i || break
+ done
+ echo "#" >> $CONFIG
+ echo " */" >> $CONFIG_H
+ echo "**"
+ read i || break
+ while [ "$i" != "." -a "$i" != ":" ]
+ do
+ read j ques def || break
+ if [ "$old" = "n" ]
+ then
+ echo No $i
+ ans="n"
+ else
+ echo -n $i '('$ques', default='$def')? '
+ read ans < /dev/tty
+ if [ "$ans" = "" ]
+ then
+ ans=$def
+ fi
+ fi
+ if [ "$ans" = "y" ]
+ then
+ echo $j = $j >> $CONFIG
+ echo "#define" $j 1 >> $CONFIG_H
+ next="y";
+ fi
+ read i || break
+ done
+ old=$next
+ next="y"
+ if [ "$i" = ":" ]
+ then
+ next="n"
+ fi
+done
+
+echo
+echo "The linux kernel is now hopefully configured for your setup."
+echo "Check the top-level Makefile for additional configuration,"
+echo "and do a 'make dep ; make clean' if you want to be sure all"
+echo "the files are correctly re-made"
+echo
+
+exit 0
diff --git a/Makefile b/Makefile
index 02ac8ad..42d893c 100644
--- a/Makefile
+++ b/Makefile
@@ -1,3 +1,5 @@
+include .config
+
#
# ROOT_DEV specifies the default root-device when making the image.
# This can be either FLOPPY, /dev/xxxx or empty, in which case the
@@ -7,13 +9,6 @@
ROOT_DEV = /dev/hdb1
#
-# uncomment this if you want kernel profiling: the profile_shift is the
-# granularity of the profiling (5 = 32-byte granularity)
-#
-
-PROFILING =# -DPROFILE_SHIFT=2
-
-#
# uncomment the correct keyboard:
#
# The value of KBDFLAGS should be or'ed together from the following
@@ -48,24 +43,6 @@ KEYBOARD = -DKBD_FINNISH -DKBDFLAGS=0
# KEYBOARD = -DKBD_NO -DKBDFLAGS=0
#
-# comment this line if you don't want the emulation-code
-#
-
-MATH_EMULATION = -DKERNEL_MATH_EMULATION
-
-#
-# Comment out this line if you don't want the 16MB kernel limit - but
-# note that some of the SCSI drivers may have problems with anything
-# else due to DMA limits. The drivers should check, but they don't.
-#
-# EVEN IF YOU HAVE > 16MB, YOU SHOULD EDIT THIS ONLY IF YOU ARE 100%
-# SURE YOU AREN'T USING ANY DEVICE THAT DOES UNCHECKED DMA!! THE
-# FLOPPY DRIVER IS OK, BUT OTHERS MIGHT HAVE PROBLEMS.
-#
-
-LIMIT_MEMORY = -DMAX_16M
-
-#
# 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.
@@ -74,11 +51,23 @@ LIMIT_MEMORY = -DMAX_16M
SVGA_MODE= -DSVGA_MODE=1
+#
+# Edit the SOUND_SUPPORT line to suit your setup if you have configured
+# the sound driver to be in the kernel (not really there yet).
+#
+# The DSP_BUFFSIZE defines size of the DMA buffer used for PCM voice I/O.
+# You should use one of the values 4096 (SB), 16384 (SB Pro), 32768 (PAS+)
+# or 65536 (PAS16). The SBC_IRQ defines the IRQ line used by SoundBlaster and
+# the PAS_IRQ is the IRQ number for ProAudioSpectrum.
+# NOTE! The ProAudioSpectrum support is not available yet.
+
+SOUND_SUPPORT = -DKERNEL_SOUNDCARD -DDSP_BUFFSIZE=16384 -DSBC_IRQ=7 -DPAS_IRQ=5
+
#
# standard CFLAGS
#
-CFLAGS = -Wall -O6 -fomit-frame-pointer $(LIMIT_MEMORY)
+CFLAGS = -Wall -O6 -fomit-frame-pointer
#
# if you want the ram-disk device, define this to be the
@@ -95,13 +84,13 @@ LD =ld
HOSTCC =gcc
CC =gcc -DKERNEL
MAKE =make
-CPP =$(CC) -E $(LIMIT_MEMORY)
+CPP =$(CC) -E
AR =ar
ARCHIVES =kernel/kernel.o mm/mm.o fs/fs.o net/net.o
FILESYSTEMS =fs/filesystems.a
DRIVERS =kernel/blk_drv/blk_drv.a kernel/chr_drv/chr_drv.a \
- kernel/blk_drv/scsi/scsi.a
+ kernel/blk_drv/scsi/scsi.a kernel/chr_drv/sound/sound.a
MATH =kernel/FPU-emu/math.a
LIBS =lib/lib.a
SUBDIRS =kernel mm fs net lib
@@ -122,12 +111,15 @@ lilo: Image
cat Image > /vmlinux
/etc/lilo/install
+config:
+ sh Configure < config.in
+
linuxsubdirs: dummy
@for i in $(SUBDIRS); do (cd $$i && echo $$i && $(MAKE)) || exit; done
Version:
@./makever.sh
- @echo \#define UTS_RELEASE \"0.98.pl6-`cat .version`\" > tools/version.h
+ @echo \#define UTS_RELEASE \"0.99-`cat .version`\" > tools/version.h
@echo \#define UTS_VERSION \"`date +%D`\" >> tools/version.h
@echo \#define LINUX_COMPILE_TIME \"`date +%T`\" >> tools/version.h
@echo \#define LINUX_COMPILE_BY \"`whoami`\" >> tools/version.h
@@ -190,7 +182,7 @@ kernel: dummy
$(MAKE) linuxsubdirs SUBDIRS=kernel
clean:
- rm -f Image System.map tmp_make core boot/bootsect boot/setup \
+ rm -f Image System.map core boot/bootsect boot/setup \
boot/bootsect.s boot/setup.s boot/head.s init/main.s
rm -f init/*.o tools/system tools/build boot/*.o tools/*.o
for i in $(SUBDIRS); do (cd $$i && $(MAKE) clean); done
@@ -200,24 +192,14 @@ backup: clean
sync
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 init/*.c;do echo -n "init/";$(CPP) -M $$i;done > .depend
for i in $(SUBDIRS); do (cd $$i && $(MAKE) dep) || exit; done
dummy:
-### Dependencies:
-init/main.o : init/main.c /usr/lib/gcc-lib/i386-linux/2.3.2/include/stdarg.h /usr/include/asm/system.h \
- /usr/include/asm/io.h /usr/include/linux/mktime.h /usr/include/linux/types.h \
- /usr/include/linux/fcntl.h /usr/include/linux/config.h /usr/include/linux/config.dist.h \
- /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/dirent.h \
- /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
- /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
- /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
- /usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/linux/unistd.h \
- /usr/include/linux/string.h
+#
+# include a dependency file if one exists
+#
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
diff --git a/README b/README
index 0e85e71..8543657 100644
--- a/README
+++ b/README
@@ -29,16 +29,8 @@ toplevel kernel source directory.
* Basic configuration
1. Edit Makefile: Check the definitions of macros ROOTDEV, KEYBOARD,
-MATH_EMULATION, RAMDISK and SVGA_MODE before you run make. They are
-explained in the Makefile. MATH_EMULATION does not hurt much even if
-you have an FPU (387 or a 486 with a built in FPU), since Linux uses
-the FPU if it finds one, even with MATH_EMULATION defined. The kernel
-will be slightly bigger. It is probably not worth it to recompile the
-kernel just to get rid of the emulation.
-
-[ Linus' note: the new math-emulator in 0.98.2 is much better than my
- old one, but it also takes up more memory. You may want to remove it
- if you are short on memory and long on math-coprocessors ]
+RAMDISK and SVGA_MODE before you run make. They are explained in the
+Makefile.
2. Create the symlinks:
@@ -53,54 +45,19 @@ get some system-specific information.
installation script, so if you have the new compiler, you should
already have these links ]
-* Things you may want to get rid of
-
-3. To remove SCSI drivers, do this:
-
- - remove kernel/blk_drv/scsi/scsi.a from DRIVERS in the Makefile
- - remove the commands for the subdirs dependency in
- kernel/blk_drv/Makefile
- - add "#undef CONFIG_SCSI" to the end of include/linux/config.h
-
-The SCSI drivers take a bit of memory, and also slow the bootup a bit,
-so you may want to get rid of them if you don't have an SCSI drive.
-
-4. The kernel contains code for the extended filesystem (extfs),
-MS-DOS filesystem (dosfs) and proc-fs (proc), all of which are in
-testing phases and are not recommended for real use yet. If you don't
-want to include these in the kernel, do the following:
-
- - remove references to these in the FILESYSTEMS macro in the
- root Makefile
- - remove directory names from the SUBDIRS macro in fs/Makefile
- - remove the corresponding lines in the initialization of
- file_systems in fs/super.c.
-
-5. The TCP/IP code is in the standard sources as of version 0.98, but
-it is not compiled into the normal binary. To get TCP/IP working, you
-have to:
-
- - edit 'net/Makefile', defining the SUBDIRS and SOCK_FLAGS
- variables correctly (currently commented out). Likewise, you
- have to edit the rule for linking net.o in the Makefile (again
- removing a '#' to make tcp/tcpip.o active)
- - make sure you have the /usr/include/netinet/protocols.h header
- file. If you don't have it, you should be able to find it at
- the same place you got the kernel, or with a newer compiler
- version.
- - remove all object (*.o) files in the net/ subdirectory, making
- sure that they are recompiled with the correct Makefile
- definitions.
- - Additionally, you obviously need the tcp/ip programs to make any
- use of the kernel feature. If you haven't joined the TCP/IP
- mailing list, do so.
+3. Run "make config" in /usr/src/linux, and answer the questions that
+the config script asks you. It should hopefully set up most of the rest
+of the flags for your system.
+4. Run "make dep" to set up all the dependencies correctly. The
+default dependencies may not fit your system due to different compiler
+versions or similar.
* Running make
[ Linus' note3: if you have problems with make not working correctly,
- get a new copy of GNU make. pmake may or may not work due to the
- macro inheritation assumptions etc ]
+ get a new copy of GNU make. The linux kernel makefiles are written
+ for GNU make and will not work for anything else ]
Unless you know what you're doing, don't ever run the makefiles in
subdirectories by hand. There is a bit of interaction between the
diff --git a/boot/setup.S b/boot/setup.S
index e3df8f8..194ca1b 100644
--- a/boot/setup.S
+++ b/boot/setup.S
@@ -233,17 +233,25 @@ end_move:
jmpi 0,8 ! jmp offset 0 of segment 8 (cs)
! This routine checks that the keyboard command queue is empty
+! (after emptying the output buffers)
+!
! No timeout is used - if this hangs there is something wrong with
! the machine, and we probably couldn't proceed anyway.
empty_8042:
.word 0x00eb,0x00eb
in al,#0x64 ! 8042 status port
+ test al,#1 ! output buffer?
+ jz no_output
+ .word 0x00eb,0x00eb
+ in al,#0x60 ! read it
+ jmp empty_8042
+no_output:
test al,#2 ! is input buffer full?
jnz empty_8042 ! yes - loop
ret
getkey:
- in al,#0x60 ! Quick and dirty...
+ in al,#0x60 ! Quick and dirty...
.word 0x00eb,0x00eb ! jmp $+2, jmp $+2
mov bl,al
in al,#0x61
diff --git a/config.in b/config.in
new file mode 100644
index 0000000..f81aca0
--- /dev/null
+++ b/config.in
@@ -0,0 +1,77 @@
+General setup
+.
+Kernel math emulation
+CONFIG_MATH_EMULATION y/n n
+Normal harddisk support
+CONFIG_BLK_DEV_HD y/n y
+TCP/IP
+CONFIG_TCPIP y/n y
+Kernel profiling support
+CONFIG_PROFILE y/n n
+Limit to memory to low 16MB
+CONFIG_MAX_16M y/n y
+:
+SCSI support
+.
+SCSI support?
+CONFIG_SCSI y/n n
+:
+SCSI support type (disk, tape, CDrom)
+.
+Scsi disk support
+CONFIG_BLK_DEV_SD y/n y
+Scsi tape support
+CONFIG_BLK_DEV_ST y/n y
+Scsi CDROM support
+CONFIG_BLK_DEV_SR y/n y
+.
+SCSI low-level drivers
+.
+Adaptek AHA1542 support
+CONFIG_SCSI_AHA1542 y/n y
+Adaptek AHA1740 support
+CONFIG_SCSI_AHA1740 y/n y
+Always IN support
+CONFIG_SCSI_ALWAYS y/n y
+Future Domain SCSI support
+CONFIG_SCSI_FUTURE_DOMAIN y/n y
+Seagate ST-02 SCSI support
+CONFIG_SCSI_SEAGATE y/n y
+UltraStor SCSI support
+CONFIG_SCSI_ULTRASTOR y/n y
+7000FASST SCSI support
+CONFIG_SCSI_7000FASST y/n y
+.
+Filesystems
+.
+Standard (minix) fs support
+CONFIG_MINIX_FS y/n y
+Extended fs support
+CONFIG_EXT_FS y/n n
+msdos fs support
+CONFIG_MSDOS_FS y/n n
+/proc filesystem support
+CONFIG_PROC_FS y/n y
+NFS filesystem support
+CONFIG_NFS_FS y/n n
+ISO9660 cdrom filesystem support
+CONFIG_ISO9660_FS y/n n
+.
+Various character device drivers..
+.
+Autoconfigure serial IRQ lines at bootup
+CONFIG_AUTOIRQ y/n n
+AST Fourport serial driver support
+CONFIG_AST_FOURPORT y/n n
+Accent Async 4 serial support
+CONFIG_ACCENT_ASYNC y/n n
+Logitech busmouse support
+CONFIG_BUSMOUSE y/n n
+PS/2 mouse (aka 'auxilliary device') support
+CONFIG_PSMOUSE y/n n
+MicroSoft busmouse support
+CONFIG_MS_BUSMOUSE y/n n
+ATIXL busmouse support
+CONFIG_ATIXL_BUSMOUSE y/n n
+Soundcard support (not really there yet)
+CONFIG_SOUND y/n n
diff --git a/fs/Makefile b/fs/Makefile
index 0f97234..3d93208 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -7,7 +7,26 @@
#
# Note 2! The CFLAGS definitions are now in the main makefile...
-SUBDIRS = minix ext msdos proc isofs
+SUBDIRS = minix ext msdos proc isofs nfs
+
+ifdef CONFIG_MINIX_FS
+FS_SUBDIRS := $(FS_SUBDIRS) minix
+endif
+ifdef CONFIG_EXT_FS
+FS_SUBDIRS := $(FS_SUBDIRS) ext
+endif
+ifdef CONFIG_MSDOS_FS
+FS_SUBDIRS := $(FS_SUBDIRS) msdos
+endif
+ifdef CONFIG_PROC_FS
+FS_SUBDIRS := $(FS_SUBDIRS) proc
+endif
+ifdef CONFIG_ISO9660_FS
+FS_SUBDIRS := $(FS_SUBDIRS) isofs
+endif
+ifdef CONFIG_NFS_FS
+FS_SUBDIRS := $(FS_SUBDIRS) nfs
+endif
.c.s:
$(CC) $(CFLAGS) -S $<
@@ -27,191 +46,23 @@ fs.o: $(OBJS)
filesystems.a: dummy
rm -f filesystems.a
- @for i in $(SUBDIRS); do [ ! -d $$i ] || \
+ @for i in $(FS_SUBDIRS); do [ ! -d $$i ] || \
(cd $$i && echo $$i && $(MAKE) && $(AR) rcs ../filesystems.a $$i.o) \
|| exit; done
clean:
- rm -f core *.o *.a tmp_make
- for i in *.c; do rm -f `basename $$i .c`.s;done
+ rm -f core *.s *.o *.a
for i in $(SUBDIRS); do ([ -d $$i ] && cd $$i && $(MAKE) clean); done
depend dep:
- sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
- $(CPP) -M *.c >> tmp_make
- cp tmp_make Makefile
+ $(CPP) -M *.c > .depend
for i in $(SUBDIRS); do [ ! -d $$i ] || (cd $$i && $(MAKE) dep) || exit; done
dummy:
-### Dependencies:
-block_dev.o : block_dev.c /usr/include/linux/errno.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
- /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
- /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
- /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
- /usr/include/linux/locks.h /usr/include/asm/segment.h /usr/include/asm/system.h
-buffer.o : buffer.c /usr/lib/gcc-lib/i386-linux/2.3.2/include/stdarg.h /usr/include/linux/config.h \
- /usr/include/linux/config.dist.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/string.h \
- /usr/include/linux/locks.h /usr/include/asm/system.h /usr/include/asm/io.h
-exec.o : exec.c /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/a.out.h /usr/include/linux/errno.h \
- /usr/include/linux/string.h /usr/include/linux/stat.h /usr/include/linux/fcntl.h \
- /usr/include/linux/ptrace.h /usr/include/linux/user.h /usr/include/asm/segment.h
-fcntl.o : fcntl.c /usr/include/asm/segment.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/errno.h \
- /usr/include/linux/stat.h /usr/include/linux/fcntl.h /usr/include/linux/string.h
-fifo.o : fifo.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/errno.h /usr/include/linux/fcntl.h
-file_table.o : file_table.c /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
- /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/string.h
-filesystems.o : filesystems.c /usr/include/linux/config.h /usr/include/linux/config.dist.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/minix_fs.h /usr/include/linux/proc_fs.h /usr/include/linux/ext_fs.h \
- /usr/include/linux/msdos_fs.h
-inode.o : inode.c /usr/include/linux/stat.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/string.h \
- /usr/include/asm/system.h
-ioctl.o : ioctl.c /usr/include/asm/segment.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/errno.h \
- /usr/include/linux/string.h /usr/include/linux/stat.h /usr/include/linux/termios.h \
- /usr/include/linux/fcntl.h
-locks.o : locks.c /usr/include/asm/segment.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/errno.h \
- /usr/include/linux/stat.h /usr/include/linux/fcntl.h
-namei.o : namei.c /usr/include/asm/segment.h /usr/include/linux/errno.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
- /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
- /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
- /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
- /usr/include/linux/string.h /usr/include/linux/fcntl.h /usr/include/linux/stat.h
-open.o : open.c /usr/include/linux/vfs.h /usr/include/linux/types.h /usr/include/linux/utime.h \
- /usr/include/linux/errno.h /usr/include/linux/fcntl.h /usr/include/linux/stat.h \
- /usr/include/linux/string.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/dirent.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
- /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
- /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
- /usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/asm/system.h \
- /usr/include/asm/segment.h
-pipe.o : pipe.c /usr/include/asm/segment.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/errno.h \
- /usr/include/linux/fcntl.h /usr/include/linux/termios.h
-read_write.o : read_write.c /usr/include/linux/types.h /usr/include/linux/errno.h \
- /usr/include/linux/stat.h /usr/include/linux/kernel.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/minix_fs.h /usr/include/asm/segment.h
-select.o : select.c /usr/include/linux/types.h /usr/include/linux/time.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/dirent.h \
- /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/kernel.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/mm.h /usr/include/linux/signal.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/string.h /usr/include/linux/stat.h \
- /usr/include/linux/errno.h /usr/include/asm/segment.h /usr/include/asm/system.h
-stat.o : stat.c /usr/include/linux/errno.h /usr/include/linux/stat.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
- /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
- /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
- /usr/include/asm/segment.h
-super.o : super.c /usr/include/linux/config.h /usr/include/linux/config.dist.h \
- /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/stat.h /usr/include/linux/errno.h \
- /usr/include/linux/string.h /usr/include/linux/locks.h /usr/include/asm/system.h \
- /usr/include/asm/segment.h
+#
+# include a dependency file if one exists
+#
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 8b57a6e..def02f6 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -59,42 +59,46 @@ int block_write(struct inode * inode, struct file * filp, char * buf, int count)
#define NBUF 16
-
int block_read(struct inode * inode, struct file * filp, char * buf, int count)
{
- unsigned int block = filp->f_pos >> BLOCK_SIZE_BITS;
- unsigned int offset = filp->f_pos & (BLOCK_SIZE-1);
+ unsigned int block;
+ unsigned int offset;
int blocks, left;
- int bhrequest;
- int ra_blocks, max_block, nextblock;
+ int bhrequest, uptodate;
struct buffer_head ** bhb, ** bhe;
struct buffer_head * buflist[NBUF];
struct buffer_head * bhreq[NBUF];
unsigned int chars;
unsigned int size;
unsigned int dev;
- int read = 0;
+ int read;
dev = inode->i_rdev;
+ offset = filp->f_pos;
if (blk_size[MAJOR(dev)])
size = blk_size[MAJOR(dev)][MINOR(dev)] << BLOCK_SIZE_BITS;
else
size = 0x7fffffff;
- if (filp->f_pos > size)
+ if (offset > size)
left = 0;
else
- left = size - filp->f_pos;
+ left = size - offset;
if (left > count)
left = count;
if (left <= 0)
return 0;
-
- blocks = (left + offset + BLOCK_SIZE - 1) / BLOCK_SIZE;
+ read = 0;
+ block = offset >> BLOCK_SIZE_BITS;
+ offset &= BLOCK_SIZE-1;
+ size >>= BLOCK_SIZE_BITS;
+ blocks = (left + offset + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS;
bhb = bhe = buflist;
- ra_blocks = read_ahead[MAJOR(dev)] / (BLOCK_SIZE >> 9);
- max_block = size;
- nextblock = -1;
+ if (filp->f_reada) {
+ blocks += read_ahead[MAJOR(dev)] / (BLOCK_SIZE >> 9);
+ if (block + blocks > size)
+ blocks = size - block;
+ }
/* We do this in a two stage process. We first try and request
as many blocks as we can, then we wait for the first one to
@@ -108,103 +112,67 @@ int block_read(struct inode * inode, struct file * filp, char * buf, int count)
do {
bhrequest = 0;
+ uptodate = 1;
while (blocks) {
- int uptodate;
--blocks;
*bhb = getblk(dev, block++, BLOCK_SIZE);
- uptodate = 1;
if (*bhb && !(*bhb)->b_uptodate) {
uptodate = 0;
bhreq[bhrequest++] = *bhb;
- nextblock = (*bhb)->b_blocknr + 1;
- };
+ }
if (++bhb == &buflist[NBUF])
bhb = buflist;
/* If the block we have on hand is uptodate, go ahead
and complete processing. */
- if(bhrequest == 0 && uptodate) break;
-
+ if (uptodate)
+ break;
if (bhb == bhe)
break;
- }
-
- if(blocks == 0 && bhrequest && filp->f_reada && bhb != bhe) {
- /* If we are going to read something anyways, add in the
- read-ahead blocks */
- while(ra_blocks){
- if (block >= max_block) break;
- if(bhrequest == NBUF) break; /* Block full */
- --ra_blocks;
- *bhb = getblk(dev, block++, BLOCK_SIZE);
-
- if (*bhb && !(*bhb)->b_uptodate) {
- if((*bhb)->b_blocknr != nextblock) {
- brelse(*bhb);
- break;
- };
- nextblock = (*bhb)->b_blocknr + 1;
- bhreq[bhrequest++] = *bhb;
- };
-
- if (++bhb == &buflist[NBUF])
- bhb = buflist;
-
- if (bhb == bhe)
- break;
- };
- };
+ }
+
/* Now request them all */
if (bhrequest)
- ll_rw_block(READ, bhrequest, bhreq);
-
- do{ /* Finish off all I/O that has actually completed */
- if (*bhe) {/* test for valid buffer */
- wait_on_buffer(*bhe);
- if (!(*bhe)->b_uptodate) {
- do {
- brelse(*bhe);
+ ll_rw_block(READ, bhrequest, bhreq);
+
+ do { /* Finish off all I/O that has actually completed */
+ if (*bhe) {
+ wait_on_buffer(*bhe);
+ if (!(*bhe)->b_uptodate) { /* read error? */
+ left = 0;
+ break;
+ }
+ }
+ if (left < BLOCK_SIZE - offset)
+ chars = left;
+ else
+ chars = BLOCK_SIZE - offset;
+ filp->f_pos += chars;
+ left -= chars;
+ read += chars;
+ if (*bhe) {
+ memcpy_tofs(buf,offset+(*bhe)->b_data,chars);
+ brelse(*bhe);
+ buf += chars;
+ } else {
+ while (chars-->0)
+ put_fs_byte(0,buf++);
+ }
+ offset = 0;
if (++bhe == &buflist[NBUF])
- bhe = buflist;
- } while (bhe != bhb);
- break;
- }
- }
-
- if (left < BLOCK_SIZE - offset)
- chars = left;
- else
- chars = BLOCK_SIZE - offset;
- filp->f_pos += chars;
- left -= chars;
- read += chars;
- if (*bhe) {
- memcpy_tofs(buf,offset+(*bhe)->b_data,chars);
- brelse(*bhe);
- buf += chars;
- } else {
- while (chars-->0)
- put_fs_byte(0,buf++);
- }
- offset = 0;
- if (++bhe == &buflist[NBUF])
- bhe = buflist;
- } while( bhe != bhb && (*bhe == 0 || !(*bhe)->b_lock) &&
- (left > 0));
+ bhe = buflist;
+ } while (left > 0 && bhe != bhb && (!*bhe || !(*bhe)->b_lock));
} while (left > 0);
/* Release the read-ahead blocks */
while (bhe != bhb) {
- if (*bhe) brelse(*bhe);
- if (++bhe == &buflist[NBUF])
- bhe = buflist;
+ brelse(*bhe);
+ if (++bhe == &buflist[NBUF])
+ bhe = buflist;
};
-
- filp->f_reada = 1;
-
if (!read)
return -EIO;
-
+ filp->f_reada = 1;
return read;
}
diff --git a/fs/buffer.c b/fs/buffer.c
index 009a5a1..6561bb0 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -314,7 +314,7 @@ repeat:
return bh;
}
- if (nr_free_pages > 30)
+ if (nr_free_pages > 30 && buffermem < 6*1024*1024)
grow_buffers(size);
buffers = nr_buffers;
diff --git a/fs/exec.c b/fs/exec.c
index fd4f589..62ea594 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -243,16 +243,19 @@ static unsigned long * create_tables(char * p,int argc,int envc)
put_fs_long((unsigned long)envp,--sp);
put_fs_long((unsigned long)argv,--sp);
put_fs_long((unsigned long)argc,--sp);
+ current->arg_start = (unsigned long) p;
while (argc-->0) {
put_fs_long((unsigned long) p,argv++);
while (get_fs_byte(p++)) /* nothing */ ;
}
put_fs_long(0,argv);
+ current->arg_end = current->env_start = (unsigned long) p;
while (envc-->0) {
put_fs_long((unsigned long) p,envp++);
while (get_fs_byte(p++)) /* nothing */ ;
}
put_fs_long(0,envp);
+ current->env_end = (unsigned long) p;
return sp;
}
diff --git a/fs/ext/Makefile b/fs/ext/Makefile
index 69ca71d..205c05f 100644
--- a/fs/ext/Makefile
+++ b/fs/ext/Makefile
@@ -21,114 +21,14 @@ ext.o: $(OBJS)
$(LD) -r -o ext.o $(OBJS)
clean:
- rm -f core *.o *.a tmp_make
- for i in *.c;do rm -f `basename $$i .c`.s;done
+ rm -f core *.s *.o *.a
dep:
- sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
- $(CPP) -M *.c >> tmp_make
- cp tmp_make Makefile
+ $(CPP) -M *.c > .depend
-### Dependencies:
-blkdev.o : blkdev.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/ext_fs.h /usr/include/linux/tty.h \
- /usr/include/linux/termios.h /usr/include/asm/system.h /usr/include/linux/stat.h \
- /usr/include/linux/fcntl.h /usr/include/linux/errno.h
-chrdev.o : chrdev.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/ext_fs.h /usr/include/linux/tty.h \
- /usr/include/linux/termios.h /usr/include/asm/system.h /usr/include/linux/stat.h \
- /usr/include/linux/fcntl.h /usr/include/linux/errno.h
-dir.o : dir.c /usr/include/asm/segment.h /usr/include/linux/errno.h /usr/include/linux/kernel.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/ext_fs.h /usr/include/linux/stat.h
-fifo.o : fifo.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/ext_fs.h
-file.o : file.c /usr/include/asm/segment.h /usr/include/asm/system.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
- /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
- /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
- /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
- /usr/include/linux/ext_fs.h /usr/include/linux/errno.h /usr/include/linux/fcntl.h \
- /usr/include/linux/stat.h /usr/include/linux/locks.h
-freelists.o : freelists.c /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/ext_fs.h \
- /usr/include/linux/stat.h /usr/include/linux/string.h /usr/include/linux/locks.h
-inode.o : inode.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/ext_fs.h /usr/include/linux/string.h \
- /usr/include/linux/stat.h /usr/include/linux/locks.h /usr/include/asm/system.h \
- /usr/include/asm/segment.h
-namei.o : namei.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/ext_fs.h /usr/include/linux/string.h \
- /usr/include/linux/stat.h /usr/include/linux/fcntl.h /usr/include/linux/errno.h \
- /usr/include/asm/segment.h
-symlink.o : symlink.c /usr/include/asm/segment.h /usr/include/linux/errno.h \
- /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/ext_fs.h /usr/include/linux/stat.h
-truncate.o : truncate.c /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/ext_fs.h \
- /usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/asm/system.h \
- /usr/include/linux/stat.h /usr/include/linux/fcntl.h /usr/include/linux/errno.h
+#
+# include a dependency file if one exists
+#
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
diff --git a/fs/ext/file.c b/fs/ext/file.c
index e8684d5..bb70d50 100644
--- a/fs/ext/file.c
+++ b/fs/ext/file.c
@@ -71,37 +71,41 @@ static int ext_file_read(struct inode * inode, struct file * filp, char * buf, i
{
int read,left,chars;
int block, blocks, offset;
- int bhrequest;
- int ra_blocks, max_block, nextblock;
+ int bhrequest, uptodate;
struct buffer_head ** bhb, ** bhe;
struct buffer_head * bhreq[NBUF];
struct buffer_head * buflist[NBUF];
+ unsigned int size;
if (!inode) {
printk("ext_file_read: inode = NULL\n");
return -EINVAL;
}
- if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
+ if (!S_ISREG(inode->i_mode)) {
printk("ext_file_read: mode = %07o\n",inode->i_mode);
return -EINVAL;
}
- if (filp->f_pos > inode->i_size)
+ offset = filp->f_pos;
+ size = inode->i_size;
+ if (offset > size)
left = 0;
else
- left = inode->i_size - filp->f_pos;
+ left = size - offset;
if (left > count)
left = count;
if (left <= 0)
return 0;
read = 0;
- block = filp->f_pos >> BLOCK_SIZE_BITS;
- offset = filp->f_pos & (BLOCK_SIZE-1);
- blocks = (left + offset + BLOCK_SIZE - 1) / BLOCK_SIZE;
+ block = offset >> BLOCK_SIZE_BITS;
+ offset &= BLOCK_SIZE-1;
+ size = (size + (BLOCK_SIZE-1)) >> BLOCK_SIZE_BITS;
+ blocks = (left + offset + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS;
bhb = bhe = buflist;
-
- ra_blocks = read_ahead[MAJOR(inode->i_dev)] / (BLOCK_SIZE >> 9);
- max_block = (inode->i_size + BLOCK_SIZE - 1)/BLOCK_SIZE;
- nextblock = -1;
+ if (filp->f_reada) {
+ blocks += read_ahead[MAJOR(inode->i_dev)] / (BLOCK_SIZE >> 9);
+ if (block + blocks > size)
+ blocks = size - block;
+ }
/* We do this in a two stage process. We first try and request
as many blocks as we can, then we wait for the first one to
@@ -115,103 +119,68 @@ static int ext_file_read(struct inode * inode, struct file * filp, char * buf, i
do {
bhrequest = 0;
+ uptodate = 1;
while (blocks) {
- int uptodate;
--blocks;
*bhb = ext_getblk(inode, block++, 0);
- uptodate = 1;
if (*bhb && !(*bhb)->b_uptodate) {
uptodate = 0;
bhreq[bhrequest++] = *bhb;
- nextblock = (*bhb)->b_blocknr + 1;
- };
+ }
if (++bhb == &buflist[NBUF])
bhb = buflist;
/* If the block we have on hand is uptodate, go ahead
and complete processing. */
- if(bhrequest == 0 && uptodate) break;
-
+ if (uptodate)
+ break;
if (bhb == bhe)
break;
- }
-
- if(blocks == 0 && bhrequest && filp->f_reada && bhb != bhe) {
- /* If we are going to read something anyways, add in the
- read-ahead blocks */
- while(ra_blocks){
- if (block >= max_block) break;
- if(bhrequest == NBUF) break; /* Block full */
- --ra_blocks;
- *bhb = ext_getblk(inode, block++, 0);
+ }
- if (*bhb && !(*bhb)->b_uptodate) {
- if((*bhb)->b_blocknr != nextblock) {
- brelse(*bhb);
- break;
- };
- nextblock = (*bhb)->b_blocknr + 1;
- bhreq[bhrequest++] = *bhb;
- };
-
- if (++bhb == &buflist[NBUF])
- bhb = buflist;
-
- if (bhb == bhe)
- break;
- };
- };
/* Now request them all */
if (bhrequest)
- ll_rw_block(READ, bhrequest, bhreq);
-
- do{ /* Finish off all I/O that has actually completed */
- if (*bhe) {/* test for valid buffer */
- wait_on_buffer(*bhe);
- if (!(*bhe)->b_uptodate) {
- do {
- brelse(*bhe);
+ ll_rw_block(READ, bhrequest, bhreq);
+
+ do { /* Finish off all I/O that has actually completed */
+ if (*bhe) {
+ wait_on_buffer(*bhe);
+ if (!(*bhe)->b_uptodate) { /* read error? */
+ left = 0;
+ break;
+ }
+ }
+ if (left < BLOCK_SIZE - offset)
+ chars = left;
+ else
+ chars = BLOCK_SIZE - offset;
+ filp->f_pos += chars;
+ left -= chars;
+ read += chars;
+ if (*bhe) {
+ memcpy_tofs(buf,offset+(*bhe)->b_data,chars);
+ brelse(*bhe);
+ buf += chars;
+ } else {
+ while (chars-->0)
+ put_fs_byte(0,buf++);
+ }
+ offset = 0;
if (++bhe == &buflist[NBUF])
- bhe = buflist;
- } while (bhe != bhb);
- break;
- }
- }
-
- if (left < BLOCK_SIZE - offset)
- chars = left;
- else
- chars = BLOCK_SIZE - offset;
- filp->f_pos += chars;
- left -= chars;
- read += chars;
- if (*bhe) {
- memcpy_tofs(buf,offset+(*bhe)->b_data,chars);
- brelse(*bhe);
- buf += chars;
- } else {
- while (chars-->0)
- put_fs_byte(0,buf++);
- }
- offset = 0;
- if (++bhe == &buflist[NBUF])
- bhe = buflist;
- } while( bhe != bhb && (*bhe == 0 || !(*bhe)->b_lock) &&
- (left > 0));
+ bhe = buflist;
+ } while (left > 0 && bhe != bhb && (!*bhe || !(*bhe)->b_lock));
} while (left > 0);
/* Release the read-ahead blocks */
while (bhe != bhb) {
- if (*bhe) brelse(*bhe);
- if (++bhe == &buflist[NBUF])
- bhe = buflist;
+ brelse(*bhe);
+ if (++bhe == &buflist[NBUF])
+ bhe = buflist;
};
-
- filp->f_reada = 1;
-
if (!read)
return -EIO;
+ filp->f_reada = 1;
if (!IS_RDONLY(inode)) {
inode->i_atime = CURRENT_TIME;
inode->i_dirt = 1;
diff --git a/fs/filesystems.c b/fs/filesystems.c
index c19c4d6..3891f53 100644
--- a/fs/filesystems.c
+++ b/fs/filesystems.c
@@ -8,42 +8,42 @@
#include <linux/config.h>
#include <linux/fs.h>
-#ifdef MINIX_FS
+#ifdef CONFIG_MINIX_FS
#include <linux/minix_fs.h>
#endif
-#ifdef PROC_FS
+#ifdef CONFIG_PROC_FS
#include <linux/proc_fs.h>
#endif
-#ifdef EXT_FS
+#ifdef CONFIG_EXT_FS
#include <linux/ext_fs.h>
#endif
-#ifdef MSDOS_FS
+#ifdef CONFIG_MSDOS_FS
#include <linux/msdos_fs.h>
#endif
-#ifdef NFS_FS
+#ifdef CONFIG_NFS_FS
#include <linux/nfs_fs.h>
#endif
-#ifdef ISO9660_FS
+#ifdef CONFIG_ISO9660_FS
#include <linux/iso_fs.h>
#endif
struct file_system_type file_systems[] = {
-#ifdef MINIX_FS
+#ifdef CONFIG_MINIX_FS
{minix_read_super, "minix", 1},
#endif
-#ifdef EXT_FS
+#ifdef CONFIG_EXT_FS
{ext_read_super, "ext", 1},
#endif
-#ifdef MSDOS_FS
+#ifdef CONFIG_MSDOS_FS
{msdos_read_super, "msdos", 1},
#endif
-#ifdef PROC_FS
+#ifdef CONFIG_PROC_FS
{proc_read_super, "proc", 0},
#endif
-#ifdef NFS_FS
+#ifdef CONFIG_NFS_FS
{nfs_read_super, "nfs", 0},
#endif
-#ifdef ISO9660_FS
+#ifdef CONFIG_ISO9660_FS
{isofs_read_super, "iso9660", 1},
#endif
{NULL, NULL, 0}
diff --git a/fs/inode.c b/fs/inode.c
index 78a3907..d1eb15e 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -14,6 +14,7 @@
static struct inode inode_table[NR_INODE];
static struct inode * last_inode = inode_table;
+static struct wait_queue * inode_wait;
void inode_init(void)
{
@@ -196,6 +197,7 @@ repeat:
inode->i_count--;
return;
}
+ wake_up(&inode_wait);
if (inode->i_pipe) {
unsigned long page = (unsigned long) PIPE_BASE(*inode);
PIPE_BASE(*inode) = NULL;
@@ -232,10 +234,9 @@ repeat:
}
}
if (!inode) {
- for (i=0 ; i<NR_INODE ; i++)
- printk("(%04x: %d (%o)) ",inode_table[i].i_dev,
- inode_table[i].i_ino,inode_table[i].i_mode);
- panic("No free inodes in mem");
+ printk("No free inodes - contact Linus\n");
+ sleep_on(&inode_wait);
+ goto repeat;
}
if (inode->i_lock) {
wait_on_inode(inode);
diff --git a/fs/isofs/Makefile b/fs/isofs/Makefile
index 0c51e9e..06fffff 100644
--- a/fs/isofs/Makefile
+++ b/fs/isofs/Makefile
@@ -14,104 +14,21 @@
.s.o:
$(AS) -o $*.o $<
-OBJS= namei.o inode.o file.o dir.o util.o rock.o symlink.o blkdev.o chrdev.o
+OBJS= namei.o inode.o file.o dir.o util.o rock.o symlink.o \
+ fifo.o blkdev.o chrdev.o
isofs.o: $(OBJS)
$(LD) -r -o isofs.o $(OBJS)
clean:
- rm -f core *.o *.a tmp_make
- for i in *.c;do rm -f `basename $$i .c`.s;done
+ rm -f core *.o *.a *.s
dep:
- sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
- for i in *.c;do $(CPP) -M $$i;done >> tmp_make
- cp tmp_make Makefile
+ $(CPP) -M *.c > .depend
-### Dependencies:
-blkdev.o : blkdev.c /usr/include/linux/errno.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/iso_fs.h \
- /usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/asm/system.h \
- /usr/include/linux/stat.h /usr/include/linux/fcntl.h
-chrdev.o : chrdev.c /usr/include/linux/errno.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/iso_fs.h \
- /usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/asm/system.h \
- /usr/include/linux/stat.h /usr/include/linux/fcntl.h
-dir.o : dir.c /usr/include/linux/errno.h /usr/include/asm/segment.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/iso_fs.h \
- /usr/include/linux/kernel.h /usr/include/linux/stat.h /usr/include/linux/string.h \
- /usr/include/linux/mm.h
-file.o : file.c /usr/include/asm/segment.h /usr/include/asm/system.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
- /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
- /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
- /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
- /usr/include/linux/iso_fs.h /usr/include/linux/fcntl.h /usr/include/linux/errno.h \
- /usr/include/linux/stat.h /usr/include/linux/locks.h
-inode.o : inode.c /usr/include/linux/config.h /usr/include/linux/config.dist.h \
- /usr/include/linux/stat.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/iso_fs.h \
- /usr/include/linux/string.h /usr/include/linux/locks.h /usr/include/asm/system.h \
- /usr/include/asm/segment.h /usr/include/linux/errno.h
-namei.o : namei.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/iso_fs.h /usr/include/linux/string.h \
- /usr/include/linux/stat.h /usr/include/linux/fcntl.h /usr/include/asm/segment.h \
- /usr/include/linux/errno.h
-rock.o : rock.c /usr/include/linux/config.h /usr/include/linux/config.dist.h \
- /usr/include/linux/stat.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/iso_fs.h \
- /usr/include/linux/string.h rock.h
-symlink.o : symlink.c /usr/include/asm/segment.h /usr/include/linux/errno.h \
- /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/iso_fs.h /usr/include/linux/stat.h
-util.o : util.c
+#
+# include a dependency file if one exists
+#
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
diff --git a/fs/isofs/dir.c b/fs/isofs/dir.c
index ac61fcb..eb93065 100644
--- a/fs/isofs/dir.c
+++ b/fs/isofs/dir.c
@@ -23,7 +23,7 @@ static int isofs_readdir(struct inode *, struct file *, struct dirent *, int);
static struct file_operations isofs_dir_operations = {
NULL, /* lseek - default */
- isofs_file_read, /* read */
+ NULL, /* read */
NULL, /* write - bad */
isofs_readdir, /* readdir */
NULL, /* select - default */
diff --git a/fs/isofs/fifo.c b/fs/isofs/fifo.c
new file mode 100644
index 0000000..d63aaac
--- /dev/null
+++ b/fs/isofs/fifo.c
@@ -0,0 +1,27 @@
+/*
+ * linux/fs/fifo.c
+ *
+ * written by Paul H. Hargrove
+ */
+
+#include <linux/sched.h>
+#include <linux/iso_fs.h>
+
+extern struct file_operations def_fifo_fops;
+
+struct inode_operations isofs_fifo_inode_operations = {
+ &def_fifo_fops, /* default file operations */
+ NULL, /* create */
+ NULL, /* lookup */
+ NULL, /* link */
+ NULL, /* unlink */
+ NULL, /* symlink */
+ NULL, /* mkdir */
+ NULL, /* rmdir */
+ NULL, /* mknod */
+ NULL, /* rename */
+ NULL, /* readlink */
+ NULL, /* follow_link */
+ NULL, /* bmap */
+ NULL /* truncate */
+};
diff --git a/fs/isofs/file.c b/fs/isofs/file.c
index ff14934..221a9d4 100644
--- a/fs/isofs/file.c
+++ b/fs/isofs/file.c
@@ -29,7 +29,7 @@
#include <linux/fs.h>
#include <linux/iso_fs.h>
-int isofs_file_read(struct inode *, struct file *, char *, int);
+static int isofs_file_read(struct inode *, struct file *, char *, int);
/*
* We have mostly NULL's here: the current defaults are ok for
@@ -38,7 +38,7 @@ int isofs_file_read(struct inode *, struct file *, char *, int);
static struct file_operations isofs_file_operations = {
NULL, /* lseek - default */
isofs_file_read, /* read */
- NULL, /* write */
+ NULL, /* write */
NULL, /* readdir - bad */
NULL, /* select - default */
NULL, /* ioctl - default */
@@ -60,7 +60,7 @@ struct inode_operations isofs_file_inode_operations = {
NULL, /* readlink */
NULL, /* follow_link */
isofs_bmap, /* bmap */
- NULL /* truncate */
+ NULL /* truncate */
};
/* This is a heuristic to determine if a file is text of binary. If it
@@ -108,13 +108,7 @@ static void isofs_determine_filetype(struct inode * inode)
}
}
-/*
- * isofs_file_read() is also needed by the directory read-routine,
- * so it's not static. NOTE! reading directories directly is a bad idea,
- * but has to be supported for now for compatability reasons with older
- * versions.
- */
-int isofs_file_read(struct inode * inode, struct file * filp, char * buf, int count)
+static int isofs_file_read(struct inode * inode, struct file * filp, char * buf, int count)
{
int read,left,chars;
int block, blocks, offset;
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index 7585abb..57981c1 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -316,6 +316,13 @@ void isofs_read_inode(struct inode * inode)
inode->i_gid = 0;
inode->i_size = isonum_733 (raw_inode->size);
+ /* There are defective discs out there - we do this to protect
+ ourselves. A cdrom will never contain more than 700Mb */
+ if(inode->i_size < 0 || inode->i_size > 700000000) {
+ printk("Warning: defective cdrom. Enabling \"cruft\" mount option.\n");
+ inode->i_sb->u.isofs_sb.s_cruft = 'y';
+ };
+
/* Some dipshit decided to store some other bit of information in the high
byte of the file length. Catch this and holler. WARNING: this will make
it impossible for a file to be > 16Mb on the CDROM!!!*/
@@ -412,6 +419,14 @@ void isofs_read_inode(struct inode * inode)
inode->i_op = &isofs_chrdev_inode_operations;
else if (S_ISBLK(inode->i_mode))
inode->i_op = &isofs_blkdev_inode_operations;
+ else if (S_ISFIFO(inode->i_mode)) {
+ inode->i_op = &isofs_fifo_inode_operations;
+ inode->i_pipe = 1;
+ PIPE_BASE(*inode) = NULL;
+ PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
+ PIPE_READ_WAIT(*inode) = PIPE_WRITE_WAIT(*inode) = NULL;
+ PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
+ }
}
/* There are times when we need to know the inode number of a parent of
diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c
index eb6f071..09ffa0c 100644
--- a/fs/isofs/rock.c
+++ b/fs/isofs/rock.c
@@ -115,14 +115,18 @@ int find_rock_ridge_relocation(struct iso_directory_record * de,
CHECK_SP(goto out);
break;
case SIG('C','L'):
+#ifdef DEBUG
printk("RR: CL\n");
+#endif
if (flag == 0) {
retval = isonum_733(rr->u.CL.location);
goto out;
};
break;
case SIG('P','L'):
+#ifdef DEBUG
printk("RR: PL\n");
+#endif
if (flag != 0) {
retval = isonum_733(rr->u.PL.location);
goto out;
@@ -202,7 +206,9 @@ int get_rock_ridge_filename(struct iso_directory_record * de,
retnamlen += rr->len - 5;
break;
case SIG('R','E'):
+#ifdef DEBUG
printk("RR: RE (%x)\n", inode->i_ino);
+#endif
if (buffer) kfree(buffer);
if (retname) kfree(retname);
return -1;
@@ -274,7 +280,7 @@ int parse_rock_ridge_inode(struct iso_directory_record * de,
{ int high, low;
high = isonum_733(rr->u.PN.dev_high);
low = isonum_733(rr->u.PN.dev_low);
- inode->i_rdev = ((high << 8) | (low && 0xff)) & 0xffff;
+ inode->i_rdev = ((high << 8) | (low & 0xff)) & 0xffff;
};
break;
case SIG('T','F'):
@@ -317,9 +323,12 @@ int parse_rock_ridge_inode(struct iso_directory_record * de,
printk("Attempt to read inode for relocated directory\n");
goto out;
case SIG('C','L'):
+#ifdef DEBUG
printk("RR CL (%x)\n",inode->i_ino);
- inode->u.isofs_i.i_first_extent = isonum_733(rr->u.CL.location);
- reloc = iget(inode->i_sb, inode->u.isofs_i.i_first_extent << ISOFS_BLOCK_BITS);
+#endif
+ inode->u.isofs_i.i_first_extent = isonum_733(rr->u.CL.location) <<
+ (ISOFS_BLOCK_BITS - ISOFS_BUFFER_BITS);
+ reloc = iget(inode->i_sb, inode->u.isofs_i.i_first_extent << ISOFS_BUFFER_BITS);
inode->i_mode = reloc->i_mode;
inode->i_nlink = reloc->i_nlink;
inode->i_uid = reloc->i_uid;
diff --git a/fs/minix/Makefile b/fs/minix/Makefile
index 0482477..aac5242 100644
--- a/fs/minix/Makefile
+++ b/fs/minix/Makefile
@@ -21,114 +21,14 @@ minix.o: $(OBJS)
$(LD) -r -o minix.o $(OBJS)
clean:
- rm -f core *.o *.a tmp_make
- for i in *.c;do rm -f `basename $$i .c`.s;done
+ rm -f core *.o *.a *.s
dep:
- sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
- $(CPP) -M *.c >> tmp_make
- cp tmp_make Makefile
+ $(CPP) -M *.c > .depend
-### Dependencies:
-bitmap.o : bitmap.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/minix_fs.h /usr/include/linux/stat.h \
- /usr/include/linux/string.h
-blkdev.o : blkdev.c /usr/include/linux/errno.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/minix_fs.h \
- /usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/asm/system.h \
- /usr/include/linux/stat.h /usr/include/linux/fcntl.h
-chrdev.o : chrdev.c /usr/include/linux/errno.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/minix_fs.h \
- /usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/asm/system.h \
- /usr/include/linux/stat.h /usr/include/linux/fcntl.h
-dir.o : dir.c /usr/include/asm/segment.h /usr/include/linux/errno.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/minix_fs.h \
- /usr/include/linux/stat.h
-fifo.o : fifo.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/minix_fs.h
-file.o : file.c /usr/include/asm/segment.h /usr/include/asm/system.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
- /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
- /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
- /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
- /usr/include/linux/minix_fs.h /usr/include/linux/errno.h /usr/include/linux/fcntl.h \
- /usr/include/linux/stat.h /usr/include/linux/locks.h
-inode.o : inode.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/minix_fs.h /usr/include/linux/string.h \
- /usr/include/linux/stat.h /usr/include/linux/locks.h /usr/include/asm/system.h \
- /usr/include/asm/segment.h
-namei.o : namei.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/minix_fs.h /usr/include/linux/string.h \
- /usr/include/linux/stat.h /usr/include/linux/fcntl.h /usr/include/linux/errno.h \
- /usr/include/asm/segment.h
-symlink.o : symlink.c /usr/include/asm/segment.h /usr/include/linux/errno.h \
- /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/minix_fs.h /usr/include/linux/stat.h
-truncate.o : truncate.c /usr/include/linux/errno.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
- /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
- /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
- /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
- /usr/include/linux/minix_fs.h /usr/include/linux/tty.h /usr/include/linux/termios.h \
- /usr/include/asm/system.h /usr/include/linux/stat.h /usr/include/linux/fcntl.h
+#
+# include a dependency file if one exists
+#
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
diff --git a/fs/minix/file.c b/fs/minix/file.c
index 0f17e2e..9643009 100644
--- a/fs/minix/file.c
+++ b/fs/minix/file.c
@@ -65,37 +65,41 @@ static int minix_file_read(struct inode * inode, struct file * filp, char * buf,
{
int read,left,chars;
int block, blocks, offset;
- int bhrequest;
- int ra_blocks, max_block, nextblock;
+ int bhrequest, uptodate;
struct buffer_head ** bhb, ** bhe;
struct buffer_head * bhreq[NBUF];
struct buffer_head * buflist[NBUF];
+ unsigned int size;
if (!inode) {
printk("minix_file_read: inode = NULL\n");
return -EINVAL;
}
- if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
+ if (!S_ISREG(inode->i_mode)) {
printk("minix_file_read: mode = %07o\n",inode->i_mode);
return -EINVAL;
}
- if (filp->f_pos > inode->i_size)
+ offset = filp->f_pos;
+ size = inode->i_size;
+ if (offset > size)
left = 0;
else
- left = inode->i_size - filp->f_pos;
+ left = size - offset;
if (left > count)
left = count;
if (left <= 0)
return 0;
read = 0;
- block = filp->f_pos >> BLOCK_SIZE_BITS;
- offset = filp->f_pos & (BLOCK_SIZE-1);
- blocks = (left + offset + BLOCK_SIZE - 1) / BLOCK_SIZE;
+ block = offset >> BLOCK_SIZE_BITS;
+ offset &= BLOCK_SIZE-1;
+ size = (size + (BLOCK_SIZE-1)) >> BLOCK_SIZE_BITS;
+ blocks = (left + offset + BLOCK_SIZE - 1) >> BLOCK_SIZE_BITS;
bhb = bhe = buflist;
-
- ra_blocks = read_ahead[MAJOR(inode->i_dev)] / (BLOCK_SIZE >> 9);
- max_block = (inode->i_size + BLOCK_SIZE - 1)/BLOCK_SIZE;
- nextblock = -1;
+ if (filp->f_reada) {
+ blocks += read_ahead[MAJOR(inode->i_dev)] / (BLOCK_SIZE >> 9);
+ if (block + blocks > size)
+ blocks = size - block;
+ }
/* We do this in a two stage process. We first try and request
as many blocks as we can, then we wait for the first one to
@@ -108,104 +112,69 @@ static int minix_file_read(struct inode * inode, struct file * filp, char * buf,
buffers and caches. */
do {
- bhrequest = 0;
+ bhrequest = 0;
+ uptodate = 1;
while (blocks) {
- int uptodate;
--blocks;
*bhb = minix_getblk(inode, block++, 0);
- uptodate = 1;
if (*bhb && !(*bhb)->b_uptodate) {
uptodate = 0;
bhreq[bhrequest++] = *bhb;
- nextblock = (*bhb)->b_blocknr + 1;
- };
+ }
if (++bhb == &buflist[NBUF])
bhb = buflist;
/* If the block we have on hand is uptodate, go ahead
and complete processing. */
- if(bhrequest == 0 && uptodate) break;
-
+ if (uptodate)
+ break;
if (bhb == bhe)
break;
- }
-
- if(blocks == 0 && bhrequest && filp->f_reada && bhb != bhe) {
- /* If we are going to read something anyways, add in the
- read-ahead blocks */
- while(ra_blocks){
- if (block >= max_block) break;
- if(bhrequest == NBUF) break; /* Block full */
- --ra_blocks;
- *bhb = minix_getblk(inode, block++, 0);
+ }
- if (*bhb && !(*bhb)->b_uptodate) {
- if((*bhb)->b_blocknr != nextblock) {
- brelse(*bhb);
- break;
- };
- nextblock = (*bhb)->b_blocknr + 1;
- bhreq[bhrequest++] = *bhb;
- };
-
- if (++bhb == &buflist[NBUF])
- bhb = buflist;
-
- if (bhb == bhe)
- break;
- };
- };
/* Now request them all */
if (bhrequest)
- ll_rw_block(READ, bhrequest, bhreq);
-
- do{ /* Finish off all I/O that has actually completed */
- if (*bhe) {/* test for valid buffer */
- wait_on_buffer(*bhe);
- if (!(*bhe)->b_uptodate) {
- do {
- brelse(*bhe);
+ ll_rw_block(READ, bhrequest, bhreq);
+
+ do { /* Finish off all I/O that has actually completed */
+ if (*bhe) {
+ wait_on_buffer(*bhe);
+ if (!(*bhe)->b_uptodate) { /* read error? */
+ left = 0;
+ break;
+ }
+ }
+ if (left < BLOCK_SIZE - offset)
+ chars = left;
+ else
+ chars = BLOCK_SIZE - offset;
+ filp->f_pos += chars;
+ left -= chars;
+ read += chars;
+ if (*bhe) {
+ memcpy_tofs(buf,offset+(*bhe)->b_data,chars);
+ brelse(*bhe);
+ buf += chars;
+ } else {
+ while (chars-->0)
+ put_fs_byte(0,buf++);
+ }
+ offset = 0;
if (++bhe == &buflist[NBUF])
- bhe = buflist;
- } while (bhe != bhb);
- break;
- }
- }
-
- if (left < BLOCK_SIZE - offset)
- chars = left;
- else
- chars = BLOCK_SIZE - offset;
- filp->f_pos += chars;
- left -= chars;
- read += chars;
- if (*bhe) {
- memcpy_tofs(buf,offset+(*bhe)->b_data,chars);
- brelse(*bhe);
- buf += chars;
- } else {
- while (chars-->0)
- put_fs_byte(0,buf++);
- }
- offset = 0;
- if (++bhe == &buflist[NBUF])
- bhe = buflist;
- } while( bhe != bhb && (*bhe == 0 || !(*bhe)->b_lock) &&
- (left > 0));
+ bhe = buflist;
+ } while (left > 0 && bhe != bhb && (!*bhe || !(*bhe)->b_lock));
} while (left > 0);
/* Release the read-ahead blocks */
while (bhe != bhb) {
- if (*bhe) brelse(*bhe);
- if (++bhe == &buflist[NBUF])
- bhe = buflist;
+ brelse(*bhe);
+ if (++bhe == &buflist[NBUF])
+ bhe = buflist;
};
-
- filp->f_reada = 1;
-
if (!read)
return -EIO;
+ filp->f_reada = 1;
if (!IS_RDONLY(inode)) {
inode->i_atime = CURRENT_TIME;
inode->i_dirt = 1;
diff --git a/fs/msdos/Makefile b/fs/msdos/Makefile
index 2ca5a9e..b84c536 100644
--- a/fs/msdos/Makefile
+++ b/fs/msdos/Makefile
@@ -20,71 +20,14 @@ msdos.o: $(OBJS)
$(LD) -r -o msdos.o $(OBJS)
clean:
- rm -f core *.o *.a tmp_make
- for i in *.c;do rm -f `basename $$i .c`.s;done
+ rm -f core *.o *.a *.s
dep:
- sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
- $(CPP) -M *.c >> tmp_make
- cp tmp_make Makefile
+ $(CPP) -M *.c > .depend
-### Dependencies:
-dir.o : dir.c /usr/include/asm/segment.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/msdos_fs.h \
- /usr/include/linux/errno.h /usr/include/linux/stat.h
-fat.o : fat.c /usr/include/linux/msdos_fs.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
- /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/kernel.h /usr/include/linux/errno.h \
- /usr/include/linux/stat.h
-file.o : file.c /usr/include/asm/segment.h /usr/include/asm/system.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
- /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
- /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
- /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
- /usr/include/linux/msdos_fs.h /usr/include/linux/errno.h /usr/include/linux/fcntl.h \
- /usr/include/linux/stat.h
-inode.o : inode.c /usr/include/linux/msdos_fs.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
- /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/kernel.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/mm.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/errno.h \
- /usr/include/linux/string.h /usr/include/linux/ctype.h /usr/include/linux/stat.h \
- /usr/include/linux/locks.h /usr/include/asm/segment.h
-misc.o : misc.c /usr/include/linux/msdos_fs.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
- /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/errno.h \
- /usr/include/linux/string.h /usr/include/linux/stat.h
-namei.o : namei.c /usr/include/asm/segment.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/msdos_fs.h \
- /usr/include/linux/errno.h /usr/include/linux/string.h /usr/include/linux/stat.h
+#
+# include a dependency file if one exists
+#
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
diff --git a/fs/namei.c b/fs/namei.c
index 175526b..b1a82cf 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -226,12 +226,17 @@ int open_namei(const char * pathname, int flag, int mode,
if (error)
return error;
if (!namelen) { /* special case: '/usr/' etc */
- if (!(flag & 2)) {
- *res_inode=dir;
- return 0;
+ if (flag & 2) {
+ iput(dir);
+ return -EISDIR;
}
- iput(dir);
- return -EISDIR;
+ /* thanks to Paul Pluzhnikov for noticing this was missing.. */
+ if (!permission(dir,ACC_MODE(flag))) {
+ iput(dir);
+ return -EACCES;
+ }
+ *res_inode=dir;
+ return 0;
}
dir->i_count++; /* lookup eats the dir */
error = lookup(dir,basename,namelen,&inode);
@@ -264,7 +269,7 @@ int open_namei(const char * pathname, int flag, int mode,
return error;
if (S_ISDIR(inode->i_mode) && (flag & 2)) {
iput(inode);
- return -EPERM;
+ return -EISDIR;
}
if (!permission(inode,ACC_MODE(flag))) {
iput(inode);
diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
new file mode 100644
index 0000000..f422bfa
--- /dev/null
+++ b/fs/nfs/Makefile
@@ -0,0 +1,34 @@
+#
+# Makefile for the linux nfs-filesystem routines.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+.c.s:
+ $(CC) $(CFLAGS) -S $<
+.c.o:
+ $(CC) $(CFLAGS) -c $<
+.s.o:
+ $(AS) -o $*.o $<
+
+OBJS= proc.o sock.o inode.o file.o dir.o \
+ symlink.o blkdev.o chrdev.o fifo.o
+
+nfs.o: $(OBJS)
+ $(LD) -r -o nfs.o $(OBJS)
+
+clean:
+ rm -f core *.o *.a *.s
+
+dep:
+ $(CPP) -M *.c > .depend
+
+#
+# include a dependency file if one exists
+#
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
diff --git a/fs/nfs/blkdev.c b/fs/nfs/blkdev.c
new file mode 100644
index 0000000..7df82f6
--- /dev/null
+++ b/fs/nfs/blkdev.c
@@ -0,0 +1,62 @@
+/*
+ * linux/fs/nfs/blkdev.c
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/nfs_fs.h>
+#include <linux/tty.h>
+#include <linux/stat.h>
+#include <linux/fcntl.h>
+
+/*
+ * Called every time a nfs block special file is opened
+ */
+static int blkdev_open(struct inode * inode, struct file * filp)
+{
+ int i;
+
+ i = MAJOR(inode->i_rdev);
+ if (i < MAX_BLKDEV) {
+ filp->f_op = blkdev_fops[i];
+ if (filp->f_op && filp->f_op->open)
+ return filp->f_op->open(inode,filp);
+ }
+ return 0;
+}
+
+/*
+ * Dummy default file-operations: the only thing this does
+ * is contain the open that then fills in the correct operations
+ * depending on the special file...
+ */
+static struct file_operations def_blk_fops = {
+ NULL, /* lseek */
+ NULL, /* read */
+ NULL, /* write */
+ NULL, /* readdir */
+ NULL, /* select */
+ NULL, /* ioctl */
+ NULL, /* mmap */
+ blkdev_open, /* open */
+ NULL, /* release */
+};
+
+struct inode_operations nfs_blkdev_inode_operations = {
+ &def_blk_fops, /* default file operations */
+ NULL, /* create */
+ NULL, /* lookup */
+ NULL, /* link */
+ NULL, /* unlink */
+ NULL, /* symlink */
+ NULL, /* mkdir */
+ NULL, /* rmdir */
+ NULL, /* mknod */
+ NULL, /* rename */
+ NULL, /* readlink */
+ NULL, /* follow_link */
+ NULL, /* bmap */
+ NULL /* truncate */
+};
diff --git a/fs/nfs/chrdev.c b/fs/nfs/chrdev.c
new file mode 100644
index 0000000..458b4c7
--- /dev/null
+++ b/fs/nfs/chrdev.c
@@ -0,0 +1,63 @@
+/*
+ * linux/fs/nfs/chrdev.c
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/nfs_fs.h>
+#include <linux/tty.h>
+#include <linux/stat.h>
+#include <linux/fcntl.h>
+
+/*
+ * Called every time a nfs character special file is opened
+ */
+static int chrdev_open(struct inode * inode, struct file * filp)
+{
+ int i;
+
+ i = MAJOR(inode->i_rdev);
+ if (i < MAX_CHRDEV) {
+ filp->f_op = chrdev_fops[i];
+ if (filp->f_op && filp->f_op->open)
+ return filp->f_op->open(inode,filp);
+ }
+ return 0;
+}
+
+/*
+ * Dummy default file-operations: the only thing this does
+ * is contain the open that then fills in the correct operations
+ * depending on the special file...
+ */
+static struct file_operations def_chr_fops = {
+ NULL, /* lseek */
+ NULL, /* read */
+ NULL, /* write */
+ NULL, /* readdir */
+ NULL, /* select */
+ NULL, /* ioctl */
+ NULL, /* mmap */
+ chrdev_open, /* open */
+ NULL, /* release */
+};
+
+struct inode_operations nfs_chrdev_inode_operations = {
+ &def_chr_fops, /* default file operations */
+ NULL, /* create */
+ NULL, /* lookup */
+ NULL, /* link */
+ NULL, /* unlink */
+ NULL, /* symlink */
+ NULL, /* mkdir */
+ NULL, /* rmdir */
+ NULL, /* mknod */
+ NULL, /* rename */
+ NULL, /* readlink */
+ NULL, /* follow_link */
+ NULL, /* bmap */
+ NULL /* truncate */
+};
+
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
new file mode 100644
index 0000000..16d2208
--- /dev/null
+++ b/fs/nfs/dir.c
@@ -0,0 +1,641 @@
+/*
+ * linux/fs/nfs/dir.c
+ *
+ * Copyright (C) 1992 Rick Sladkey
+ *
+ * nfs directory handling functions
+ */
+
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/stat.h>
+#include <linux/nfs_fs.h>
+#include <linux/fcntl.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+
+#include <asm/segment.h> /* for fs functions */
+
+static int nfs_dir_read(struct inode *, struct file *filp, char *buf,
+ int count);
+static int nfs_readdir(struct inode *, struct file *, struct dirent *, int);
+static int nfs_lookup(struct inode *dir, const char *name, int len,
+ struct inode **result);
+static int nfs_create(struct inode *dir, const char *name, int len, int mode,
+ struct inode **result);
+static int nfs_mkdir(struct inode *dir, const char *name, int len, int mode);
+static int nfs_rmdir(struct inode *dir, const char *name, int len);
+static int nfs_unlink(struct inode *dir, const char *name, int len);
+static int nfs_symlink(struct inode *inode, const char *name, int len,
+ const char *symname);
+static int nfs_link(struct inode *oldinode, struct inode *dir,
+ const char *name, int len);
+static int nfs_mknod(struct inode *dir, const char *name, int len, int mode,
+ int rdev);
+static int nfs_rename(struct inode *old_dir, const char *old_name,
+ int old_len, struct inode *new_dir, const char *new_name,
+ int new_len);
+
+static struct file_operations nfs_dir_operations = {
+ NULL, /* lseek - default */
+ nfs_dir_read, /* read - bad */
+ NULL, /* write - bad */
+ nfs_readdir, /* readdir */
+ NULL, /* select - default */
+ NULL, /* ioctl - default */
+ NULL, /* mmap */
+ NULL, /* no special open code */
+ NULL /* no special release code */
+};
+
+struct inode_operations nfs_dir_inode_operations = {
+ &nfs_dir_operations, /* default directory file-ops */
+ nfs_create, /* create */
+ nfs_lookup, /* lookup */
+ nfs_link, /* link */
+ nfs_unlink, /* unlink */
+ nfs_symlink, /* symlink */
+ nfs_mkdir, /* mkdir */
+ nfs_rmdir, /* rmdir */
+ nfs_mknod, /* mknod */
+ nfs_rename, /* rename */
+ NULL, /* readlink */
+ NULL, /* follow_link */
+ NULL, /* bmap */
+ NULL, /* truncate */
+};
+
+static int nfs_dir_read(struct inode *inode, struct file *filp, char *buf,
+ int count)
+{
+ return -EISDIR;
+}
+
+/*
+ * We need to do caching of directory entries to prevent an
+ * incredible amount of RPC traffic. Only the most recent open
+ * directory is cached. This seems sufficient for most purposes.
+ * Technically, we ought to flush the cache on close but this is
+ * not a problem in practice.
+ */
+
+static int nfs_readdir(struct inode *inode, struct file *filp,
+ struct dirent *dirent, int count)
+{
+ static int c_dev = 0;
+ static int c_ino;
+ static int c_size;
+ static struct nfs_entry *c_entry = NULL;
+
+ int result;
+ int i;
+ struct nfs_entry *entry;
+
+ if (!inode || !S_ISDIR(inode->i_mode)) {
+ printk("nfs_readdir: inode is NULL or not a directory\n");
+ return -EBADF;
+ }
+
+ /* initialize cache memory if it hasn't been used before */
+
+ if (c_entry == NULL) {
+ i = sizeof (struct nfs_entry)*NFS_READDIR_CACHE_SIZE;
+ c_entry = (struct nfs_entry *) kmalloc(i, GFP_KERNEL);
+ for (i = 0; i < NFS_READDIR_CACHE_SIZE; i++) {
+ c_entry[i].name = (char *) kmalloc(NFS_MAXNAMLEN + 1,
+ GFP_KERNEL);
+ }
+ }
+ entry = NULL;
+
+ /* try to find it in the cache */
+
+ if (inode->i_dev == c_dev && inode->i_ino == c_ino) {
+ for (i = 0; i < c_size; i++) {
+ if (filp->f_pos == c_entry[i].cookie) {
+ if (i == c_size - 1) {
+ if (c_entry[i].eof)
+ return 0;
+ }
+ else
+ entry = c_entry + i + 1;
+ break;
+ }
+ }
+ }
+
+ /* if we didn't find it in the cache, revert to an nfs call */
+
+ if (!entry) {
+ result = nfs_proc_readdir(NFS_SERVER(inode), NFS_FH(inode),
+ filp->f_pos, NFS_READDIR_CACHE_SIZE, c_entry);
+ if (result < 0) {
+ c_dev = 0;
+#if 0
+ printk("nfs_readdir: readdir error = %d\n", result);
+#endif
+ return result;
+ }
+ if (result > 0) {
+ c_dev = inode->i_dev;
+ c_ino = inode->i_ino;
+ c_size = result;
+ entry = c_entry + 0;
+ }
+ }
+
+ /* if we found it in the cache or from an nfs call, return results */
+
+ if (entry) {
+ i = strlen(entry->name);
+ memcpy_tofs(dirent->d_name, entry->name, i + 1);
+ put_fs_long(entry->fileid, &dirent->d_ino);
+ put_fs_word(i, &dirent->d_reclen);
+ filp->f_pos = entry->cookie;
+ return i;
+ }
+ return 0;
+}
+
+/*
+ * Lookup caching is a big win for performance but this is just
+ * a trial to see how well it works on a small scale.
+ * For example, bash does a lookup on ".." 13 times for each path
+ * element when running pwd. Yes, hard to believe but true.
+ * Try pwd in a filesystem mounted with noac.
+ *
+ * It trades a little cpu time and memory for a lot of network bandwidth.
+ * Since the cache is not hashed yet, it is a good idea not to make it too
+ * large because every lookup looks through the entire cache even
+ * though most of them will fail.
+ */
+
+#define NFS_LOOKUP_CACHE_SIZE 16
+
+static struct nfs_lookup_cache_entry {
+ int dev;
+ int inode;
+ char filename[NFS_MAXNAMLEN + 1];
+ struct nfs_fh fhandle;
+ struct nfs_fattr fattr;
+ int expiration_date;
+} nfs_lookup_cache[NFS_LOOKUP_CACHE_SIZE];
+
+static struct nfs_lookup_cache_entry *nfs_lookup_cache_index(struct inode *dir,
+ char *filename)
+{
+ struct nfs_lookup_cache_entry *entry;
+ int i;
+
+ for (i = 0; i < NFS_LOOKUP_CACHE_SIZE; i++) {
+ entry = nfs_lookup_cache + i;
+ if (entry->dev == dir->i_dev && entry->inode == dir->i_ino
+ && !strcmp(filename, entry->filename))
+ return entry;
+ }
+ return NULL;
+}
+
+static int nfs_lookup_cache_lookup(struct inode *dir, char *filename,
+ struct nfs_fh *fhandle,
+ struct nfs_fattr *fattr)
+{
+ static int nfs_lookup_cache_in_use = 0;
+
+ struct nfs_lookup_cache_entry *entry;
+
+ if (!nfs_lookup_cache_in_use) {
+ memset(nfs_lookup_cache, 0, sizeof(nfs_lookup_cache));
+ nfs_lookup_cache_in_use = 1;
+ }
+ if ((entry = nfs_lookup_cache_index(dir, filename))) {
+ if (jiffies > entry->expiration_date) {
+ entry->dev = 0;
+ return 0;
+ }
+ *fhandle = entry->fhandle;
+ *fattr = entry->fattr;
+ return 1;
+ }
+ return 0;
+}
+
+static void nfs_lookup_cache_add(struct inode *dir, char *filename,
+ struct nfs_fh *fhandle,
+ struct nfs_fattr *fattr)
+{
+ static int nfs_lookup_cache_pos = 0;
+
+ struct nfs_lookup_cache_entry *entry;
+
+ /* compensate for bug in SGI NFS server */
+ if (fattr->size == -1 || fattr->uid == -1 || fattr->gid == -1
+ || fattr->atime.seconds == -1 || fattr->mtime.seconds == -1)
+ return;
+ if (!(entry = nfs_lookup_cache_index(dir, filename))) {
+ entry = nfs_lookup_cache + nfs_lookup_cache_pos++;
+ if (nfs_lookup_cache_pos == NFS_LOOKUP_CACHE_SIZE)
+ nfs_lookup_cache_pos = 0;
+ }
+ entry->dev = dir->i_dev;
+ entry->inode = dir->i_ino;
+ strcpy(entry->filename, filename);
+ entry->fhandle = *fhandle;
+ entry->fattr = *fattr;
+ entry->expiration_date = jiffies + NFS_SERVER(dir)->acregmax;
+}
+
+static void nfs_lookup_cache_remove(struct inode *dir, char *filename)
+{
+ struct nfs_lookup_cache_entry *entry;
+
+ if ((entry = nfs_lookup_cache_index(dir, filename)))
+ entry->dev = 0;
+}
+
+static void nfs_lookup_cache_refresh(struct inode *file,
+ struct nfs_fattr *fattr)
+{
+ struct nfs_lookup_cache_entry *entry;
+ int i;
+
+ for (i = 0; i < NFS_LOOKUP_CACHE_SIZE; i++) {
+ entry = nfs_lookup_cache + i;
+ if (entry->dev == file->i_dev
+ && entry->fattr.fileid == file->i_ino) {
+ entry->fattr = *fattr;
+ break;
+ }
+ }
+}
+
+static int nfs_lookup(struct inode *dir, const char *name, int len,
+ struct inode **result)
+{
+ char filename[NFS_MAXNAMLEN + 1];
+ struct nfs_fh fhandle;
+ struct nfs_fattr fattr;
+ int error;
+
+ *result = NULL;
+ if (!dir || !S_ISDIR(dir->i_mode)) {
+ printk("nfs_lookup: inode is NULL or not a directory\n");
+ iput(dir);
+ return -ENOENT;
+ }
+ if (len > NFS_MAXNAMLEN) {
+ iput(dir);
+ return -ENAMETOOLONG;
+ }
+ memcpy_fromfs(filename, (char *) name, len);
+ filename[len] = '\0';
+ if (len == 1 && filename[0] == '.') { /* cheat for "." */
+ *result = dir;
+ return 0;
+ }
+ if ((NFS_SERVER(dir)->flags & NFS_MOUNT_NOAC)
+ || !nfs_lookup_cache_lookup(dir, filename, &fhandle, &fattr)) {
+ if ((error = nfs_proc_lookup(NFS_SERVER(dir), NFS_FH(dir),
+ filename, &fhandle, &fattr))) {
+ iput(dir);
+ return error;
+ }
+ nfs_lookup_cache_add(dir, filename, &fhandle, &fattr);
+ }
+ if (!(*result = nfs_fhget(dir->i_sb, &fhandle, &fattr))) {
+ iput(dir);
+ return -EACCES;
+ }
+ iput(dir);
+ return 0;
+}
+
+static int nfs_create(struct inode *dir, const char *name, int len, int mode,
+ struct inode **result)
+{
+ char filename[NFS_MAXNAMLEN + 1];
+ struct nfs_sattr sattr;
+ struct nfs_fattr fattr;
+ struct nfs_fh fhandle;
+ int error;
+
+ *result = NULL;
+ if (!dir || !S_ISDIR(dir->i_mode)) {
+ printk("nfs_create: inode is NULL or not a directory\n");
+ iput(dir);
+ return -ENOENT;
+ }
+ if (len > NFS_MAXNAMLEN) {
+ iput(dir);
+ return -ENAMETOOLONG;
+ }
+ memcpy_fromfs(filename, (char *) name, len);
+ filename[len] = '\0';
+#if 0
+ sattr.mode = mode & 0777;
+#else
+ sattr.mode = mode;
+#endif
+ sattr.uid = sattr.gid = sattr.size = -1;
+ sattr.atime.seconds = sattr.mtime.seconds = -1;
+ if ((error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dir),
+ filename, &sattr, &fhandle, &fattr))) {
+ iput(dir);
+ return error;
+ }
+ if (!(*result = nfs_fhget(dir->i_sb, &fhandle, &fattr))) {
+ iput(dir);
+ return -EACCES;
+ }
+ nfs_lookup_cache_add(dir, filename, &fhandle, &fattr);
+ iput(dir);
+ return 0;
+}
+
+static int nfs_mknod(struct inode *dir, const char *name, int len,
+ int mode, int rdev)
+{
+ char filename[NFS_MAXNAMLEN + 1];
+ struct nfs_sattr sattr;
+ struct nfs_fattr fattr;
+ struct nfs_fh fhandle;
+ int error;
+
+ if (!dir || !S_ISDIR(dir->i_mode)) {
+ printk("nfs_mknod: inode is NULL or not a directory\n");
+ iput(dir);
+ return -ENOENT;
+ }
+ if (len > NFS_MAXNAMLEN) {
+ iput(dir);
+ return -ENAMETOOLONG;
+ }
+ memcpy_fromfs(filename, (char *) name, len);
+ filename[len] = '\0';
+ sattr.mode = mode;
+ sattr.uid = sattr.gid = -1;
+ if (S_ISCHR(mode) || S_ISBLK(mode))
+ sattr.size = rdev; /* get out your barf bag */
+ else
+ sattr.size = -1;
+ sattr.atime.seconds = sattr.mtime.seconds = -1;
+ error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dir),
+ filename, &sattr, &fhandle, &fattr);
+ if (!error)
+ nfs_lookup_cache_add(dir, filename, &fhandle, &fattr);
+ iput(dir);
+ return error;
+}
+
+static int nfs_mkdir(struct inode *dir, const char *name, int len, int mode)
+{
+ char filename[NFS_MAXNAMLEN + 1];
+ struct nfs_sattr sattr;
+ struct nfs_fattr fattr;
+ struct nfs_fh fhandle;
+ int error;
+
+ if (!dir || !S_ISDIR(dir->i_mode)) {
+ printk("nfs_mkdir: inode is NULL or not a directory\n");
+ iput(dir);
+ return -ENOENT;
+ }
+ if (len > NFS_MAXNAMLEN) {
+ iput(dir);
+ return -ENAMETOOLONG;
+ }
+ memcpy_fromfs(filename, (char *) name, len);
+ filename[len] = '\0';
+#if 0
+ sattr.mode = mode & 0777;
+#else
+ sattr.mode = mode;
+#endif
+ sattr.uid = sattr.gid = sattr.size = -1;
+ sattr.atime.seconds = sattr.mtime.seconds = -1;
+ error = nfs_proc_mkdir(NFS_SERVER(dir), NFS_FH(dir),
+ filename, &sattr, &fhandle, &fattr);
+ if (!error)
+ nfs_lookup_cache_add(dir, filename, &fhandle, &fattr);
+ iput(dir);
+ return error;
+}
+
+static int nfs_rmdir(struct inode *dir, const char *name, int len)
+{
+ char filename[NFS_MAXNAMLEN + 1];
+ int error;
+
+ if (!dir || !S_ISDIR(dir->i_mode)) {
+ printk("nfs_rmdir: inode is NULL or not a directory\n");
+ iput(dir);
+ return -ENOENT;
+ }
+ if (len > NFS_MAXNAMLEN) {
+ iput(dir);
+ return -ENAMETOOLONG;
+ }
+ memcpy_fromfs(filename, (char *) name, len);
+ filename[len] = '\0';
+ error = nfs_proc_rmdir(NFS_SERVER(dir), NFS_FH(dir), filename);
+ if (!error)
+ nfs_lookup_cache_remove(dir, filename);
+ iput(dir);
+ return error;
+}
+
+static int nfs_unlink(struct inode *dir, const char *name, int len)
+{
+ char filename[NFS_MAXNAMLEN + 1];
+ int error;
+
+ if (!dir || !S_ISDIR(dir->i_mode)) {
+ printk("nfs_unlink: inode is NULL or not a directory\n");
+ iput(dir);
+ return -ENOENT;
+ }
+ if (len > NFS_MAXNAMLEN) {
+ iput(dir);
+ return -ENAMETOOLONG;
+ }
+ memcpy_fromfs(filename, (char *) name, len);
+ filename[len] = '\0';
+ error = nfs_proc_remove(NFS_SERVER(dir), NFS_FH(dir), filename);
+ if (!error)
+ nfs_lookup_cache_remove(dir, filename);
+ iput(dir);
+ return error;
+}
+
+static int nfs_symlink(struct inode *dir, const char *name, int len,
+ const char *symname)
+{
+ char filename[NFS_MAXNAMLEN + 1];
+ char *symfilename;
+ struct nfs_sattr sattr;
+ int error;
+ int i;
+ int c;
+
+ if (!dir || !S_ISDIR(dir->i_mode)) {
+ printk("nfs_symlink: inode is NULL or not a directory\n");
+ iput(dir);
+ return -ENOENT;
+ }
+ if (len > NFS_MAXNAMLEN) {
+ iput(dir);
+ return -ENAMETOOLONG;
+ }
+ memcpy_fromfs(filename, (char *) name, len);
+ filename[len] = '\0';
+ symfilename = (char *) kmalloc(NFS_MAXPATHLEN + 1, GFP_KERNEL);
+ for (i = 0; i < NFS_MAXPATHLEN && (c = get_fs_byte(symname++)); i++)
+ symfilename[i] = c;
+ if (i == NFS_MAXPATHLEN && get_fs_byte(symname)) {
+ kfree_s(symfilename, NFS_MAXPATHLEN + 1);
+ iput(dir);
+ return -ENAMETOOLONG;
+ }
+ symfilename[i] = '\0';
+ sattr.mode = S_IFLNK | 0777; /* SunOS 4.1.2 crashes without this! */
+ sattr.uid = sattr.gid = sattr.size = -1;
+ sattr.atime.seconds = sattr.mtime.seconds = -1;
+ error = nfs_proc_symlink(NFS_SERVER(dir), NFS_FH(dir),
+ filename, symfilename, &sattr);
+ kfree_s(symfilename, NFS_MAXPATHLEN + 1);
+ iput(dir);
+ return error;
+}
+
+static int nfs_link(struct inode *oldinode, struct inode *dir,
+ const char *name, int len)
+{
+ char filename[NFS_MAXNAMLEN + 1];
+ int error;
+
+ if (!oldinode) {
+ printk("nfs_link: old inode is NULL\n");
+ iput(oldinode);
+ iput(dir);
+ return -ENOENT;
+ }
+ if (!dir || !S_ISDIR(dir->i_mode)) {
+ printk("nfs_link: dir is NULL or not a directory\n");
+ iput(oldinode);
+ iput(dir);
+ return -ENOENT;
+ }
+ if (len > NFS_MAXNAMLEN) {
+ iput(oldinode);
+ iput(dir);
+ return -ENAMETOOLONG;
+ }
+ memcpy_fromfs(filename, (char *) name, len);
+ filename[len] = '\0';
+ error = nfs_proc_link(NFS_SERVER(oldinode), NFS_FH(oldinode),
+ NFS_FH(dir), filename);
+ iput(oldinode);
+ iput(dir);
+ return error;
+}
+
+static int nfs_rename(struct inode *old_dir, const char *old_name, int old_len,
+ struct inode *new_dir, const char *new_name, int new_len)
+{
+ char old_filename[NFS_MAXNAMLEN + 1];
+ char new_filename[NFS_MAXNAMLEN + 1];
+ int error;
+
+ if (!old_dir || !S_ISDIR(old_dir->i_mode)) {
+ printk("nfs_rename: old inode is NULL or not a directory\n");
+ iput(old_dir);
+ iput(new_dir);
+ return -ENOENT;
+ }
+ if (!new_dir || !S_ISDIR(new_dir->i_mode)) {
+ printk("nfs_rename: new inode is NULL or not a directory\n");
+ iput(old_dir);
+ iput(new_dir);
+ return -ENOENT;
+ }
+ if (old_len > NFS_MAXNAMLEN || new_len > NFS_MAXNAMLEN) {
+ iput(old_dir);
+ iput(new_dir);
+ return -ENAMETOOLONG;
+ }
+ memcpy_fromfs(old_filename, (char *) old_name, old_len);
+ old_filename[old_len] = '\0';
+ memcpy_fromfs(new_filename, (char *) new_name, new_len);
+ new_filename[new_len] = '\0';
+ error = nfs_proc_rename(NFS_SERVER(old_dir),
+ NFS_FH(old_dir), old_filename,
+ NFS_FH(new_dir), new_filename);
+ if (!error)
+ nfs_lookup_cache_remove(old_dir, old_filename);
+ iput(old_dir);
+ iput(new_dir);
+ return error;
+}
+
+/*
+ * Many nfs protocol calls return the new file attributes after
+ * an operation. Here we update the inode to reflect the state
+ * of the server's inode.
+ */
+
+void nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
+{
+ int was_empty;
+
+ if (!inode || !fattr) {
+ printk("nfs_refresh_inode: inode or fattr is NULL\n");
+ return;
+ }
+ if (inode->i_ino != fattr->fileid) {
+ printk("nfs_refresh_inode: inode number mismatch\n");
+ return;
+ }
+ was_empty = inode->i_mode == 0;
+#if 0
+ if (!was_empty && inode->i_atime > fattr->atime.seconds)
+ return;
+#endif
+ inode->i_mode = fattr->mode;
+ inode->i_nlink = fattr->nlink;
+ inode->i_uid = fattr->uid;
+ inode->i_gid = fattr->gid;
+ inode->i_size = fattr->size;
+ inode->i_blksize = fattr->blocksize;
+ if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
+ inode->i_rdev = fattr->rdev;
+ else
+ inode->i_rdev = 0;
+ inode->i_blocks = fattr->blocks;
+ inode->i_atime = fattr->atime.seconds;
+ inode->i_mtime = fattr->mtime.seconds;
+ inode->i_ctime = fattr->ctime.seconds;
+ if (was_empty) {
+ if (S_ISREG(inode->i_mode))
+ inode->i_op = &nfs_file_inode_operations;
+ else if (S_ISDIR(inode->i_mode))
+ inode->i_op = &nfs_dir_inode_operations;
+ else if (S_ISLNK(inode->i_mode))
+ inode->i_op = &nfs_symlink_inode_operations;
+ else if (S_ISCHR(inode->i_mode))
+ inode->i_op = &nfs_chrdev_inode_operations;
+ else if (S_ISBLK(inode->i_mode))
+ inode->i_op = &nfs_blkdev_inode_operations;
+ else if (S_ISFIFO(inode->i_mode)) {
+ inode->i_op = &nfs_fifo_inode_operations;
+ inode->i_pipe = 1;
+ PIPE_BASE(*inode) = NULL;
+ PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
+ PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
+ }
+ else
+ inode->i_op = NULL;
+ }
+ nfs_lookup_cache_refresh(inode, fattr);
+}
+
diff --git a/fs/nfs/fifo.c b/fs/nfs/fifo.c
new file mode 100644
index 0000000..7199dde
--- /dev/null
+++ b/fs/nfs/fifo.c
@@ -0,0 +1,27 @@
+/*
+ * linux/fs/fifo.c
+ *
+ * written by Paul H. Hargrove
+ */
+
+#include <linux/sched.h>
+#include <linux/nfs_fs.h>
+
+extern struct file_operations def_fifo_fops;
+
+struct inode_operations nfs_fifo_inode_operations = {
+ &def_fifo_fops, /* default file operations */
+ NULL, /* create */
+ NULL, /* lookup */
+ NULL, /* link */
+ NULL, /* unlink */
+ NULL, /* symlink */
+ NULL, /* mkdir */
+ NULL, /* rmdir */
+ NULL, /* mknod */
+ NULL, /* rename */
+ NULL, /* readlink */
+ NULL, /* follow_link */
+ NULL, /* bmap */
+ NULL /* truncate */
+};
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
new file mode 100644
index 0000000..c8af995
--- /dev/null
+++ b/fs/nfs/file.c
@@ -0,0 +1,147 @@
+/*
+ * linux/fs/nfs/file.c
+ *
+ * Copyright (C) 1992 Rick Sladkey
+ *
+ * nfs regular file handling functions
+ */
+
+#include <asm/segment.h>
+#include <asm/system.h>
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/fcntl.h>
+#include <linux/stat.h>
+#include <linux/mm.h>
+#include <linux/nfs_fs.h>
+
+static int nfs_file_read(struct inode *, struct file *, char *, int);
+static int nfs_file_write(struct inode *, struct file *, char *, int);
+
+static struct file_operations nfs_file_operations = {
+ NULL, /* lseek - default */
+ nfs_file_read, /* read */
+ nfs_file_write, /* write */
+ NULL, /* readdir - bad */
+ NULL, /* select - default */
+ NULL, /* ioctl - default */
+ NULL, /* mmap */
+ NULL, /* no special open is needed */
+ NULL /* release */
+};
+
+struct inode_operations nfs_file_inode_operations = {
+ &nfs_file_operations, /* default file operations */
+ NULL, /* create */
+ NULL, /* lookup */
+ NULL, /* link */
+ NULL, /* unlink */
+ NULL, /* symlink */
+ NULL, /* mkdir */
+ NULL, /* rmdir */
+ NULL, /* mknod */
+ NULL, /* rename */
+ NULL, /* readlink */
+ NULL, /* follow_link */
+ NULL, /* bmap */
+ NULL /* truncate */
+};
+
+static int nfs_file_read(struct inode *inode, struct file *file, char *buf,
+ int count)
+{
+ int result;
+ int hunk;
+ int i;
+ int n;
+ struct nfs_fattr fattr;
+ char *data;
+
+ if (!inode) {
+ printk("nfs_file_read: inode = NULL\n");
+ return -EINVAL;
+ }
+ if (!S_ISREG(inode->i_mode)) {
+ printk("nfs_file_read: read from non-file, mode %07o\n",
+ inode->i_mode);
+ return -EINVAL;
+ }
+ if (file->f_pos + count > inode->i_size)
+ count = inode->i_size - file->f_pos;
+ if (count <= 0)
+ return 0;
+ n = NFS_SERVER(inode)->rsize;
+ data = (char *) kmalloc(n, GFP_KERNEL);
+ for (i = 0; i < count; i += n) {
+ hunk = count - i;
+ if (hunk > n)
+ hunk = n;
+ result = nfs_proc_read(NFS_SERVER(inode), NFS_FH(inode),
+ file->f_pos, hunk, data, &fattr);
+ if (result < 0) {
+ kfree_s(data, n);
+ return result;
+ }
+ memcpy_tofs(buf, data, result);
+ file->f_pos += result;
+ buf += result;
+ if (result < n) {
+ i += result;
+ break;
+ }
+ }
+ kfree_s(data, n);
+ nfs_refresh_inode(inode, &fattr);
+ return i;
+}
+
+static int nfs_file_write(struct inode *inode, struct file *file, char *buf,
+ int count)
+{
+ int result;
+ int hunk;
+ int i;
+ int n;
+ struct nfs_fattr fattr;
+ char *data;
+
+ if (!inode) {
+ printk("nfs_file_write: inode = NULL\n");
+ return -EINVAL;
+ }
+ if (!S_ISREG(inode->i_mode)) {
+ printk("nfs_file_write: write to non-file, mode %07o\n",
+ inode->i_mode);
+ return -EINVAL;
+ }
+ if (count <= 0)
+ return 0;
+ if (file->f_flags & O_APPEND)
+ file->f_pos = inode->i_size;
+ n = NFS_SERVER(inode)->wsize;
+ data = (char *) kmalloc(n, GFP_KERNEL);
+ for (i = 0; i < count; i += n) {
+ hunk = count - i;
+ if (hunk >= n)
+ hunk = n;
+ memcpy_fromfs(data, buf, hunk);
+ result = nfs_proc_write(NFS_SERVER(inode), NFS_FH(inode),
+ file->f_pos, hunk, data, &fattr);
+ if (result < 0) {
+ kfree_s(data, n);
+ return result;
+ }
+ file->f_pos += hunk;
+ buf += hunk;
+ if (hunk < n) {
+ i += hunk;
+ break;
+ }
+ }
+ kfree_s(data, n);
+ nfs_refresh_inode(inode, &fattr);
+ return i;
+}
+
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
new file mode 100644
index 0000000..37d9c5f
--- /dev/null
+++ b/fs/nfs/inode.c
@@ -0,0 +1,210 @@
+/*
+ * linux/fs/nfs/inode.c
+ *
+ * Copyright (C) 1992 Rick Sladkey
+ *
+ * nfs inode and superblock handling functions
+ */
+
+#include <asm/system.h>
+#include <asm/segment.h>
+
+#include <linux/sched.h>
+#include <linux/nfs_fs.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/stat.h>
+#include <linux/errno.h>
+#include <linux/locks.h>
+
+extern int close_fp(struct file *filp);
+
+static int nfs_notify_change(struct inode *);
+static void nfs_put_super(struct super_block *);
+static void nfs_statfs(struct super_block *, struct statfs *);
+
+static struct super_operations nfs_sops = {
+ NULL, /* read inode */
+ nfs_notify_change, /* notify change */
+ NULL, /* write inode */
+ NULL, /* put inode */
+ nfs_put_super, /* put superblock */
+ NULL, /* write superblock */
+ nfs_statfs /* stat filesystem */
+};
+
+void nfs_put_super(struct super_block *sb)
+{
+ close_fp(sb->u.nfs_sb.s_server.file);
+ lock_super(sb);
+ sb->s_dev = 0;
+ unlock_super(sb);
+}
+
+/*
+ * The way this works is that the mount process passes a structure
+ * in the data argument which contains an open socket to the NFS
+ * server and the root file handle obtained from the server's mount
+ * daemon. We stash theses away in the private superblock fields.
+ * Later we can add other mount parameters like caching values.
+ */
+
+struct super_block *nfs_read_super(struct super_block *sb, void *raw_data)
+{
+ struct nfs_mount_data *data = (struct nfs_mount_data *) raw_data;
+ struct nfs_server *server;
+ unsigned int fd;
+ struct file *filp;
+ dev_t dev = sb->s_dev;
+
+ if (!data) {
+ printk("nfs_read_super: missing data argument\n");
+ sb->s_dev = 0;
+ return NULL;
+ }
+ fd = data->fd;
+ if (data->version != NFS_MOUNT_VERSION) {
+ printk("nfs warning: mount version %s than kernel\n",
+ data->version < NFS_MOUNT_VERSION ? "older" : "newer");
+ }
+ if (fd >= NR_OPEN || !(filp = current->filp[fd])) {
+ printk("nfs_read_super: invalid file descriptor\n");
+ sb->s_dev = 0;
+ return NULL;
+ }
+ if (!S_ISSOCK(filp->f_inode->i_mode)) {
+ printk("nfs_read_super: not a socket\n");
+ sb->s_dev = 0;
+ return NULL;
+ }
+ filp->f_count++;
+ lock_super(sb);
+ sb->s_blocksize = 1024; /* XXX */
+ sb->s_magic = NFS_SUPER_MAGIC;
+ sb->s_dev = dev;
+ sb->s_op = &nfs_sops;
+ server = &sb->u.nfs_sb.s_server;
+ server->file = filp;
+ server->lock = 0;
+ server->wait = NULL;
+ server->flags = data->flags;
+ server->rsize = data->rsize;
+ if (server->rsize <= 0)
+ server->rsize = NFS_DEF_FILE_IO_BUFFER_SIZE;
+ else if (server->rsize >= NFS_MAX_FILE_IO_BUFFER_SIZE)
+ server->rsize = NFS_MAX_FILE_IO_BUFFER_SIZE;
+ server->wsize = data->wsize;
+ if (server->wsize <= 0)
+ server->wsize = NFS_DEF_FILE_IO_BUFFER_SIZE;
+ else if (server->wsize >= NFS_MAX_FILE_IO_BUFFER_SIZE)
+ server->wsize = NFS_MAX_FILE_IO_BUFFER_SIZE;
+ server->timeo = data->timeo*HZ/10;
+ server->retrans = data->retrans;
+ server->acregmin = data->acregmin*HZ;
+ server->acregmax = data->acregmax*HZ;
+ server->acdirmin = data->acdirmin*HZ;
+ server->acdirmax = data->acdirmax*HZ;
+ strcpy(server->hostname, data->hostname);
+ sb->u.nfs_sb.s_root = data->root;
+ unlock_super(sb);
+ if (!(sb->s_mounted = nfs_fhget(sb, &data->root, NULL))) {
+ sb->s_dev = 0;
+ printk("nfs_read_super: get root inode failed\n");
+ return NULL;
+ }
+ return sb;
+}
+
+void nfs_statfs(struct super_block *sb, struct statfs *buf)
+{
+ int error;
+ struct nfs_fsinfo res;
+
+ put_fs_long(NFS_SUPER_MAGIC, &buf->f_type);
+ error = nfs_proc_statfs(&sb->u.nfs_sb.s_server, &sb->u.nfs_sb.s_root,
+ &res);
+ if (error) {
+ if (error != -EINTR)
+ printk("nfs_statfs: statfs error = %d\n", -error);
+ res.bsize = res.blocks = res.bfree = res.bavail = 0;
+ }
+ put_fs_long(res.bsize, &buf->f_bsize);
+ put_fs_long(res.blocks, &buf->f_blocks);
+ put_fs_long(res.bfree, &buf->f_bfree);
+ put_fs_long(res.bavail, &buf->f_bavail);
+#if 0
+ put_fs_long(-1, &buf->f_files);
+ put_fs_long(-1, &buf->f_ffree);
+#else
+ put_fs_long(0, &buf->f_files);
+ put_fs_long(0, &buf->f_ffree);
+#endif
+}
+
+/*
+ * This is our own version of iget that looks up inodes by file handle
+ * instead of inode number. We use this technique instead of using
+ * the vfs read_inode function because there is no way to pass the
+ * file handle or current attributes into the read_inode function.
+ * We just have to be careful not to subvert iget's special handling
+ * of mount points.
+ */
+
+struct inode *nfs_fhget(struct super_block *sb, struct nfs_fh *fhandle,
+ struct nfs_fattr *fattr)
+{
+ struct nfs_fattr newfattr;
+ int error;
+ struct inode *inode;
+
+ if (!sb) {
+ printk("nfs_fhget: super block is NULL\n");
+ return NULL;
+ }
+ if (!fattr) {
+ error = nfs_proc_getattr(&sb->u.nfs_sb.s_server, fhandle,
+ &newfattr);
+ if (error) {
+ printk("nfs_fhget: getattr error = %d\n", -error);
+ return NULL;
+ }
+ fattr = &newfattr;
+ }
+ if (!(inode = iget(sb, fattr->fileid))) {
+ printk("nfs_fhget: iget failed\n");
+ return NULL;
+ }
+ if (inode->i_dev == sb->s_dev) {
+ if (inode->i_ino != fattr->fileid) {
+ printk("nfs_fhget: unexpected inode from iget\n");
+ return inode;
+ }
+ *NFS_FH(inode) = *fhandle;
+ nfs_refresh_inode(inode, fattr);
+ }
+ return inode;
+}
+
+int nfs_notify_change(struct inode *inode)
+{
+ struct nfs_sattr sattr;
+ struct nfs_fattr fattr;
+ int error;
+
+ sattr.mode = inode->i_mode;
+ sattr.uid = inode->i_uid;
+ sattr.gid = inode->i_gid;
+ sattr.size = S_ISREG(inode->i_mode) ? inode->i_size : -1;
+ sattr.mtime.seconds = inode->i_mtime;
+ sattr.mtime.useconds = 0;
+ sattr.atime.seconds = inode->i_atime;
+ sattr.atime.useconds = 0;
+ error = nfs_proc_setattr(NFS_SERVER(inode), NFS_FH(inode),
+ &sattr, &fattr);
+ if (!error)
+ nfs_refresh_inode(inode, &fattr);
+ inode->i_dirt = 0;
+ return error;
+}
+
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
new file mode 100644
index 0000000..45a5895
--- /dev/null
+++ b/fs/nfs/proc.c
@@ -0,0 +1,667 @@
+/*
+ * linux/fs/nfs/proc.c
+ *
+ * Copyright (C) 1992 Rick Sladkey
+ *
+ * OS-independent nfs remote procedure call functions
+ */
+
+/*
+ * Defining NFS_PROC_DEBUG causes a lookup of a file named
+ * "xyzzy" to toggle debugging. Just cd to an NFS-mounted
+ * filesystem and type 'ls xyzzy' to turn on debugging.
+ */
+
+#define NFS_PROC_DEBUG
+
+#include <linux/param.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/nfs_fs.h>
+#include <linux/utsname.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+
+#include <netinet/in.h>
+
+#ifdef NFS_PROC_DEBUG
+static int proc_debug = 0;
+#define PRINTK if (proc_debug) printk
+#else
+#define PRINTK (void)
+#endif
+
+static int *nfs_rpc_header(int *p, int procedure);
+static int *nfs_rpc_verify(int *p);
+static int nfs_stat_to_errno(int stat);
+
+/*
+ * Here are a bunch of xdr encode/decode functions that convert
+ * between machine dependent and xdr data formats.
+ */
+
+static inline int *xdr_encode_fhandle(int *p, struct nfs_fh *fhandle)
+{
+ *((struct nfs_fh *) p) = *fhandle;
+ p += (sizeof (*fhandle) + 3) >> 2;
+ return p;
+}
+
+static inline int *xdr_decode_fhandle(int *p, struct nfs_fh *fhandle)
+{
+ *fhandle = *((struct nfs_fh *) p);
+ p += (sizeof (*fhandle) + 3) >> 2;
+ return p;
+}
+
+static inline int *xdr_encode_string(int *p, char *string)
+{
+ int len, quadlen;
+
+ len = strlen(string);
+ quadlen = (len + 3) >> 2;
+ *p++ = htonl(len);
+ memcpy((char *) p, string, len);
+ memset(((char *) p) + len, '\0', (quadlen << 2) - len);
+ p += quadlen;
+ return p;
+}
+
+static inline int *xdr_decode_string(int *p, char *string)
+{
+ int len;
+
+ len = ntohl(*p++);
+ memcpy(string, (char *) p, len);
+ string[len] = '\0';
+ p += (len + 3) >> 2;
+ return p;
+}
+
+static inline int *xdr_encode_data(int *p, char *data, int len)
+{
+ int quadlen;
+
+ quadlen = (len + 3) >> 2;
+ *p++ = htonl(len);
+ memcpy((char *) p, data, len);
+ memset(((char *) p) + len, '\0', (quadlen << 2) - len);
+ p += quadlen;
+ return p;
+}
+
+static inline int *xdr_decode_data(int *p, char *data, int *lenp)
+{
+ int len;
+
+ len = *lenp = ntohl(*p++);
+ memcpy(data, (char *) p, len);
+ data[len] = '\0';
+ p += (len + 3) >> 2;
+ return p;
+}
+
+static int *xdr_decode_fattr(int *p, struct nfs_fattr *fattr)
+{
+ fattr->type = ntohl(*p++);
+ fattr->mode = ntohl(*p++);
+ fattr->nlink = ntohl(*p++);
+ fattr->uid = ntohl(*p++);
+ fattr->gid = ntohl(*p++);
+ fattr->size = ntohl(*p++);
+ fattr->blocksize = ntohl(*p++);
+ fattr->rdev = ntohl(*p++);
+ fattr->blocks = ntohl(*p++);
+ fattr->fsid = ntohl(*p++);
+ fattr->fileid = ntohl(*p++);
+ fattr->atime.seconds = ntohl(*p++);
+ fattr->atime.useconds = ntohl(*p++);
+ fattr->mtime.seconds = ntohl(*p++);
+ fattr->mtime.useconds = ntohl(*p++);
+ fattr->ctime.seconds = ntohl(*p++);
+ fattr->ctime.useconds = ntohl(*p++);
+ return p;
+}
+
+static int *xdr_encode_sattr(int *p, struct nfs_sattr *sattr)
+{
+ *p++ = htonl(sattr->mode);
+ *p++ = htonl(sattr->uid);
+ *p++ = htonl(sattr->gid);
+ *p++ = htonl(sattr->size);
+ *p++ = htonl(sattr->atime.seconds);
+ *p++ = htonl(sattr->atime.useconds);
+ *p++ = htonl(sattr->mtime.seconds);
+ *p++ = htonl(sattr->mtime.useconds);
+ return p;
+}
+
+static int *xdr_decode_entry(int *p, struct nfs_entry *entry)
+{
+ entry->fileid = ntohl(*p++);
+ p = xdr_decode_string(p, entry->name);
+ entry->cookie = ntohl(*p++);
+ entry->eof = 0;
+ return p;
+}
+
+static int *xdr_decode_fsinfo(int *p, struct nfs_fsinfo *res)
+{
+ res->tsize = ntohl(*p++);
+ res->bsize = ntohl(*p++);
+ res->blocks = ntohl(*p++);
+ res->bfree = ntohl(*p++);
+ res->bavail = ntohl(*p++);
+ return p;
+}
+
+int nfs_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
+ struct nfs_fattr *fattr)
+{
+ int *p, *p0;
+ int status;
+
+ PRINTK("NFS call getattr\n");
+ p = p0 = (int *) get_free_page(GFP_KERNEL);
+ p = nfs_rpc_header(p, NFSPROC_GETATTR);
+ p = xdr_encode_fhandle(p, fhandle);
+ if ((status = nfs_rpc_call(server, p0, p)) < 0) {
+ free_page((long) p0);
+ return status;
+ }
+ if (!(p = nfs_rpc_verify(p0)))
+ status = NFSERR_IO;
+ else if ((status = ntohl(*p++)) == NFS_OK) {
+ p = xdr_decode_fattr(p, fattr);
+ PRINTK("NFS reply getattr\n");
+ }
+ free_page((long) p0);
+ return -nfs_stat_to_errno(status);
+}
+
+int nfs_proc_setattr(struct nfs_server *server, struct nfs_fh *fhandle,
+ struct nfs_sattr *sattr, struct nfs_fattr *fattr)
+{
+ int *p, *p0;
+ int status;
+
+ PRINTK("NFS call setattr\n");
+ p = p0 = (int *) get_free_page(GFP_KERNEL);
+ p = nfs_rpc_header(p, NFSPROC_SETATTR);
+ p = xdr_encode_fhandle(p, fhandle);
+ p = xdr_encode_sattr(p, sattr);
+ if ((status = nfs_rpc_call(server, p0, p)) < 0) {
+ free_page((long) p0);
+ return status;
+ }
+ if (!(p = nfs_rpc_verify(p0)))
+ status = NFSERR_IO;
+ else if ((status = ntohl(*p++)) == NFS_OK) {
+ p = xdr_decode_fattr(p, fattr);
+ PRINTK("NFS reply setattr\n");
+ }
+ free_page((long) p0);
+ return -nfs_stat_to_errno(status);
+}
+
+int nfs_proc_lookup(struct nfs_server *server, struct nfs_fh *dir, char *name,
+ struct nfs_fh *fhandle, struct nfs_fattr *fattr)
+{
+ int *p, *p0;
+ int status;
+
+ PRINTK("NFS call lookup %s\n", name);
+#ifdef NFS_PROC_DEBUG
+ if (!strcmp(name, "xyzzy"))
+ proc_debug = 1 - proc_debug;
+#endif
+ p = p0 = (int *) get_free_page(GFP_KERNEL);
+ p = nfs_rpc_header(p, NFSPROC_LOOKUP);
+ p = xdr_encode_fhandle(p, dir);
+ p = xdr_encode_string(p, name);
+ if ((status = nfs_rpc_call(server, p0, p)) < 0) {
+ free_page((long) p0);
+ return status;
+ }
+ if (!(p = nfs_rpc_verify(p0)))
+ status = NFSERR_IO;
+ else if ((status = ntohl(*p++)) == NFS_OK) {
+ p = xdr_decode_fhandle(p, fhandle);
+ p = xdr_decode_fattr(p, fattr);
+ PRINTK("NFS reply lookup\n");
+ }
+ free_page((long) p0);
+ return -nfs_stat_to_errno(status);
+}
+
+int nfs_proc_readlink(struct nfs_server *server, struct nfs_fh *fhandle,
+ char *res)
+{
+ int *p, *p0;
+ int status;
+
+ PRINTK("NFS call readlink\n");
+ p = p0 = (int *) get_free_page(GFP_KERNEL);
+ p = nfs_rpc_header(p, NFSPROC_READLINK);
+ p = xdr_encode_fhandle(p, fhandle);
+ if ((status = nfs_rpc_call(server, p0, p)) < 0) {
+ free_page((long) p0);
+ return status;
+ }
+ if (!(p = nfs_rpc_verify(p0)))
+ status = NFSERR_IO;
+ else if ((status = ntohl(*p++)) == NFS_OK) {
+ p = xdr_decode_string(p, res);
+ PRINTK("NFS reply readlink %s\n", res);
+ }
+ free_page((long) p0);
+ return -nfs_stat_to_errno(status);
+}
+
+int nfs_proc_read(struct nfs_server *server, struct nfs_fh *fhandle,
+ int offset, int count, char *data, struct nfs_fattr *fattr)
+{
+ int *p, *p0;
+ int status;
+ int len = 0; /* = 0 is for gcc */
+
+ PRINTK("NFS call read %d @ %d\n", count, offset);
+ p = p0 = (int *) get_free_page(GFP_KERNEL);
+ p = nfs_rpc_header(p, NFSPROC_READ);
+ p = xdr_encode_fhandle(p, fhandle);
+ *p++ = htonl(offset);
+ *p++ = htonl(count);
+ *p++ = htonl(count); /* traditional, could be any value */
+ if ((status = nfs_rpc_call(server, p0, p)) < 0) {
+ free_page((long) p0);
+ return status;
+ }
+ if (!(p = nfs_rpc_verify(p0)))
+ status = NFSERR_IO;
+ else if ((status = ntohl(*p++)) == NFS_OK) {
+ p = xdr_decode_fattr(p, fattr);
+ p = xdr_decode_data(p, data, &len);
+ PRINTK("NFS reply read %d\n", len);
+ }
+ free_page((long) p0);
+ return (status == NFS_OK) ? len : -nfs_stat_to_errno(status);
+}
+
+int nfs_proc_write(struct nfs_server *server, struct nfs_fh *fhandle,
+ int offset, int count, char *data, struct nfs_fattr *fattr)
+{
+ int *p, *p0;
+ int status;
+
+ PRINTK("NFS call write %d @ %d\n", count, offset);
+ p = p0 = (int *) get_free_page(GFP_KERNEL);
+ p = nfs_rpc_header(p, NFSPROC_WRITE);
+ p = xdr_encode_fhandle(p, fhandle);
+ *p++ = htonl(offset); /* traditional, could be any value */
+ *p++ = htonl(offset);
+ *p++ = htonl(count); /* traditional, could be any value */
+ p = xdr_encode_data(p, data, count);
+ if ((status = nfs_rpc_call(server, p0, p)) < 0) {
+ free_page((long) p0);
+ return status;
+ }
+ if (!(p = nfs_rpc_verify(p0)))
+ status = NFSERR_IO;
+ else if ((status = ntohl(*p++)) == NFS_OK) {
+ p = xdr_decode_fattr(p, fattr);
+ PRINTK("NFS reply write\n");
+ }
+ free_page((long) p0);
+ return -nfs_stat_to_errno(status);
+}
+
+int nfs_proc_create(struct nfs_server *server, struct nfs_fh *dir,
+ char *name, struct nfs_sattr *sattr,
+ struct nfs_fh *fhandle, struct nfs_fattr *fattr)
+{
+ int *p, *p0;
+ int status;
+
+ PRINTK("NFS call create %s\n", name);
+ p = p0 = (int *) get_free_page(GFP_KERNEL);
+ p = nfs_rpc_header(p, NFSPROC_CREATE);
+ p = xdr_encode_fhandle(p, dir);
+ p = xdr_encode_string(p, name);
+ p = xdr_encode_sattr(p, sattr);
+ if ((status = nfs_rpc_call(server, p0, p)) < 0) {
+ free_page((long) p0);
+ return status;
+ }
+ if (!(p = nfs_rpc_verify(p0)))
+ status = NFSERR_IO;
+ else if ((status = ntohl(*p++)) == NFS_OK) {
+ p = xdr_decode_fhandle(p, fhandle);
+ p = xdr_decode_fattr(p, fattr);
+ PRINTK("NFS reply create\n");
+ }
+ free_page((long) p0);
+ return -nfs_stat_to_errno(status);
+}
+
+int nfs_proc_remove(struct nfs_server *server, struct nfs_fh *dir, char *name)
+{
+ int *p, *p0;
+ int status;
+
+ PRINTK("NFS call remove %s\n", name);
+ p = p0 = (int *) get_free_page(GFP_KERNEL);
+ p = nfs_rpc_header(p, NFSPROC_REMOVE);
+ p = xdr_encode_fhandle(p, dir);
+ p = xdr_encode_string(p, name);
+ if ((status = nfs_rpc_call(server, p0, p)) < 0) {
+ free_page((long) p0);
+ return status;
+ }
+ if (!(p = nfs_rpc_verify(p0)))
+ status = NFSERR_IO;
+ else if ((status = ntohl(*p++)) == NFS_OK) {
+ PRINTK("NFS reply remove\n");
+ }
+ free_page((long) p0);
+ return -nfs_stat_to_errno(status);
+}
+
+int nfs_proc_rename(struct nfs_server *server,
+ struct nfs_fh *old_dir, char *old_name,
+ struct nfs_fh *new_dir, char *new_name)
+{
+ int *p, *p0;
+ int status;
+
+ PRINTK("NFS call rename %s -> %s\n", old_name, new_name);
+ p = p0 = (int *) get_free_page(GFP_KERNEL);
+ p = nfs_rpc_header(p, NFSPROC_RENAME);
+ p = xdr_encode_fhandle(p, old_dir);
+ p = xdr_encode_string(p, old_name);
+ p = xdr_encode_fhandle(p, new_dir);
+ p = xdr_encode_string(p, new_name);
+ if ((status = nfs_rpc_call(server, p0, p)) < 0) {
+ free_page((long) p0);
+ return status;
+ }
+ if (!(p = nfs_rpc_verify(p0)))
+ status = NFSERR_IO;
+ else if ((status = ntohl(*p++)) == NFS_OK) {
+ PRINTK("NFS reply rename\n");
+ }
+ free_page((long) p0);
+ return -nfs_stat_to_errno(status);
+}
+
+int nfs_proc_link(struct nfs_server *server, struct nfs_fh *fhandle,
+ struct nfs_fh *dir, char *name)
+{
+ int *p, *p0;
+ int status;
+
+ PRINTK("NFS call link %s\n", name);
+ p = p0 = (int *) get_free_page(GFP_KERNEL);
+ p = nfs_rpc_header(p, NFSPROC_LINK);
+ p = xdr_encode_fhandle(p, fhandle);
+ p = xdr_encode_fhandle(p, dir);
+ p = xdr_encode_string(p, name);
+ if ((status = nfs_rpc_call(server, p0, p)) < 0) {
+ free_page((long) p0);
+ return status;
+ }
+ if (!(p = nfs_rpc_verify(p0)))
+ status = NFSERR_IO;
+ else if ((status = ntohl(*p++)) == NFS_OK) {
+ PRINTK("NFS reply link\n");
+ }
+ free_page((long) p0);
+ return -nfs_stat_to_errno(status);
+}
+
+int nfs_proc_symlink(struct nfs_server *server, struct nfs_fh *dir,
+ char *name, char *path, struct nfs_sattr *sattr)
+{
+ int *p, *p0;
+ int status;
+
+ PRINTK("NFS call symlink %s -> %s\n", name, path);
+ p = p0 = (int *) get_free_page(GFP_KERNEL);
+ p = nfs_rpc_header(p, NFSPROC_SYMLINK);
+ p = xdr_encode_fhandle(p, dir);
+ p = xdr_encode_string(p, name);
+ p = xdr_encode_string(p, path);
+ p = xdr_encode_sattr(p, sattr);
+ if ((status = nfs_rpc_call(server, p0, p)) < 0) {
+ free_page((long) p0);
+ return status;
+ }
+ if (!(p = nfs_rpc_verify(p0)))
+ status = NFSERR_IO;
+ else if ((status = ntohl(*p++)) == NFS_OK) {
+ PRINTK("NFS reply symlink\n");
+ }
+ free_page((long) p0);
+ return -nfs_stat_to_errno(status);
+}
+
+int nfs_proc_mkdir(struct nfs_server *server, struct nfs_fh *dir,
+ char *name, struct nfs_sattr *sattr,
+ struct nfs_fh *fhandle, struct nfs_fattr *fattr)
+{
+ int *p, *p0;
+ int status;
+
+ PRINTK("NFS call mkdir %s\n", name);
+ p = p0 = (int *) get_free_page(GFP_KERNEL);
+ p = nfs_rpc_header(p, NFSPROC_MKDIR);
+ p = xdr_encode_fhandle(p, dir);
+ p = xdr_encode_string(p, name);
+ p = xdr_encode_sattr(p, sattr);
+ if ((status = nfs_rpc_call(server, p0, p)) < 0) {
+ free_page((long) p0);
+ return status;
+ }
+ if (!(p = nfs_rpc_verify(p0)))
+ status = NFSERR_IO;
+ else if ((status = ntohl(*p++)) == NFS_OK) {
+ p = xdr_decode_fhandle(p, fhandle);
+ p = xdr_decode_fattr(p, fattr);
+ PRINTK("NFS reply mkdir\n");
+ }
+ free_page((long) p0);
+ return -nfs_stat_to_errno(status);
+}
+
+int nfs_proc_rmdir(struct nfs_server *server, struct nfs_fh *dir, char *name)
+{
+ int *p, *p0;
+ int status;
+
+ PRINTK("NFS call rmdir %s\n", name);
+ p = p0 = (int *) get_free_page(GFP_KERNEL);
+ p = nfs_rpc_header(p, NFSPROC_RMDIR);
+ p = xdr_encode_fhandle(p, dir);
+ p = xdr_encode_string(p, name);
+ if ((status = nfs_rpc_call(server, p0, p)) < 0) {
+ free_page((long) p0);
+ return status;
+ }
+ if (!(p = nfs_rpc_verify(p0)))
+ status = NFSERR_IO;
+ else if ((status = ntohl(*p++)) == NFS_OK) {
+ PRINTK("NFS reply rmdir\n");
+ }
+ free_page((long) p0);
+ return -nfs_stat_to_errno(status);
+}
+
+int nfs_proc_readdir(struct nfs_server *server, struct nfs_fh *fhandle,
+ int cookie, int count, struct nfs_entry *entry)
+{
+ int *p, *p0;
+ int status;
+ int i = 0; /* = 0 is for gcc */
+ int size;
+ int eof;
+
+ PRINTK("NFS call readdir %d @ %d\n", count, cookie);
+ size = server->rsize;
+ p = p0 = (int *) get_free_page(GFP_KERNEL);
+ p = nfs_rpc_header(p, NFSPROC_READDIR);
+ p = xdr_encode_fhandle(p, fhandle);
+ *p++ = htonl(cookie);
+ *p++ = htonl(size);
+ if ((status = nfs_rpc_call(server, p0, p)) < 0) {
+ free_page((long) p0);
+ return status;
+ }
+ if (!(p = nfs_rpc_verify(p0)))
+ status = NFSERR_IO;
+ else if ((status = ntohl(*p++)) == NFS_OK) {
+ for (i = 0; i < count && *p++; i++)
+ p = xdr_decode_entry(p, entry++);
+ eof = (i == count && !*p++ && *p++) || (i < count && *p++);
+ if (eof && i)
+ entry[-1].eof = 1;
+ PRINTK("NFS reply readdir %d %s\n", i, eof ? "eof" : "");
+ }
+ free_page((long) p0);
+ return (status == NFS_OK) ? i : -nfs_stat_to_errno(status);
+}
+
+int nfs_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
+ struct nfs_fsinfo *res)
+{
+ int *p, *p0;
+ int status;
+
+ PRINTK("NFS call statfs\n");
+ p = p0 = (int *) get_free_page(GFP_KERNEL);
+ p = nfs_rpc_header(p, NFSPROC_STATFS);
+ p = xdr_encode_fhandle(p, fhandle);
+ if ((status = nfs_rpc_call(server, p0, p)) < 0) {
+ free_page((long) p0);
+ return status;
+ }
+ if (!(p = nfs_rpc_verify(p0)))
+ status = NFSERR_IO;
+ else if ((status = ntohl(*p++)) == NFS_OK) {
+ p = xdr_decode_fsinfo(p, res);
+ PRINTK("NFS reply statfs\n");
+ }
+ free_page((long) p0);
+ return -nfs_stat_to_errno(status);
+}
+
+/*
+ * Here are a few RPC-assist functions.
+ */
+
+static int *nfs_rpc_header(int *p, int procedure)
+{
+ int *p1, *p2;
+ int i;
+ static int xid = 0;
+ unsigned char *sys = system_utsname.nodename;
+
+ if (xid == 0) {
+ xid = CURRENT_TIME;
+ xid ^= (sys[3]<<24) | (sys[2]<<16) | (sys[1]<<8) | sys[0];
+ }
+ *p++ = htonl(++xid);
+ *p++ = htonl(RPC_CALL);
+ *p++ = htonl(RPC_VERSION);
+ *p++ = htonl(NFS_PROGRAM);
+ *p++ = htonl(NFS_VERSION);
+ *p++ = htonl(procedure);
+ *p++ = htonl(RPC_AUTH_UNIX);
+ p1 = p++;
+ *p++ = htonl(CURRENT_TIME); /* traditional, could be anything */
+ p = xdr_encode_string(p, sys);
+ *p++ = htonl(current->euid);
+ *p++ = htonl(current->egid);
+ p2 = p++;
+ for (i = 0; i < 16 && i < NGROUPS && current->groups[i] != NOGROUP; i++)
+ *p++ = htonl(current->groups[i]);
+ *p2 = htonl(i);
+ *p1 = htonl((p - (p1 + 1)) << 2);
+ *p++ = htonl(RPC_AUTH_NULL);
+ *p++ = htonl(0);
+ return p;
+}
+
+static int *nfs_rpc_verify(int *p)
+{
+ int n;
+
+ p++;
+ if (ntohl(*p++) != RPC_REPLY) {
+ printk("not an RPC reply\n");
+ return 0;
+ }
+ if (ntohl(*p++) != RPC_MSG_ACCEPTED) {
+ printk("RPC call rejected\n");
+ return 0;
+ }
+ if ((n = ntohl(*p++)) != RPC_AUTH_NULL && n != RPC_AUTH_UNIX) {
+ printk("reply with unknown RPC authentication type\n");
+ return 0;
+ }
+ n = ntohl(*p++);
+ p += (n + 3) >> 2;
+ if (ntohl(*p++) != RPC_SUCCESS) {
+ printk("RPC call failed\n");
+ return 0;
+ }
+ return p;
+}
+
+/*
+ * We need to translate between nfs status return values and
+ * the local errno values which may not be the same.
+ */
+
+#ifndef EDQUOT
+#define EDQUOT ENOSPC
+#endif
+
+static struct {
+ enum nfs_stat stat;
+ int errno;
+} nfs_errtbl[] = {
+ { NFS_OK, 0 },
+ { NFSERR_PERM, EPERM },
+ { NFSERR_NOENT, ENOENT },
+ { NFSERR_IO, EIO },
+ { NFSERR_NXIO, ENXIO },
+ { NFSERR_ACCES, EACCES },
+ { NFSERR_EXIST, EEXIST },
+ { NFSERR_NODEV, ENODEV },
+ { NFSERR_NOTDIR, ENOTDIR },
+ { NFSERR_ISDIR, EISDIR },
+ { NFSERR_FBIG, EFBIG },
+ { NFSERR_NOSPC, ENOSPC },
+ { NFSERR_ROFS, EROFS },
+ { NFSERR_NAMETOOLONG, ENAMETOOLONG },
+ { NFSERR_NOTEMPTY, ENOTEMPTY },
+ { NFSERR_DQUOT, EDQUOT },
+ { NFSERR_STALE, ESTALE },
+ { NFSERR_WFLUSH, EIO },
+ { -1, EIO }
+};
+
+static int nfs_stat_to_errno(int stat)
+{
+ int errno;
+ int i;
+
+ errno = EIO;
+ for (i = 0; nfs_errtbl[i].stat != -1; i++) {
+ if (nfs_errtbl[i].stat == stat) {
+ errno = nfs_errtbl[i].errno;
+ break;
+ }
+ }
+ return errno;
+}
+
diff --git a/fs/nfs/sock.c b/fs/nfs/sock.c
new file mode 100644
index 0000000..592607c
--- /dev/null
+++ b/fs/nfs/sock.c
@@ -0,0 +1,163 @@
+/*
+ * linux/fs/nfs/sock.c
+ *
+ * Copyright (C) 1992 Rick Sladkey
+ *
+ * low-level nfs remote procedure call interface
+ */
+
+#include <linux/sched.h>
+#include <linux/nfs_fs.h>
+#include <linux/errno.h>
+#include <linux/socket.h>
+#include <linux/fcntl.h>
+
+#include <netinet/in.h>
+
+#include "../../net/kern_sock.h"
+
+extern struct socket *socki_lookup(struct inode *inode);
+
+/*
+ * We violate some modularity principles here by poking around
+ * in some socket internals. Besides having to call socket
+ * functions from kernel-space instead of user space, the socket
+ * interface does not lend itself well to being cleanly called
+ * without a file descriptor. Since the nfs calls can run on
+ * behalf of any process, the superblock maintains a file pointer
+ * to the server socket.
+ */
+
+static int do_nfs_rpc_call(struct nfs_server *server, int *start, int *end)
+{
+ struct file *file;
+ struct inode *inode;
+ struct socket *sock;
+ unsigned short fs;
+ int result;
+ int xid;
+ int len;
+ select_table wait_table;
+ struct select_table_entry entry;
+ int (*select) (struct inode *, struct file *, int, select_table *);
+ int init_timeout, max_timeout;
+ int timeout;
+ int retrans;
+ int major_timeout_seen;
+ char *server_name;
+ int n;
+
+ xid = start[0];
+ len = ((char *) end) - ((char *) start);
+ file = server->file;
+ inode = file->f_inode;
+ select = file->f_op->select;
+ sock = socki_lookup(inode);
+ init_timeout = server->timeo;
+ max_timeout = NFS_MAX_RPC_TIMEOUT*HZ/10;
+ retrans = server->retrans;
+ major_timeout_seen = 0;
+ server_name = server->hostname;
+ if (!sock) {
+ printk("nfs_rpc_call: socki_lookup failed\n");
+ return -EBADF;
+ }
+ __asm__("mov %%fs,%0":"=r" (fs));
+ __asm__("mov %0,%%fs"::"r" ((unsigned short) 0x10));
+ for (n = 0, timeout = init_timeout; ; n++, timeout <<= 1) {
+ result = sock->ops->send(sock, (void *) start, len, 0, 0);
+ if (result < 0) {
+ printk("nfs_rpc_call: send error = %d\n", result);
+ break;
+ }
+ re_select:
+ wait_table.nr = 0;
+ wait_table.entry = &entry;
+ current->state = TASK_INTERRUPTIBLE;
+ if (!select(inode, file, SEL_IN, &wait_table)
+ && !select(inode, file, SEL_IN, NULL)) {
+ if (timeout > max_timeout)
+ timeout = max_timeout;
+ current->timeout = jiffies + timeout;
+ schedule();
+ remove_wait_queue(entry.wait_address, &entry.wait);
+ current->state = TASK_RUNNING;
+ if (current->signal & ~current->blocked) {
+#if 0
+ /* doesn't work yet */
+ if (!(server->flags & NFS_MOUNT_INTR))
+ goto re_select;
+#endif
+ current->timeout = 0;
+ result = -EINTR;
+ break;
+ }
+ if (!current->timeout) {
+ if (n < retrans)
+ continue;
+ if (server->flags & NFS_MOUNT_SOFT) {
+ printk("NFS server %s not responding, "
+ "timed out", server_name);
+ result = -EIO;
+ break;
+ }
+ n = 0;
+ timeout = init_timeout;
+ init_timeout <<= 1;
+ if (!major_timeout_seen) {
+ printk("NFS server %s not responding, "
+ "still trying\n", server_name);
+ }
+ major_timeout_seen = 1;
+ continue;
+ }
+ else
+ current->timeout = 0;
+ }
+ else if (wait_table.nr)
+ remove_wait_queue(entry.wait_address, &entry.wait);
+ current->state = TASK_RUNNING;
+ result = sock->ops->recv(sock, (void *) start, 4096, 1, 0);
+ if (result < 0) {
+ if (result == -EAGAIN) {
+ printk("nfs_rpc_call: bad select ready\n");
+ goto re_select;
+ }
+ if (result != -ERESTARTSYS) {
+ printk("nfs_rpc_call: recv error = %d\n",
+ -result);
+ }
+ break;
+ }
+ if (*start == xid) {
+ if (major_timeout_seen)
+ printk("NFS server %s OK\n", server_name);
+ break;
+ }
+#if 0
+ printk("nfs_rpc_call: XID mismatch\n");
+#endif
+ }
+ __asm__("mov %0,%%fs"::"r" (fs));
+ return result;
+}
+
+/*
+ * For now we lock out other simulaneous nfs calls for the same filesytem
+ * because we are single-threaded and don't want to get mismatched
+ * RPC replies.
+ */
+
+int nfs_rpc_call(struct nfs_server *server, int *start, int *end)
+{
+ int result;
+
+ while (server->lock)
+ sleep_on(&server->wait);
+ server->lock = 1;
+ result = do_nfs_rpc_call(server, start, end);
+ server->lock = 0;
+ wake_up(&server->wait);
+ return result;
+}
+
diff --git a/fs/nfs/symlink.c b/fs/nfs/symlink.c
new file mode 100644
index 0000000..8e192cf
--- /dev/null
+++ b/fs/nfs/symlink.c
@@ -0,0 +1,110 @@
+/*
+ * linux/fs/nfs/symlink.c
+ *
+ * Copyright (C) 1992 Rick Sladkey
+ *
+ * nfs symlink handling code
+ */
+
+#include <asm/segment.h>
+
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/nfs_fs.h>
+#include <linux/stat.h>
+#include <linux/mm.h>
+
+static int nfs_readlink(struct inode *, char *, int);
+static int nfs_follow_link(struct inode *, struct inode *, int, int,
+ struct inode **);
+
+/*
+ * symlinks can't do much...
+ */
+struct inode_operations nfs_symlink_inode_operations = {
+ NULL, /* no file-operations */
+ NULL, /* create */
+ NULL, /* lookup */
+ NULL, /* link */
+ NULL, /* unlink */
+ NULL, /* symlink */
+ NULL, /* mkdir */
+ NULL, /* rmdir */
+ NULL, /* mknod */
+ NULL, /* rename */
+ nfs_readlink, /* readlink */
+ nfs_follow_link, /* follow_link */
+ NULL, /* bmap */
+ NULL /* truncate */
+};
+
+static int nfs_follow_link(struct inode *dir, struct inode *inode,
+ int flag, int mode, struct inode **res_inode)
+{
+ int error;
+ unsigned short fs;
+ char *res;
+
+ *res_inode = NULL;
+ if (!dir) {
+ dir = current->root;
+ dir->i_count++;
+ }
+ if (!inode) {
+ iput(dir);
+ return -ENOENT;
+ }
+ if (!S_ISLNK(inode->i_mode)) {
+ iput(dir);
+ *res_inode = inode;
+ return 0;
+ }
+ if (current->link_count > 5) {
+ iput(inode);
+ iput(dir);
+ return -ELOOP;
+ }
+ res = (char *) kmalloc(NFS_MAXPATHLEN + 1, GFP_KERNEL);
+ error = nfs_proc_readlink(NFS_SERVER(inode), NFS_FH(inode), res);
+ if (error) {
+ iput(inode);
+ iput(dir);
+ kfree_s(res, NFS_MAXPATHLEN + 1);
+ return error;
+ }
+ iput(inode);
+ __asm__("mov %%fs,%0":"=r" (fs));
+ __asm__("mov %0,%%fs"::"r" ((unsigned short) 0x10));
+ current->link_count++;
+ error = open_namei(res, flag, mode, res_inode, dir);
+ current->link_count--;
+ kfree_s(res, NFS_MAXPATHLEN + 1);
+ __asm__("mov %0,%%fs"::"r" (fs));
+ return error;
+}
+
+static int nfs_readlink(struct inode *inode, char *buffer, int buflen)
+{
+ int i;
+ char c;
+ int error;
+ char *res;
+
+ if (!S_ISLNK(inode->i_mode)) {
+ iput(inode);
+ return -EINVAL;
+ }
+ if (buflen > NFS_MAXPATHLEN)
+ buflen = NFS_MAXPATHLEN;
+ res = (char *) kmalloc(buflen + 1, GFP_KERNEL);
+ error = nfs_proc_readlink(NFS_SERVER(inode), NFS_FH(inode), res);
+ iput(inode);
+ if (error) {
+ kfree_s(res, buflen + 1);
+ return error;
+ }
+ for (i = 0; i < buflen && (c = res[i]); i++)
+ put_fs_byte(c,buffer++);
+ kfree_s(res, buflen + 1);
+ return i;
+}
diff --git a/fs/open.c b/fs/open.c
index 8f0bdff..27a4981 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -416,7 +416,7 @@ int close_fp(struct file *filp)
return 0;
}
inode = filp->f_inode;
- if (S_ISREG(inode->i_mode))
+ if (inode && S_ISREG(inode->i_mode))
fcntl_remove_locks(current, filp);
if (filp->f_count > 1) {
filp->f_count--;
diff --git a/fs/proc/Makefile b/fs/proc/Makefile
index efe8294..9af56d3 100644
--- a/fs/proc/Makefile
+++ b/fs/proc/Makefile
@@ -20,83 +20,14 @@ proc.o: $(OBJS)
$(LD) -r -o proc.o $(OBJS)
clean:
- rm -f core *.o *.a tmp_make
- for i in *.c;do rm -f `basename $$i .c`.s;done
+ rm -f core *.o *.a *.s
dep:
- sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
- $(CPP) -M *.c >> tmp_make
- cp tmp_make Makefile
+ $(CPP) -M *.c > .depend
-### Dependencies:
-array.o : array.c /usr/include/linux/types.h /usr/include/linux/errno.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/asm/segment.h \
- /usr/include/asm/io.h
-base.o : base.c /usr/include/asm/segment.h /usr/include/linux/errno.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
- /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
- /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
- /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
- /usr/include/linux/proc_fs.h /usr/include/linux/stat.h
-fd.o : fd.c /usr/include/asm/segment.h /usr/include/linux/errno.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
- /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
- /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
- /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
- /usr/include/linux/proc_fs.h /usr/include/linux/stat.h
-inode.o : inode.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/proc_fs.h /usr/include/linux/string.h \
- /usr/include/linux/stat.h /usr/include/linux/locks.h /usr/include/asm/system.h \
- /usr/include/asm/segment.h
-link.o : link.c /usr/include/asm/segment.h /usr/include/linux/errno.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
- /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
- /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
- /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
- /usr/include/linux/minix_fs.h /usr/include/linux/stat.h
-mem.o : mem.c /usr/include/linux/types.h /usr/include/linux/errno.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/asm/segment.h \
- /usr/include/asm/io.h
-root.o : root.c /usr/include/asm/segment.h /usr/include/linux/errno.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
- /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
- /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
- /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
- /usr/include/linux/proc_fs.h /usr/include/linux/stat.h
+#
+# include a dependency file if one exists
+#
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 49b77a1..3d8db0b 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -13,15 +13,20 @@
#include <asm/segment.h>
#include <asm/io.h>
+#define LOAD_INT(x) ((x) >> FSHIFT)
+#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
+
static int get_loadavg(char * buffer)
{
+ int a, b, c;
+
+ a = avenrun[0] + (FIXED_1/200);
+ b = avenrun[1] + (FIXED_1/200);
+ c = avenrun[2] + (FIXED_1/200);
return sprintf(buffer,"%d.%02d %d.%02d %d.%02d\n",
- avenrun[0] >> FSHIFT,
- (FIXED_1/2 + (avenrun[0] & (FIXED_1-1))*100) >> FSHIFT,
- avenrun[1] >> FSHIFT,
- (FIXED_1/2 + (avenrun[1] & (FIXED_1-1))*100) >> FSHIFT,
- avenrun[2] >> FSHIFT,
- (FIXED_1/2 + (avenrun[2] & (FIXED_1-1))*100) >> FSHIFT);
+ LOAD_INT(a), LOAD_FRAC(a),
+ LOAD_INT(b), LOAD_FRAC(b),
+ LOAD_INT(c), LOAD_FRAC(c));
}
static int get_uptime(char * buffer)
@@ -75,54 +80,31 @@ static unsigned long get_phys_addr(struct task_struct ** p, unsigned long ptr)
return page;
}
-static unsigned long get_long(struct task_struct ** p, unsigned long ptr)
-{
- unsigned long addr;
-
- if (ptr & 3)
- return 0;
- addr = get_phys_addr(p,ptr);
- if (!addr)
- return 0;
- return *(unsigned long *) addr;
-}
-
-static int get_char(struct task_struct ** p, unsigned long ptr)
+static int get_array(struct task_struct ** p, unsigned long start, unsigned long end, char * buffer)
{
unsigned long addr;
-
- addr = get_phys_addr(p,ptr);
- if (!addr)
- return -1;
- return *(unsigned char *) addr;
-}
-
-static int get_array(struct task_struct ** p, unsigned long ptr, char * buffer)
-{
- unsigned long tmp;
int size = 0, result = 0;
- unsigned long array;
char c;
- array = get_long(p,ptr);
- if (!ptr)
- return 0;
+ if (start >= end)
+ return result;
for (;;) {
- tmp = get_long(p,array);
- if (!tmp)
+ addr = get_phys_addr(p, start);
+ if (!addr)
return result;
- array += 4;
- while ((c = get_char(p,tmp++)) > 0) {
+ do {
+ c = *(char *) addr;
+ if (!c)
+ result = size;
if (size < PAGE_SIZE)
buffer[size++] = c;
else
return result;
- }
- if (c < 0)
- return result;
- result = size;
- if (size < PAGE_SIZE)
- buffer[size++] = '\0';
+ addr++;
+ start++;
+ if (start >= end)
+ return result;
+ } while (!(addr & 0xfff));
}
}
@@ -132,7 +114,7 @@ static int get_env(int pid, char * buffer)
if (!p || !*p)
return 0;
- return get_array(p, (*p)->start_stack+8, buffer);
+ return get_array(p, (*p)->env_start, (*p)->env_end, buffer);
}
static int get_arg(int pid, char * buffer)
@@ -141,7 +123,7 @@ static int get_arg(int pid, char * buffer)
if (!p || !*p)
return 0;
- return get_array(p, (*p)->start_stack+4, buffer);
+ return get_array(p, (*p)->arg_start, (*p)->arg_end, buffer);
}
static int get_stat(int pid, char * buffer)
@@ -175,7 +157,6 @@ static int array_read(struct inode * inode, struct file * file,char * buf, int c
if (count < 0)
return -EINVAL;
page = (char *) get_free_page(GFP_KERNEL);
- *page = 0;
if (!page)
return -ENOMEM;
type = inode->i_ino;
@@ -201,10 +182,13 @@ static int array_read(struct inode * inode, struct file * file,char * buf, int c
length = get_stat(pid, page);
break;
default:
+ free_page((unsigned long) page);
return -EBADF;
}
- if (file->f_pos >= length)
+ if (file->f_pos >= length) {
+ free_page((unsigned long) page);
return 0;
+ }
if (count + file->f_pos > length)
count = length - file->f_pos;
end = count + file->f_pos;
diff --git a/fs/proc/root.c b/fs/proc/root.c
index 8ad4eca..2aa78a6 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -53,7 +53,8 @@ static struct proc_dir_entry root_dir[] = {
{ 1,2,".." },
{ 2,7,"loadavg" },
{ 3,6,"uptime" },
- { 4,7,"meminfo" }
+ { 4,7,"meminfo" },
+ { 5,4,"self" } /* will change inode # */
};
#define NR_ROOT_DIRENTRY ((sizeof (root_dir))/(sizeof (root_dir[0])))
@@ -80,6 +81,8 @@ static int proc_lookuproot(struct inode * dir,const char * name, int len,
*result = dir;
return 0;
}
+ if (ino == 5) /* self modifying inode ... */
+ ino = (current->pid << 16) + 2;
} else {
pid = 0;
while (len-- > 0) {
diff --git a/include/asm/irq.h b/include/asm/irq.h
index fe82a03..a492dc8 100644
--- a/include/asm/irq.h
+++ b/include/asm/irq.h
@@ -113,6 +113,7 @@ __asm__( \
"pushl $-"#nr"-2\n\t" \
SAVE_ALL \
ACK_##chip(mask) \
+ "incl _intr_count\n\t"\
"sti\n\t" \
"movl %esp,%ebx\n\t" \
"pushl %ebx\n\t" \
@@ -121,6 +122,7 @@ __asm__( \
"addl $8,%esp\n\t" \
"cli\n\t" \
UNBLK_##chip(mask) \
+ "call _do_bottom_half\n\t"\
"jmp ret_from_sys_call\n" \
"\n.align 2\n" \
"_fast_IRQ" #nr "_interrupt:\n\t" \
diff --git a/include/linux/autoconf.h b/include/linux/autoconf.h
new file mode 100644
index 0000000..172aac3
--- /dev/null
+++ b/include/linux/autoconf.h
@@ -0,0 +1,33 @@
+/*
+ * Automatically generated C config: don't edit
+ */
+
+/*
+ * General setup
+ */
+#define CONFIG_BLK_DEV_HD 1
+#define CONFIG_TCPIP 1
+#define CONFIG_PROFILE 1
+#define CONFIG_MAX_16M 1
+
+/*
+ * SCSI support
+ */
+
+/*
+ * SCSI support type (disk, tape, CDrom)
+ */
+
+/*
+ * SCSI low-level drivers
+ */
+
+/*
+ * Filesystems
+ */
+#define CONFIG_MINIX_FS 1
+#define CONFIG_PROC_FS 1
+
+/*
+ * Various character device drivers..
+ */
diff --git a/include/linux/config.dist.h b/include/linux/config.dist.h
deleted file mode 100644
index f933e36..0000000
--- a/include/linux/config.dist.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef _LINUX_CONFIG_DIST_H
-#define _LINUX_CONFIG_DIST_H
-#ifdef CONFIG_DISTRIBUTION
-
-#undef CONFIG_SCSI
-#define CONFIG_SCSI
-
-#undef CONFIG_SCSI_AHA1542
-#define CONFIG_SCSI_AHA1542
-#undef CONFIG_SCSI_AHA1740
-#define CONFIG_SCSI_AHA1740
-#undef CONFIG_SCSI_CSC
-#define CONFIG_SCSI_CSC
-#undef CONFIG_SCSI_DTC
-#define CONFIG_SCSI_DTC
-#undef CONFIG_SCSI_FUTURE_DOMAIN
-#define CONFIG_SCSI_FUTURE_DOMAIN
-#undef CONFIG_SCSI_SEAGATE
-#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_SR
-#define CONFIG_BLK_DEV_SR
-#undef CONFIG_BLK_DEV_ST
-#define CONFIG_BLK_DEV_ST
-
-#endif
-#endif
diff --git a/include/linux/config.h b/include/linux/config.h
index 59a636a..59d2c69 100644
--- a/include/linux/config.h
+++ b/include/linux/config.h
@@ -1,7 +1,7 @@
#ifndef _LINUX_CONFIG_H
#define _LINUX_CONFIG_H
-#define CONFIG_DISTRIBUTION
+#include <linux/autoconf.h>
/*
* Defines for what uname() should return
@@ -66,57 +66,7 @@
*/
#undef HD_TYPE
-
-#define CONFIG_BLK_DEV_HD
-#undef CONFIG_BLK_DEV_SD
-#undef CONFIG_BLK_DEV_ST
-#undef CONFIG_BLK_DEV_SR
-
-
-/*
- Choose supported SCSI adapters here.
-*/
-
-#undef CONFIG_SCSI_AHA1542
-#undef CONFIG_SCSI_AHA1740
-#undef CONFIG_SCSI_ALWAYS
-#undef CONFIG_SCSI_CSC
-#undef CONFIG_SCSI_DTC
-#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_SR) || \
-defined(CONFIG_CHR_DEV_ST)
-#ifndef CONFIG_SCSI
- #define CONFIG_SCSI
-#endif
-
-#if !defined(CONFIG_SCSI_AHA1542) && !defined(CONFIG_SCSI_AHA1740) && !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
-
-/*
- * Choose filesystems here.
- */
-
-#define MINIX_FS
-#define EXT_FS
-#define MSDOS_FS
-#define PROC_FS
-#undef NFS_FS
-#undef ISO9660_FS
-
-#ifdef CONFIG_DISTRIBUTION
-#include <linux/config.dist.h>
-#else
-#include <linux/config.site.h>
-#endif
-
+
/*
File type specific stuff goes into this.
*/
diff --git a/include/linux/config.site.h b/include/linux/config.site.h
deleted file mode 100644
index e478a03..0000000
--- a/include/linux/config.site.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _LINUX_CONFIG_SITE_H
-#define _LINUX_CONFIG_SITE_H
-
-/*
- This configuration file contains site specific things, things
- that you have added and config.dist will not know about.
-*/
-
-#endif
diff --git a/include/linux/errno.h b/include/linux/errno.h
index 420d5ff..1a40c1a 100644
--- a/include/linux/errno.h
+++ b/include/linux/errno.h
@@ -41,7 +41,7 @@
#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 EWOULDBLOCK EAGAIN /* Operation would block */
#define ENOMSG 42 /* No message of desired type */
#define EIDRM 43 /* Identifier removed */
#define ECHRNG 44 /* Channel number out of range */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 3f66d6f..c00154d 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -138,6 +138,7 @@ struct buffer_head {
#include <linux/ext_fs_i.h>
#include <linux/msdos_fs_i.h>
#include <linux/iso_fs_i.h>
+#include <linux/nfs_fs_i.h>
struct inode {
dev_t i_dev;
@@ -175,6 +176,7 @@ struct inode {
struct ext_inode_info ext_i;
struct msdos_inode_info msdos_i;
struct iso_inode_info isofs_i;
+ struct nfs_inode_info nfs_i;
} u;
};
@@ -203,6 +205,7 @@ struct file_lock {
#include <linux/ext_fs_sb.h>
#include <linux/msdos_fs_sb.h>
#include <linux/iso_fs_sb.h>
+#include <linux/nfs_fs_sb.h>
struct super_block {
dev_t s_dev;
@@ -222,6 +225,7 @@ struct super_block {
struct ext_sb_info ext_sb;
struct msdos_sb_info msdos_sb;
struct isofs_sb_info isofs_sb;
+ struct nfs_sb_info nfs_sb;
} u;
};
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
new file mode 100644
index 0000000..f997e3c
--- /dev/null
+++ b/include/linux/interrupt.h
@@ -0,0 +1,24 @@
+/* interrupt.h */
+#ifndef _LINUX_INTERRUPT_H
+#define _LINUX_INTERRUPT_H
+
+struct bh_struct {
+ void (*routine)(void *);
+ void *data;
+};
+
+extern int bh_active;
+extern struct bh_struct bh_base[32];
+
+/* Who gets which entry in bh_base. Things which will occur most often
+ should come first. */
+enum {
+ TIMER_BH = 0,
+ CONSOLE_BH,
+ SERIAL_BH,
+ INET_BH
+};
+
+void do_bottom_half();
+
+#endif
diff --git a/include/linux/iso_fs.h b/include/linux/iso_fs.h
index 4461913..f95dc8b 100644
--- a/include/linux/iso_fs.h
+++ b/include/linux/iso_fs.h
@@ -170,7 +170,6 @@ extern void isofs_statfs(struct super_block *, struct statfs *);
extern int isofs_lseek(struct inode *, struct file *, off_t, int);
extern int isofs_read(struct inode *, struct file *, char *, int);
-extern int isofs_file_read(struct inode *, struct file *, char *, int);
extern int isofs_lookup_grandparent(struct inode *, int);
extern struct inode_operations isofs_file_inode_operations;
@@ -178,6 +177,7 @@ extern struct inode_operations isofs_dir_inode_operations;
extern struct inode_operations isofs_symlink_inode_operations;
extern struct inode_operations isofs_chrdev_inode_operations;
extern struct inode_operations isofs_blkdev_inode_operations;
+extern struct inode_operations isofs_fifo_inode_operations;
extern struct file_operations isofs_file_operations;
extern struct file_operations isofs_dir_operations;
diff --git a/include/linux/mouse.h b/include/linux/mouse.h
index 7e5014a..df4e427 100644
--- a/include/linux/mouse.h
+++ b/include/linux/mouse.h
@@ -1,11 +1,6 @@
#ifndef _LINUX_MOUSE_H
#define _LINUX_MOUSE_H
-/*
- * These are the minor numbers for the mice - undefine them
- * to get rid of the driver from the kernel binary..
- */
-
#define BUSMOUSE_MINOR 0
#define PSMOUSE_MINOR 1
#define MS_BUSMOUSE_MINOR 2
diff --git a/include/linux/mtio.h b/include/linux/mtio.h
index 47f803f..a1604da 100644
--- a/include/linux/mtio.h
+++ b/include/linux/mtio.h
@@ -46,7 +46,8 @@ struct mtop {
#define MTSETBLK 20 /* set block length (SCSI) */
#define MTSETDENSITY 21 /* set tape density (SCSI) */
-
+#define MTSEEK 22 /* seek to block (Tandberg, etc.) */
+#define MTTELL 23 /* tell block (Tandber, etc.) */
/* structure for MTIOCGET - mag tape get status command */
@@ -105,9 +106,18 @@ struct mt_tape_info {
}
+/* structure for MTIOCPOS - mag tape get position command */
+
+struct mtpos {
+ long mt_blkno; /* current block number */
+};
+
+
/* mag tape io control commands */
#define MTIOCTOP _IOW('m', 1, struct mtop) /* do a mag tape op */
#define MTIOCGET _IOR('m', 2, struct mtget) /* get tape status */
+#define MTIOCPOS _IOR('m', 3, struct mtpos) /* get tape position */
+
/* Generic Mag Tape (device independent) status macros for examining
* mt_gstat -- HP-UX compatible.
diff --git a/include/linux/nfs.h b/include/linux/nfs.h
new file mode 100644
index 0000000..af267f3
--- /dev/null
+++ b/include/linux/nfs.h
@@ -0,0 +1,164 @@
+#ifndef _LINUX_NFS_H
+#define _LINUX_NFS_H
+
+#define RPC_VERSION 2
+
+#define NFS_PORT 2049
+#define NFS_MAXDATA 8192
+#define NFS_MAXPATHLEN 1024
+#define NFS_MAXNAMLEN 255
+#define NFS_MAXGROUPS 16
+#define NFS_FHSIZE 32
+#define NFS_COOKIESIZE 4
+#define NFS_FIFO_DEV -1
+#define NFSMODE_FMT 0170000
+#define NFSMODE_DIR 0040000
+#define NFSMODE_CHR 0020000
+#define NFSMODE_BLK 0060000
+#define NFSMODE_REG 0100000
+#define NFSMODE_LNK 0120000
+#define NFSMODE_SOCK 0140000
+#define NFSMODE_FIFO 0010000
+
+enum rpc_auth_flavor {
+ RPC_AUTH_NULL = 0,
+ RPC_AUTH_UNIX = 1,
+ RPC_AUTH_SHORT = 2,
+};
+
+enum rpc_msg_type {
+ RPC_CALL = 0,
+ RPC_REPLY = 1,
+};
+
+enum rpc_reply_stat {
+ RPC_MSG_ACCEPTED = 0,
+ RPC_MSG_DENIED,
+};
+
+enum rpc_accept_stat {
+ RPC_SUCCESS = 0,
+ RPC_PROG_UNAVAIL = 1,
+ RPC_PROG_MISMATCH = 2,
+ RPC_PROC_UNAVAIL = 3,
+ RPC_GARBAGE_ARGS = 4,
+};
+
+enum rpc_reject_stat {
+ RPC_MISMATCH = 0,
+ RPC_AUTH_ERROR = 1,
+};
+
+enum rpc_auth_stat {
+ RPC_AUTH_BADCRED = 1,
+ RPC_AUTH_REJECTEDCRED = 2,
+ RPC_AUTH_BADVERF = 3,
+ RPC_AUTH_REJECTEDVERF = 4,
+ RPC_AUTH_TOOWEAK = 5,
+};
+
+enum nfs_stat {
+ NFS_OK = 0,
+ NFSERR_PERM = 1,
+ NFSERR_NOENT = 2,
+ NFSERR_IO = 5,
+ NFSERR_NXIO = 6,
+ NFSERR_ACCES = 13,
+ NFSERR_EXIST = 17,
+ NFSERR_NODEV = 19,
+ NFSERR_NOTDIR = 20,
+ NFSERR_ISDIR = 21,
+ NFSERR_FBIG = 27,
+ NFSERR_NOSPC = 28,
+ NFSERR_ROFS = 30,
+ NFSERR_NAMETOOLONG = 63,
+ NFSERR_NOTEMPTY = 66,
+ NFSERR_DQUOT = 69,
+ NFSERR_STALE = 70,
+ NFSERR_WFLUSH = 99,
+};
+
+enum nfs_ftype {
+ NFNON = 0,
+ NFREG = 1,
+ NFDIR = 2,
+ NFBLK = 3,
+ NFCHR = 4,
+ NFLNK = 5,
+ NFSOCK = 6,
+ NFBAD = 7,
+ NFFIFO = 8,
+};
+
+#define NFS_PROGRAM 100003
+#define NFS_VERSION 2
+#define NFSPROC_NULL 0
+#define NFSPROC_GETATTR 1
+#define NFSPROC_SETATTR 2
+#define NFSPROC_ROOT 3
+#define NFSPROC_LOOKUP 4
+#define NFSPROC_READLINK 5
+#define NFSPROC_READ 6
+#define NFSPROC_WRITECACHE 7
+#define NFSPROC_WRITE 8
+#define NFSPROC_CREATE 9
+#define NFSPROC_REMOVE 10
+#define NFSPROC_RENAME 11
+#define NFSPROC_LINK 12
+#define NFSPROC_SYMLINK 13
+#define NFSPROC_MKDIR 14
+#define NFSPROC_RMDIR 15
+#define NFSPROC_READDIR 16
+#define NFSPROC_STATFS 17
+
+struct nfs_fh {
+ char data[NFS_FHSIZE];
+};
+
+struct nfs_time {
+ u_int seconds;
+ u_int useconds;
+};
+
+struct nfs_fattr {
+ enum nfs_ftype type;
+ u_int mode;
+ u_int nlink;
+ u_int uid;
+ u_int gid;
+ u_int size;
+ u_int blocksize;
+ u_int rdev;
+ u_int blocks;
+ u_int fsid;
+ u_int fileid;
+ struct nfs_time atime;
+ struct nfs_time mtime;
+ struct nfs_time ctime;
+};
+
+struct nfs_sattr {
+ u_int mode;
+ u_int uid;
+ u_int gid;
+ u_int size;
+ struct nfs_time atime;
+ struct nfs_time mtime;
+};
+
+struct nfs_entry {
+ u_int fileid;
+ char *name;
+ int cookie;
+ int eof;
+};
+
+struct nfs_fsinfo {
+ u_int tsize;
+ u_int bsize;
+ u_int blocks;
+ u_int bfree;
+ u_int bavail;
+};
+
+#endif
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
new file mode 100644
index 0000000..1c04ed5
--- /dev/null
+++ b/include/linux/nfs_fs.h
@@ -0,0 +1,122 @@
+#ifndef _LINUX_NFS_FS_H
+#define _LINUX_NFS_FS_H
+
+/*
+ * linux/include/linux/nfs_fs.h
+ *
+ * Copyright (C) 1992 Rick Sladkey
+ *
+ * OS-specific nfs filesystem definitions and declarations
+ */
+
+#include <linux/nfs.h>
+
+#include <netinet/in.h>
+#include <linux/nfs_mount.h>
+
+/*
+ * The readdir cache size controls how many directory entries are cached.
+ * Its size is limited by the number of nfs_entry structures that can fit
+ * in one 4096-byte page, currently 256.
+ */
+
+#define NFS_READDIR_CACHE_SIZE 64
+
+/*
+ * WARNING! The I/O buffer size cannot be bigger than about 3900 for now.
+ * It needs to fit inside a 4096-byte page and leave room for the RPC and
+ * NFS headers. But it ought to at least be a multiple of 512 and probably
+ * should be a power of 2. I don't think Linux TCP/IP can handle more than
+ * about 1800 yet.
+ */
+
+#define NFS_MAX_FILE_IO_BUFFER_SIZE (7*512)
+#define NFS_DEF_FILE_IO_BUFFER_SIZE 1024
+
+/*
+ * The upper limit on timeouts for the exponential backoff algorithm
+ * in tenths of a second.
+ */
+
+#define NFS_MAX_RPC_TIMEOUT 600
+
+#define NFS_SUPER_MAGIC 0x6969
+
+#define NFS_SERVER(inode) (&(inode)->i_sb->u.nfs_sb.s_server)
+#define NFS_FH(inode) (&(inode)->u.nfs_i.fhandle)
+
+/* linux/fs/nfs/proc.c */
+
+extern int nfs_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
+ struct nfs_fattr *fattr);
+extern int nfs_proc_setattr(struct nfs_server *server, struct nfs_fh *fhandle,
+ struct nfs_sattr *sattr, struct nfs_fattr *fattr);
+extern int nfs_proc_lookup(struct nfs_server *server, struct nfs_fh *dir,
+ char *name, struct nfs_fh *fhandle,
+ struct nfs_fattr *fattr);
+extern int nfs_proc_readlink(struct nfs_server *server, struct nfs_fh *fhandle,
+ char *res);
+extern int nfs_proc_read(struct nfs_server *server, struct nfs_fh *fhandle,
+ int offset, int count, char *data,
+ struct nfs_fattr *fattr);
+extern int nfs_proc_write(struct nfs_server *server, struct nfs_fh *fhandle,
+ int offset, int count, char *data,
+ struct nfs_fattr *fattr);
+extern int nfs_proc_create(struct nfs_server *server, struct nfs_fh *dir,
+ char *name, struct nfs_sattr *sattr,
+ struct nfs_fh *fhandle, struct nfs_fattr *fattr);
+extern int nfs_proc_remove(struct nfs_server *server, struct nfs_fh *dir,
+ char *name);
+extern int nfs_proc_rename(struct nfs_server *server,
+ struct nfs_fh *old_dir, char *old_name,
+ struct nfs_fh *new_dir, char *new_name);
+extern int nfs_proc_link(struct nfs_server *server, struct nfs_fh *fhandle,
+ struct nfs_fh *dir, char *name);
+extern int nfs_proc_symlink(struct nfs_server *server, struct nfs_fh *dir,
+ char *name, char *path, struct nfs_sattr *sattr);
+extern int nfs_proc_mkdir(struct nfs_server *server, struct nfs_fh *dir,
+ char *name, struct nfs_sattr *sattr,
+ struct nfs_fh *fhandle, struct nfs_fattr *fattr);
+extern int nfs_proc_rmdir(struct nfs_server *server, struct nfs_fh *dir,
+ char *name);
+extern int nfs_proc_readdir(struct nfs_server *server, struct nfs_fh *fhandle,
+ int cookie, int count, struct nfs_entry *entry);
+extern int nfs_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
+ struct nfs_fsinfo *res);
+
+/* linux/fs/nfs/sock.c */
+
+extern int nfs_rpc_call(struct nfs_server *server, int *start, int *end);
+
+/* linux/fs/nfs/inode.c */
+
+extern struct super_block *nfs_read_super(struct super_block *sb, void *data);
+extern struct inode *nfs_fhget(struct super_block *sb, struct nfs_fh *fhandle,
+ struct nfs_fattr *fattr);
+extern void nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr);
+
+/* linux/fs/nfs/file.c */
+
+extern struct inode_operations nfs_file_inode_operations;
+
+/* linux/fs/nfs/dir.c */
+
+extern struct inode_operations nfs_dir_inode_operations;
+
+/* linux/fs/nfs/symlink.c */
+
+extern struct inode_operations nfs_symlink_inode_operations;
+
+/* linux/fs/nfs/chrdev.c */
+
+extern struct inode_operations nfs_chrdev_inode_operations;
+
+/* linux/fs/nfs/blkdev.c */
+
+extern struct inode_operations nfs_blkdev_inode_operations;
+
+/* linux/fs/nfs/fifo.c */
+
+extern struct inode_operations nfs_fifo_inode_operations;
+
+#endif
diff --git a/include/linux/nfs_fs_i.h b/include/linux/nfs_fs_i.h
new file mode 100644
index 0000000..d465286
--- /dev/null
+++ b/include/linux/nfs_fs_i.h
@@ -0,0 +1,13 @@
+#ifndef _NFS_FS_I
+#define _NFS_FS_I
+
+#include <linux/nfs.h>
+
+/*
+ * nfs fs inode data in memory
+ */
+struct nfs_inode_info {
+ struct nfs_fh fhandle;
+};
+
+#endif
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
new file mode 100644
index 0000000..25db9e8
--- /dev/null
+++ b/include/linux/nfs_fs_sb.h
@@ -0,0 +1,31 @@
+#ifndef _NFS_FS_SB
+#define _NFS_FS_SB
+
+#include <linux/nfs.h>
+
+struct nfs_server {
+ struct file *file;
+ int lock;
+ struct wait_queue *wait;
+ int flags;
+ int rsize;
+ int wsize;
+ int timeo;
+ int retrans;
+ int acregmin;
+ int acregmax;
+ int acdirmin;
+ int acdirmax;
+ char hostname[256];
+};
+
+/*
+ * nfs super-block data in memory
+ */
+
+struct nfs_sb_info {
+ struct nfs_server s_server;
+ struct nfs_fh s_root;
+};
+
+#endif
diff --git a/include/linux/nfs_mount.h b/include/linux/nfs_mount.h
new file mode 100644
index 0000000..ba75b35
--- /dev/null
+++ b/include/linux/nfs_mount.h
@@ -0,0 +1,48 @@
+#ifndef _LINUX_NFS_MOUNT_H
+#define _LINUX_NFS_MOUNT_H
+
+/*
+ * linux/include/linux/nfs_mount.h
+ *
+ * Copyright (C) 1992 Rick Sladkey
+ *
+ * structure passed from user-space to kernel-space during an nfs mount
+ */
+
+/*
+ * WARNING! Do not delete or change the order of these fields. If
+ * a new field is required then add it to the end. The version field
+ * tracks which fields are present. This will ensure some measure of
+ * mount-to-kernel version compatibilty. Most of these are used yet
+ * but here they are anyway.
+ */
+
+#define NFS_MOUNT_VERSION 1 /* current version */
+
+struct nfs_mount_data {
+ int version; /* 1 */
+ int fd; /* 1 */
+ struct nfs_fh root; /* 1 */
+ int flags; /* 1 */
+ int rsize; /* 1 */
+ int wsize; /* 1 */
+ int timeo; /* 1 */
+ int retrans; /* 1 */
+ int acregmin; /* 1 */
+ int acregmax; /* 1 */
+ int acdirmin; /* 1 */
+ int acdirmax; /* 1 */
+ struct sockaddr_in addr; /* 1 */
+ char hostname[256]; /* 1 */
+};
+
+/* bits in the flags field */
+
+#define NFS_MOUNT_SOFT 0x0001 /* 1 */
+#define NFS_MOUNT_INTR 0x0002 /* 1 */
+#define NFS_MOUNT_SECURE 0x0004 /* 1 */
+#define NFS_MOUNT_POSIX 0x0008 /* 1 */
+#define NFS_MOUNT_NOCTO 0x0010 /* 1 */
+#define NFS_MOUNT_NOAC 0x0020 /* 1 */
+
+#endif
diff --git a/include/linux/sched.h b/include/linux/sched.h
index b6fd6df..d52d65c 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -160,6 +160,7 @@ struct task_struct {
int dumpable:1;
int swappable:1;
unsigned long start_code,end_code,end_data,brk,start_stack;
+ unsigned long arg_start, arg_end, env_start, env_end;
long pid,pgrp,session,leader;
int groups[NGROUPS];
/*
@@ -226,6 +227,7 @@ struct task_struct {
/* signals */ 0,{{ 0, },},0,0,0, \
/* flags */ 0, \
/* ec,brk... */ 0,0,0,0,0,0,0,0, \
+/* argv.. */ 0,0,0,0, \
/* pid etc.. */ 0,0,0,0, \
/* suppl grps*/ {NOGROUP,}, \
/* proc links*/ &init_task,&init_task,NULL,NULL,NULL, \
@@ -290,9 +292,9 @@ extern int irqaction(unsigned int irq,struct sigaction * new);
#define FIRST_LDT_ENTRY (FIRST_TSS_ENTRY+1)
#define _TSS(n) ((((unsigned long) n)<<4)+(FIRST_TSS_ENTRY<<3))
#define _LDT(n) ((((unsigned long) n)<<4)+(FIRST_LDT_ENTRY<<3))
-#define ltr(n) __asm__("ltr %%ax"::"a" (_TSS(n)))
-#define lldt(n) __asm__("lldt %%ax"::"a" (_LDT(n)))
-#define str(n) \
+#define load_TR(n) __asm__("ltr %%ax"::"a" (_TSS(n)))
+#define load_ldt(n) __asm__("lldt %%ax"::"a" (_LDT(n)))
+#define store_TR(n) \
__asm__("str %%ax\n\t" \
"subl %2,%%eax\n\t" \
"shrl $4,%%eax" \
diff --git a/include/linux/soundcard.h b/include/linux/soundcard.h
new file mode 100644
index 0000000..60cfe07
--- /dev/null
+++ b/include/linux/soundcard.h
@@ -0,0 +1,234 @@
+#ifndef SOUNDCARD_H
+#define SOUNDCARD_H
+/*
+ * linux/soundcard.h
+ *
+ * Sound Card driver for Linux
+ *
+ * (C) Hannu Savolainen 1992
+ *
+ */
+
+/*
+ * Supported card ID numbers
+ */
+
+#define SNDCARD_ADLIB 1
+#define SNDCARD_SB 2
+#define SNDCARD_PAS 3
+
+/*
+ * IOCTL Commands. Suffix 0x4252 is string "SB".
+ */
+
+#define SNDCTL_CONFIGURE 0x00014252
+
+#define SNDCTL_FM_LOAD_INSTR 0x01014252
+/* #define SNDCTL_FM_RETURN_INSTR 0x01034252 */
+#define SNDCTL_SEQ_SYNC 0x01044252
+#define SNDCTL_SEQ_RESET 0x01054252
+#define SNDCTL_SYNTH_INFO 0x01064252
+#define SNDCTL_SEQ_TESTMIDI 0x01074252
+#define SNDCTL_SEQ_PERCMODE 0x01084252
+
+#define SNDCTL_DSP_SPEED 0x01114252
+#define SNDCTL_DSP_STEREO 0x01124252
+#define SNDCTL_DSP_GETBLKSIZE 0x01134252
+#define SNDCTL_DSP_SYNC 0x01144252
+#define SNDCTL_DSP_RESET 0x01154252
+#define SNDCTL_DSP_SAMPLESIZE 0x01164252
+/* 8, 12 or 16) */
+
+#define SEQ_FMNOTEOFF 0
+#define SEQ_FMNOTEON 1
+#define SEQ_WAIT 2
+#define SEQ_FMPGMCHANGE 3
+#define SEQ_SYNCTIMER 4
+#define SEQ_MIDIPUTC 5
+#define SEQ_DRUMON 6 /* Play percussive instrument */
+#define SEQ_DRUMOFF 7
+
+typedef unsigned char sbi_instr_data[16];
+
+struct sbi_instrument {
+ int channel; /* Channel to be programmed */
+ sbi_instr_data operators; /* Register settings for operator cells (.SBI format) */
+ };
+
+struct synth_info { /* Read only */
+ int synth_type;
+#define SYNTH_TYPE_FM 0
+
+ int synth_subtype;
+#define FM_TYPE_ADLIB 0
+#define FM_TYPE_OPL3 1
+
+ int perc_mode; /* 0=off 1=off */
+ int nr_voices;
+ int nr_drums;
+ int instr_bank_size;
+ int dummies[20]; /* Reserve space */
+ };
+/*
+ Definitions for a "universal" sound driver
+ by Craig metz (cmetz@thor.tjhsst.edu)
+*/
+
+/*
+ IOCTL requests take the general form of a base address plus
+ a device type plus a request type. The base address fills the
+ top three bytes of the request longword and is formed from the
+ letters 'SND'. The top nybble of the remaining byte indicates
+ the device type to be interacted with, and the request type
+ indicates what the device needs to do, and bit 3 of the lower
+ nybble distinguishes read and write.
+
+ IOCTL Calling Form:
+
+ ioctl(fh, SOUND_call, &parameter);
+*/
+
+#define SOUND_BASE 0x534E4400
+
+#define SOUND_READ 0x00000000
+#define SOUND_WRITE 0x00000008
+
+/*
+ Mixer control - device type 0
+
+ All parameters are of type "unsigned short int" - The LSB is the
+ left value, the MSB is the right value. Both are in percents, 0
+ being mute and 100 being full power. In the event that the card
+ only supports mono mixer control, the LSB will be the value used.
+*/
+
+#define SOUND_MIXER 0x00
+#define SOUND_MIXER_TYPE unsigned short int
+
+#define SOUND_MIXER_VOLUME 0x0
+#define SOUND_MIXER_BASS 0x1
+#define SOUND_MIXER_TREBLE 0x2
+#define SOUND_MIXER_MIDI 0x3
+#define SOUND_MIXER_PCM 0x4
+#define SOUND_MIXER_SPEAKER 0x5
+#define SOUND_MIXER_LINE 0x6
+#define SOUND_MIXER_MIC 0x7
+
+#define SOUND_MIXER_READ_VOLUME (SOUND_BASE | SOUND_MIXER | SOUND_READ | SOUND_MIXER_VOLUME )
+#define SOUND_MIXER_READ_BASS (SOUND_BASE | SOUND_MIXER | SOUND_READ | SOUND_MIXER_BASS )
+#define SOUND_MIXER_READ_TREBLE (SOUND_BASE | SOUND_MIXER | SOUND_READ | SOUND_MIXER_TREBLE )
+#define SOUND_MIXER_READ_MIDI (SOUND_BASE | SOUND_MIXER | SOUND_READ | SOUND_MIXER_MIDI )
+#define SOUND_MIXER_READ_PCM (SOUND_BASE | SOUND_MIXER | SOUND_READ | SOUND_MIXER_PCM )
+#define SOUND_MIXER_READ_SPEAKER (SOUND_BASE | SOUND_MIXER | SOUND_READ | SOUND_MIXER_SPEAKER)
+#define SOUND_MIXER_READ_LINE (SOUND_BASE | SOUND_MIXER | SOUND_READ | SOUND_MIXER_LINE )
+#define SOUND_MIXER_READ_MIC (SOUND_BASE | SOUND_MIXER | SOUND_READ | SOUND_MIXER_MIC )
+
+#define SOUND_MIXER_WRITE_VOLUME (SOUND_BASE | SOUND_MIXER | SOUND_WRITE | SOUND_MIXER_VOLUME )
+#define SOUND_MIXER_WRITE_BASS (SOUND_BASE | SOUND_MIXER | SOUND_WRITE | SOUND_MIXER_BASS )
+#define SOUND_MIXER_WRITE_TREBLE (SOUND_BASE | SOUND_MIXER | SOUND_WRITE | SOUND_MIXER_TREBLE )
+#define SOUND_MIXER_WRITE_MIDI (SOUND_BASE | SOUND_MIXER | SOUND_WRITE | SOUND_MIXER_MIDI )
+#define SOUND_MIXER_WRITE_PCM (SOUND_BASE | SOUND_MIXER | SOUND_WRITE | SOUND_MIXER_PCM )
+#define SOUND_MIXER_WRITE_SPEAKER (SOUND_BASE | SOUND_MIXER | SOUND_WRITE | SOUND_MIXER_SPEAKER)
+#define SOUND_MIXER_WRITE_LINE (SOUND_BASE | SOUND_MIXER | SOUND_WRITE | SOUND_MIXER_LINE )
+#define SOUND_MIXER_WRITE_MIC (SOUND_BASE | SOUND_MIXER | SOUND_WRITE | SOUND_MIXER_MIC )
+
+/*
+ PCM control - device type 1
+
+ All parameters are of type "unsigned short int".
+
+ RATE = sampling rate in Hz
+ CHANNELS = number of channels (1 = mono, 2 = stereo)
+ BITS = number of bits/sample/channel (8 = 8 bit,
+ 12 = 12 bit, 16 = 16 bit)
+ FILTER = flag (0 = don't filter, 1 = use best filter)
+*/
+
+#define SOUND_PCM 0x10
+#define SOUND_PCM_TYPE unsigned short int
+
+#define SOUND_RATE 0x0
+#define SOUND_CHANNELS 0x1
+#define SOUND_BITS 0x2
+#define SOUND_FILTER 0x3
+
+#define SOUND_PCM_READ_RATE (SOUND_BASE | SOUND_PCM | SOUND_READ | SOUND_RATE )
+#define SOUND_PCM_READ_CHANNELS (SOUND_BASE | SOUND_PCM | SOUND_READ | SOUND_CHANNELS)
+#define SOUND_PCM_READ_BITS (SOUND_BASE | SOUND_PCM | SOUND_READ | SOUND_BITS )
+#define SOUND_PCM_READ_FILTER (SOUND_BASE | SOUND_PCM | SOUND_READ | SOUND_FILTER )
+
+#define SOUND_PCM_WRITE_RATE (SOUND_BASE | SOUND_PCM | SOUND_WRITE | SOUND_RATE )
+#define SOUND_PCM_WRITE_CHANNELS (SOUND_BASE | SOUND_PCM | SOUND_WRITE | SOUND_CHANNELS)
+#define SOUND_PCM_WRITE_BITS (SOUND_BASE | SOUND_PCM | SOUND_WRITE | SOUND_BITS )
+#define SOUND_PCM_WRITE_FILTER (SOUND_BASE | SOUND_PCM | SOUND_WRITE | SOUND_FILTER )
+
+/*
+ * The Mixer ioctl calls are compatible with mach386 driver by
+ * Steve Haehnichen <shaehnic@ucsd.edu>
+ */
+
+typedef unsigned char BYTE;
+typedef unsigned char FLAG;
+struct stereo_vol
+{
+ BYTE l; /* Left volume */
+ BYTE r; /* Right volume */
+};
+#define MIXER_IOCTL_SET_LEVELS 0x02014252
+#define MIXER_IOCTL_SET_PARAMS 0x02024252
+#define MIXER_IOCTL_READ_LEVELS 0x02034252
+#define MIXER_IOCTL_READ_PARAMS 0x02044252
+#define MIXER_IOCTL_RESET 0x02054252
+
+/*
+ * Mixer volume levels for MIXER_IOCTL_SET_VOL & MIXER_IOCTL_READ_VOL
+ */
+struct sb_mixer_levels
+{
+ struct stereo_vol master; /* Master volume */
+ struct stereo_vol voc; /* DSP Voice volume */
+ struct stereo_vol fm; /* FM volume */
+ struct stereo_vol line; /* Line-in volume */
+ struct stereo_vol cd; /* CD audio */
+ BYTE mic; /* Microphone level */
+};
+
+/*
+ * Mixer parameters for MIXER_IOCTL_SET_PARAMS & MIXER_IOCTL_READ_PARAMS
+ */
+struct sb_mixer_params
+{
+ BYTE record_source; /* Recording source (See SRC_xxx below) */
+ FLAG hifreq_filter; /* Filter frequency (hi/low) */
+ FLAG filter_input; /* ANFI input filter */
+ FLAG filter_output; /* DNFI output filter */
+ FLAG dsp_stereo; /* 1 if DSP is in Stereo mode */
+};
+
+#define SRC_MIC 1 /* Select Microphone recording source */
+#define SRC_CD 3 /* Select CD recording source */
+#define SRC_LINE 7 /* Use Line-in for recording source */
+
+
+/*
+ * Dynamic configuration mechanism.
+ * (for soundload program)
+ */
+
+
+struct soundcard_config
+{
+ int config_command;
+#define SNDCONF_RESET 0
+#define SNDCONF_START 1
+#define SNDCONF_SETCARD 2
+
+ int cardtype; /* SNDCARD_ADLIB etc. */
+ int card_subtype; /* Card dependent number */
+
+ int config_parms[100]; /* Card dependent parameters */
+};
+
+extern long soundcard_init(long mem_start);
+
+#endif
diff --git a/include/linux/termios.h b/include/linux/termios.h
index 1ae8037..2afeb5c 100644
--- a/include/linux/termios.h
+++ b/include/linux/termios.h
@@ -177,7 +177,6 @@ struct termios {
#define HUPCL 0002000
#define CLOCAL 0004000
#define CIBAUD 03600000 /* input baud rate (not used) */
-#define CNORTSCTS 010000000000 /* no flow control */
#define CRTSCTS 020000000000 /* flow control */
/* c_lflag bits */
diff --git a/include/linux/tty.h b/include/linux/tty.h
index d214c1f..0b26653 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -87,6 +87,7 @@ struct serial_struct {
#define PORT_16450 2
#define PORT_16550 3
#define PORT_16550A 4
+#define PORT_MAX 4
/*
* Definitions for async_struct (and serial_struct) flags field
@@ -100,6 +101,8 @@ struct serial_struct {
#define ASYNC_SPD_VHI 0x0020 /* Use 115200 instead of 38400 bps */
#define ASYNC_SPD_CUST 0x0030 /* Use user-specified divisor */
+#define ASYNC_FLAGS 0x0037 /* Possible legal async flags */
+
#define IS_A_CONSOLE(min) (((min) & 0xC0) == 0x00)
#define IS_A_SERIAL(min) (((min) & 0xC0) == 0x40)
#define IS_A_PTY(min) ((min) & 0x80)
@@ -281,6 +284,7 @@ extern int is_orphaned_pgrp(int pgrp);
extern int is_ignored(int sig);
extern int tty_signal(int sig, struct tty_struct *tty);
extern int kill_pg(int pgrp, int sig, int priv);
+extern int kill_sl(int sess, int sig, int priv);
extern void do_SAK(struct tty_struct *tty);
/* tty write functions */
diff --git a/init/main.c b/init/main.c
index 0f664b5..89b351e 100644
--- a/init/main.c
+++ b/init/main.c
@@ -212,7 +212,7 @@ void start_kernel(void)
memory_end = (1<<20) + (EXT_MEM_K<<10);
memory_end &= 0xfffff000;
ramdisk_size = RAMDISK_SIZE;
-#ifdef MAX_16M
+#ifdef CONFIG_MAX_16M
if (memory_end > 16*1024*1024)
memory_end = 16*1024*1024;
#endif
@@ -227,10 +227,10 @@ void start_kernel(void)
init_IRQ();
sched_init();
parse_options(command_line);
-#ifdef PROFILE_SHIFT
+#ifdef CONFIG_PROFILE
prof_buffer = (unsigned long *) memory_start;
prof_len = (unsigned long) &end;
- prof_len >>= PROFILE_SHIFT;
+ prof_len >>= 2;
memory_start += prof_len * sizeof(unsigned long);
#endif
memory_start = chr_dev_init(memory_start,memory_end);
diff --git a/kernel/FPU-emu/Makefile b/kernel/FPU-emu/Makefile
index 25abfd8..8ae26fb 100644
--- a/kernel/FPU-emu/Makefile
+++ b/kernel/FPU-emu/Makefile
@@ -1,24 +1,25 @@
+#
# Makefile for wm-FPU-emu
#
-CC = gcc
-#OPTS = -O2
-OPTS = -O
#DEBUG = -DDEBUGGING
DEBUG =
-CFLAGS2 = $(CFLAGS) -DPARANOID $(DEBUG) -Wall -fno-builtin
+CFLAGS := $(CFLAGS) -DPARANOID $(DEBUG) -fno-builtin
.c.o:
- $(CC) $(CFLAGS2) $(MATH_EMULATION) -c $<
+ $(CC) $(CFLAGS) $(MATH_EMULATION) -c $<
.S.o:
- $(CC) $(CFLAGS2) -c $<
+ $(CC) $(CFLAGS) -c $<
.s.o:
$(CC) -c $<
-OBJS = fpu_entry.o\
- div_small.o errors.o\
+OBJS = fpu_entry.o
+
+ifdef CONFIG_MATH_EMULATION
+
+OBJS := $(OBJS) div_small.o errors.o\
fpu_arith.o fpu_aux.o fpu_etc.o fpu_trig.o\
load_store.o get_address.o\
poly_atan.o poly_l2.o poly_2xm1.o poly_sin.o poly_tan.o\
@@ -28,6 +29,7 @@ OBJS = fpu_entry.o\
reg_u_add.o reg_u_div.o reg_u_mul.o reg_u_sub.o\
wm_shrx.o wm_sqrt.o
+endif
math.a: $(OBJS)
rm -f math.a
@@ -35,151 +37,19 @@ math.a: $(OBJS)
sync
clean:
- rm -f core *.o *.a tmp_make *~
- for i in *.c;do rm -f `basename $$i .c`.s;done
+ rm -f core *.o *.a *.s *~
dep:
- sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
- for i in *.c *.S;do $(CPP) -M $$i;done >> tmp_make
- cp tmp_make Makefile
+ $(CPP) -M *.c *.S > .depend
proto:
cproto -e -DMAKING_PROTO *.c >fpu_proto.h
dummy:
-### Dependencies:
-errors.o : errors.c /usr/include/linux/signal.h /usr/include/asm/segment.h fpu_system.h \
- /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/time.h /usr/include/linux/param.h \
- /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
- exception.h fpu_emu.h fpu_proto.h status_w.h control_w.h reg_constant.h version.h
-fpu_arith.o : fpu_arith.c fpu_system.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h fpu_emu.h fpu_proto.h
-fpu_aux.o : fpu_aux.c fpu_system.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h exception.h fpu_emu.h \
- fpu_proto.h status_w.h
-fpu_entry.o : fpu_entry.c /usr/include/linux/signal.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
- /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h
-fpu_etc.o : fpu_etc.c fpu_system.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h exception.h fpu_emu.h \
- fpu_proto.h status_w.h reg_constant.h
-fpu_trig.o : fpu_trig.c fpu_system.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h exception.h fpu_emu.h \
- fpu_proto.h status_w.h control_w.h reg_constant.h
-get_address.o : get_address.c /usr/include/linux/stddef.h /usr/include/asm/segment.h \
- fpu_system.h /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h exception.h fpu_emu.h fpu_proto.h
-load_store.o : load_store.c /usr/include/asm/segment.h fpu_system.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
- /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
- /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
- /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
- exception.h fpu_emu.h fpu_proto.h status_w.h
-poly_2xm1.o : poly_2xm1.c exception.h fpu_emu.h /usr/include/linux/math_emu.h \
- fpu_proto.h reg_constant.h
-poly_atan.o : poly_atan.c exception.h fpu_emu.h /usr/include/linux/math_emu.h \
- fpu_proto.h reg_constant.h
-poly_l2.o : poly_l2.c exception.h fpu_emu.h /usr/include/linux/math_emu.h fpu_proto.h \
- reg_constant.h
-poly_sin.o : poly_sin.c exception.h fpu_emu.h /usr/include/linux/math_emu.h \
- fpu_proto.h reg_constant.h
-poly_tan.o : poly_tan.c exception.h fpu_emu.h /usr/include/linux/math_emu.h \
- fpu_proto.h reg_constant.h
-reg_add_sub.o : reg_add_sub.c exception.h fpu_emu.h /usr/include/linux/math_emu.h \
- fpu_proto.h reg_constant.h
-reg_compare.o : reg_compare.c fpu_system.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h exception.h fpu_emu.h \
- fpu_proto.h status_w.h
-reg_constant.o : reg_constant.c fpu_system.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h fpu_emu.h fpu_proto.h \
- status_w.h reg_constant.h
-reg_ld_str.o : reg_ld_str.c /usr/include/asm/segment.h fpu_system.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
- /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
- /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
- /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
- exception.h fpu_emu.h fpu_proto.h reg_constant.h control_w.h
-reg_mul.o : reg_mul.c exception.h fpu_emu.h /usr/include/linux/math_emu.h fpu_proto.h \
- reg_constant.h
-div_small.o : div_small.S fpu_asm.h fpu_emu.h
-poly_div.o : poly_div.S fpu_asm.h fpu_emu.h
-poly_mul64.o : poly_mul64.S fpu_asm.h fpu_emu.h
-polynomial.o : polynomial.S fpu_asm.h fpu_emu.h
-reg_div.o : reg_div.S exception.h fpu_emu.h fpu_asm.h
-reg_norm.o : reg_norm.S fpu_asm.h fpu_emu.h
-reg_u_add.o : reg_u_add.S exception.h fpu_emu.h fpu_asm.h
-reg_u_div.o : reg_u_div.S exception.h fpu_emu.h fpu_asm.h
-reg_u_mul.o : reg_u_mul.S exception.h fpu_emu.h fpu_asm.h
-reg_u_sub.o : reg_u_sub.S exception.h fpu_emu.h fpu_asm.h
-wm_shrx.o : wm_shrx.S fpu_asm.h fpu_emu.h
-wm_sqrt.o : wm_sqrt.S exception.h fpu_emu.h fpu_asm.h
+#
+# include a dependency file if one exists
+#
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
diff --git a/kernel/FPU-emu/fpu_entry.c b/kernel/FPU-emu/fpu_entry.c
index 0d02f87..d1c8934 100644
--- a/kernel/FPU-emu/fpu_entry.c
+++ b/kernel/FPU-emu/fpu_entry.c
@@ -22,7 +22,9 @@
| math_emulate() is the sole entry point for wm-FPU-emu |
+---------------------------------------------------------------------------*/
-#ifdef KERNEL_MATH_EMULATION
+#include <linux/config.h>
+
+#ifdef CONFIG_MATH_EMULATION
#include <linux/signal.h>
@@ -290,4 +292,4 @@ void math_emulate(long arg)
schedule();
}
-#endif /* KERNEL_MATH_EMULATION */
+#endif /* CONFIG_MATH_EMULATION */
diff --git a/kernel/Makefile b/kernel/Makefile
index fd910e5..1009703 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -40,152 +40,19 @@ sched.o: sched.c
$(CC) $(CFLAGS) $(PROFILING) -fno-omit-frame-pointer -c $<
clean:
- rm -f core *.o *.a tmp_make sys_call.s
- for i in *.c;do rm -f `basename $$i .c`.s;done
+ rm -f core *.o *.a *.s
for i in $(SUBDIRS); do (cd $$i && $(MAKE) clean); done
dep:
- sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
- $(CPP) -M *.c >> tmp_make
- cp tmp_make Makefile
+ $(CPP) -M *.c > .depend
for i in $(SUBDIRS); do (cd $$i && $(MAKE) dep) || exit; done
dummy:
-### Dependencies:
-dma.o : dma.c /usr/include/linux/kernel.h /usr/include/linux/errno.h /usr/include/asm/dma.h \
- /usr/include/asm/io.h
-exit.o : exit.c /usr/include/linux/wait.h /usr/include/linux/errno.h /usr/include/linux/signal.h \
- /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
- /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/tty.h \
- /usr/include/linux/termios.h /usr/include/asm/system.h /usr/include/asm/segment.h
-fork.o : fork.c /usr/include/linux/errno.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/stddef.h \
- /usr/include/asm/segment.h /usr/include/asm/system.h
-info.o : info.c /usr/include/asm/segment.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/string.h \
- /usr/include/linux/unistd.h
-ioport.o : ioport.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/errno.h
-irq.o : irq.c /usr/include/linux/ptrace.h /usr/include/linux/errno.h /usr/include/linux/signal.h \
- /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/time.h /usr/include/linux/param.h \
- /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
- /usr/include/asm/system.h /usr/include/asm/io.h /usr/include/asm/irq.h
-itimer.o : itimer.c /usr/include/linux/signal.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/string.h /usr/include/linux/errno.h \
- /usr/include/asm/segment.h
-mktime.o : mktime.c /usr/include/linux/mktime.h
-panic.o : panic.c /usr/include/linux/kernel.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h
-printk.o : printk.c /usr/lib/gcc-lib/i386-linux/2.3.2/include/stdarg.h /usr/include/asm/segment.h \
- /usr/include/asm/system.h /usr/include/linux/errno.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
- /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
- /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
- /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h
-ptrace.o : ptrace.c /usr/include/linux/head.h /usr/include/linux/kernel.h /usr/include/linux/sched.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/errno.h /usr/include/linux/ptrace.h \
- /usr/include/asm/segment.h /usr/include/asm/system.h
-sched.o : sched.c /usr/include/linux/signal.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/timer.h /usr/include/linux/sys.h \
- /usr/include/linux/fdreg.h /usr/include/linux/errno.h /usr/include/linux/ptrace.h \
- /usr/include/asm/system.h /usr/include/asm/io.h /usr/include/asm/segment.h
-signal.o : signal.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/errno.h /usr/include/linux/ptrace.h \
- /usr/include/asm/segment.h
-sys.o : sys.c /usr/include/linux/errno.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/tty.h \
- /usr/include/linux/termios.h /usr/include/asm/system.h /usr/include/linux/config.h \
- /usr/include/linux/config.dist.h /usr/include/linux/times.h /usr/include/linux/utsname.h \
- /usr/include/linux/string.h /usr/include/linux/ptrace.h /usr/include/asm/segment.h
-traps.o : traps.c /usr/include/linux/head.h /usr/include/linux/sched.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/string.h /usr/include/linux/errno.h \
- /usr/include/asm/system.h /usr/include/asm/segment.h /usr/include/asm/io.h
-vsprintf.o : vsprintf.c /usr/lib/gcc-lib/i386-linux/2.3.2/include/stdarg.h /usr/include/linux/types.h \
- /usr/include/linux/string.h /usr/include/linux/ctype.h
+#
+# include a dependency file if one exists
+#
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
+
diff --git a/kernel/blk_drv/Makefile b/kernel/blk_drv/Makefile
index 2343ec6..618a623 100644
--- a/kernel/blk_drv/Makefile
+++ b/kernel/blk_drv/Makefile
@@ -31,68 +31,19 @@ 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
+ rm -f core *.o *.a *.s
for i in $(SUBDIRS); do (cd $$i && $(MAKE) clean); done
dep:
- sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
- $(CPP) -M *.c >> tmp_make
- cp tmp_make Makefile
+ $(CPP) -M *.c > .depend
for i in $(SUBDIRS); do (cd $$i && $(MAKE) dep); done
dummy:
-### Dependencies:
-floppy.o : floppy.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/timer.h /usr/include/linux/fdreg.h \
- /usr/include/linux/fd.h /usr/include/linux/errno.h /usr/include/asm/dma.h /usr/include/asm/io.h \
- /usr/include/asm/system.h /usr/include/asm/segment.h blk.h
-genhd.o : genhd.c /usr/include/linux/config.h /usr/include/linux/config.dist.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/genhd.h /usr/include/linux/kernel.h
-hd.o : hd.c /usr/include/linux/config.h /usr/include/linux/config.dist.h /usr/include/linux/errno.h \
- /usr/include/linux/signal.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/timer.h /usr/include/linux/hdreg.h \
- /usr/include/linux/genhd.h /usr/include/asm/system.h /usr/include/asm/io.h /usr/include/asm/segment.h \
- blk.h
-ll_rw_blk.o : ll_rw_blk.c /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/errno.h \
- /usr/include/linux/string.h /usr/include/linux/config.h /usr/include/linux/config.dist.h \
- /usr/include/linux/locks.h /usr/include/asm/system.h blk.h
-ramdisk.o : ramdisk.c /usr/include/linux/config.h /usr/include/linux/config.dist.h \
- /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/minix_fs.h /usr/include/linux/string.h \
- /usr/include/asm/system.h /usr/include/asm/segment.h blk.h
+#
+# include a dependency file if one exists
+#
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
+
diff --git a/kernel/blk_drv/floppy.c b/kernel/blk_drv/floppy.c
index 446cd48..e8dd20f 100644
--- a/kernel/blk_drv/floppy.c
+++ b/kernel/blk_drv/floppy.c
@@ -809,10 +809,12 @@ static void reset_floppy(void)
static void floppy_shutdown(void)
{
cli();
+ do_floppy = NULL;
request_done(0);
recover = 1;
reset_floppy();
sti();
+ redo_fd_request();
}
static void shake_done(void)
diff --git a/kernel/blk_drv/hd.c b/kernel/blk_drv/hd.c
index df05a47..1e74ca9 100644
--- a/kernel/blk_drv/hd.c
+++ b/kernel/blk_drv/hd.c
@@ -675,6 +675,7 @@ unsigned long hd_init(unsigned long mem_start, unsigned long mem_end)
{
blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
blkdev_fops[MAJOR_NR] = &hd_fops;
+ read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read-ahead */
hd_gendisk.next = gendisk_head;
gendisk_head = &hd_gendisk;
timer_table[HD_TIMER].fn = hd_times_out;
diff --git a/kernel/blk_drv/ll_rw_blk.c b/kernel/blk_drv/ll_rw_blk.c
index 5e0eb5b..51759d2 100644
--- a/kernel/blk_drv/ll_rw_blk.c
+++ b/kernel/blk_drv/ll_rw_blk.c
@@ -29,8 +29,7 @@ struct request request[NR_REQUEST];
*/
struct wait_queue * wait_for_request = NULL;
-/* This specifies how many blocks to read ahead on the disk. We might want
- to change this to sectors later, but for now this will work */
+/* This specifies how many sectors to read ahead on the disk. */
int read_ahead[NR_BLK_DEV] = {0, };
diff --git a/kernel/blk_drv/scsi/Makefile b/kernel/blk_drv/scsi/Makefile
index 2109e0a..7e648e4 100644
--- a/kernel/blk_drv/scsi/Makefile
+++ b/kernel/blk_drv/scsi/Makefile
@@ -1,272 +1,98 @@
-# 1 "tmp_make.c"
-
+#
# Makefile for kernel/blk_drv/scsi
-
-# Note! This Makefile is automatically generated from makefile.in.
-# DO NOT edit makefile, edit makefile.in instead.
-
+#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DONT put your own dependencies here
# unless its something special (ie not a .c file).
+#
+
+SCSI_HOSTS := 0
+SCSI_OBJS :=
+
+ifdef CONFIG_SCSI
+
+SCSI_OBJS := hosts.o scsi.o scsi_ioctl.o
+
+ifdef CONFIG_BLK_DEV_ST
+SCSI_OBJS := $(SCSI_OBJS) st.o
+endif
+
+ifdef CONFIG_BLK_DEV_SD
+SCSI_OBJS := $(SCSI_OBJS) sd.o sd_ioctl.o
+endif
+
+ifdef CONFIG_BLK_DEV_SR
+SCSI_OBJS := $(SCSI_OBJS) sr.o sr_ioctl.o
+endif
+
+ifdef CONFIG_SCSI_AHA1542
+SCSI_OBJS := $(SCSI_OBJS) aha1542.o
+SCSI_HOSTS := 1+$(SCSI_HOSTS)
+endif
+
+ifdef CONFIG_SCSI_AHA1740
+SCSI_OBJS := $(SCSI_OBJS) aha1740.o
+SCSI_HOSTS := 1+$(SCSI_HOSTS)
+endif
+
+ifdef CONFIG_SCSI_FUTURE_DOMAIN
+SCSI_OBJS := $(SCSI_OBJS) fdomain.o
+SCSI_HOSTS := 1+$(SCSI_HOSTS)
+endif
+
+ifdef CONFIG_SCSI_ULTRASTOR
+SCSI_OBJS := $(SCSI_OBJS) ultrastor.o
+SCSI_HOSTS := 1+$(SCSI_HOSTS)
+endif
+
+ifdef CONFIG_SCSI_7000FASST
+SCSI_OBJS := $(SCSI_OBJS) wd7000.o
+SCSI_HOSTS := 1+$(SCSI_HOSTS)
+endif
+
+ifdef CONFIG_SCSI_SEAGATE
+SCSI_OBJS := $(SCSI_OBJS) seagate.o
+SCSI_HOSTS := 1+$(SCSI_HOSTS)
+else
+ifdef CONFIG_SCSI_FD_88x
+SCSI_OBJS := $(SCSI_OBJS) seagate.o
+SCSI_HOSTS := 1+$(SCSI_HOSTS)
+endif
+endif
+
+ifdef CONFIG_SCSI_DEBUG
+SCSI_OBJS := $(SCSI_OBJS) scsi_debug.o
+SCSI_HOSTS := 1+$(SCSI_HOSTS)
+endif
+
+scsi.a: $(SCSI_OBJS)
+ rm -f scsi.a
+ $(AR) rcs scsi.a $(SCSI_OBJS)
+ sync
-# 1 "/usr/include/linux/config.h" 1 3
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-# 101 "/usr/include/linux/config.h" 3
-
-
-
-# 1 "/usr/include/linux/config.dist.h" 1 3
-
-# 115 "/usr/include/linux/config.h" 2 3
-
-
-
-# 12 "tmp_make.c" 2
-
-.c.s:
- $(CC) $(CFLAGS) $(DEBUG) -S $<
-
-.s.o:
- $(AS) -c -o $*.o $<
-
-.c.o:
- $(CC) $(CFLAGS) $(DEBUG) -c $<
-
-ST_CSRC = st.c
-ST_OBJS = st.o
-
-SD_CSRC = sd.c sd_ioctl.c
-SD_OBJS = sd.o sd_ioctl.o
-
-SR_CSRC = sr.c sr_ioctl.c
-SR_OBJS = sr.o sr_ioctl.o
-
-AHA1542_OBJS = aha1542.o
-
-AHA1740_OBJS = aha1740.o
-
-FDOMAIN_OBJS = fdomain.o
-
-ULTRASTOR_OBJS = ultrastor.o
-
-WD7000_OBJS = wd7000.o
-
-SEAGATE_OBJS = seagate.o
-
-SCSI_OBJS = hosts.o scsi.o scsi_ioctl.o
-
-OBJS = $(SCSI_OBJS) $(SD_OBJS) $(ST_OBJS) $(SR_OBJS) $(AHA1542_OBJS) $(AHA1740_OBJS) $(FDOMAIN_OBJS) $(SEAGATE_OBJS) $(ULTRASTOR_OBJS) $(WD7000_OBJS) $(SCSI_DEBUG_OBJS)
-
-all:
- $(MAKE) Makefile
- $(MAKE) scsi.a
-
-figure : hosts.h $(KERNELHDRS)/linux/config.h hosts.c
- $(HOSTCC) -I$(KERNELHDRS) -DFIGURE_MAX_SCSI_HOSTS hosts.c -o figure
-
-max_hosts.h : figure
- (echo "#ifndef _MAX_HOSTS_H"; echo "#define _MAX_HOSTS_H"; echo "#define MAX_SCSI_HOSTS `./figure`"; echo "#endif") > tmp_max
-
- cp tmp_max max_hosts.h
-
-have_makefile:
- touch have_makefile
-
-Makefile: ../../../include/linux/config.h ../../../include/linux/config.site.h ../../../include/linux/config.dist.h Makefile.in have_makefile
-
- cp Makefile.in tmp_make.c
- $(CPP) -E tmp_make.c | uniq > tmp_make
-
- rm tmp_make.c
- cp tmp_make Makefile
- rm -f tmp_make*
- $(MAKE) dep
+else
-scsi.a: $(OBJS)
+scsi.a:
rm -f scsi.a
- $(AR) rcs scsi.a $(OBJS)
- sync
+ @echo No SCSI drivers configured
+ $(AR) rcs scsi.a
-clean:
- rm -f core *.o *.a tmp_make tmp_max figure max_hosts.h have_makefile
+endif
+
+CFLAGS := $(CFLAGS) "-DMAX_SCSI_HOSTS=($(SCSI_HOSTS))"
seagate.o: seagate.c
$(CC) -Wall -I$(KERNELHDRS) -c seagate.c
-dep: max_hosts.h
- sed '/\# \X\XDependencies/q' < Makefile > tmp_make
- $(CPP) -M *.c >> tmp_make
- cp tmp_make Makefile
+clean:
+ rm -f core *.o *.a *.s
+
+dep:
+ $(CPP) -M *.c > .depend
-# XXDependencies:
-aha1542.o : aha1542.c /usr/include/linux/kernel.h /usr/include/linux/head.h \
- /usr/include/linux/types.h /usr/include/linux/string.h /usr/include/linux/sched.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
- /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
- /usr/include/asm/dma.h /usr/include/asm/io.h /usr/include/asm/system.h ../blk.h \
- scsi.h hosts.h aha1542.h
-aha1740.o : aha1740.c /usr/include/linux/kernel.h /usr/include/linux/head.h \
- /usr/include/linux/types.h /usr/include/linux/string.h /usr/include/linux/sched.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
- /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
- /usr/include/asm/dma.h /usr/include/asm/io.h /usr/include/asm/system.h ../blk.h \
- scsi.h hosts.h aha1740.h
-fdomain.o : fdomain.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/asm/io.h ../blk.h scsi.h hosts.h \
- fdomain.h /usr/include/asm/system.h /usr/include/linux/errno.h
-hosts.o : hosts.c /usr/include/linux/config.h /usr/include/linux/config.dist.h \
- ../blk.h /usr/include/linux/kernel.h scsi.h max_hosts.h hosts.h aha1542.h /usr/include/linux/types.h \
- aha1740.h fdomain.h seagate.h ultrastor.h wd7000.h
-scsi.o : scsi.c /usr/include/asm/system.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/timer.h \
- /usr/include/linux/string.h ../blk.h scsi.h hosts.h
-scsi_debug.o : scsi_debug.c /usr/include/linux/kernel.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
- /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/timer.h \
- /usr/include/linux/string.h /usr/include/linux/genhd.h /usr/include/asm/system.h \
- /usr/include/asm/io.h ../blk.h scsi.h hosts.h scsi_debug.h
-scsi_ioctl.o : scsi_ioctl.c /usr/include/asm/io.h /usr/include/asm/segment.h \
- /usr/include/asm/system.h /usr/include/linux/errno.h /usr/include/linux/kernel.h \
- /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
- /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
- /usr/include/linux/string.h ../blk.h scsi.h hosts.h scsi_ioctl.h
-sd.o : sd.c /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/kernel.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/mm.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/string.h /usr/include/linux/errno.h \
- /usr/include/asm/system.h ../blk.h scsi.h hosts.h sd.h /usr/include/linux/genhd.h \
- scsi_ioctl.h
-sd_ioctl.o : sd_ioctl.c /usr/include/linux/kernel.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
- /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/hdreg.h \
- /usr/include/linux/errno.h /usr/include/asm/segment.h ../blk.h scsi.h hosts.h \
- sd.h /usr/include/linux/genhd.h
-seagate.o : seagate.c /usr/include/linux/config.h /usr/include/linux/config.dist.h \
- /usr/include/asm/io.h /usr/include/asm/system.h /usr/include/linux/signal.h \
- /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/time.h /usr/include/linux/param.h \
- /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
- ../blk.h scsi.h hosts.h seagate.h
-sr.o : sr.c /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/kernel.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/mm.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/string.h /usr/include/linux/errno.h \
- /usr/include/asm/system.h ../blk.h scsi.h hosts.h sr.h scsi_ioctl.h
-sr_ioctl.o : sr_ioctl.c /usr/include/linux/kernel.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
- /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/asm/segment.h \
- /usr/include/linux/errno.h ../blk.h scsi.h sr.h scsi_ioctl.h /usr/include/linux/cdrom.h
-st.o : st.c /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/kernel.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/mm.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/string.h /usr/include/linux/errno.h \
- /usr/include/linux/mtio.h /usr/include/linux/ioctl.h /usr/include/linux/fcntl.h \
- /usr/include/asm/segment.h /usr/include/asm/system.h ../blk.h scsi.h st.h
-ultrastor.o : ultrastor.c /usr/include/linux/stddef.h /usr/include/linux/string.h \
- /usr/include/linux/types.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/asm/io.h /usr/include/asm/system.h \
- /usr/include/asm/dma.h ../blk.h scsi.h hosts.h ultrastor.h
-wd7000.o : wd7000.c /usr/lib/gcc-lib/i386-linux/2.3.2/include/stdarg.h /usr/include/linux/kernel.h \
- /usr/include/linux/head.h /usr/include/linux/types.h /usr/include/linux/string.h \
- /usr/include/linux/sched.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/asm/system.h /usr/include/asm/dma.h \
- /usr/include/asm/io.h ../blk.h scsi.h hosts.h wd7000.h
+#
+# include a dependency file if one exists
+#
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
diff --git a/kernel/blk_drv/scsi/Makefile.in b/kernel/blk_drv/scsi/Makefile.in
deleted file mode 100644
index 8385d2c..0000000
--- a/kernel/blk_drv/scsi/Makefile.in
+++ /dev/null
@@ -1,121 +0,0 @@
-#
-# Makefile for kernel/blk_drv/scsi
-#
-# Note! This Makefile is automatically generated from makefile.in.
-# DO NOT edit makefile, edit makefile.in instead.
-#
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DONT put your own dependencies here
-# unless its something special (ie not a .c file).
-#
-
-#include <linux/config.h>
-#undef linux
-
-.c.s:
- $(CC) $(CFLAGS) $(DEBUG) -S $<
-
-.s.o:
- $(AS) -c -o $*.o $<
-
-.c.o:
- $(CC) $(CFLAGS) $(DEBUG) -c $<
-
-#ifdef CONFIG_SCSI
-#ifdef CONFIG_BLK_DEV_ST
-ST_CSRC = st.c
-ST_OBJS = st.o
-#endif
-
-#ifdef CONFIG_BLK_DEV_SD
-SD_CSRC = sd.c sd_ioctl.c
-SD_OBJS = sd.o sd_ioctl.o
-#endif
-
-#ifdef CONFIG_BLK_DEV_SR
-SR_CSRC = sr.c sr_ioctl.c
-SR_OBJS = sr.o sr_ioctl.o
-#endif
-
-#ifdef CONFIG_SCSI_AHA1542
-AHA1542_OBJS = aha1542.o
-#endif
-
-#ifdef CONFIG_SCSI_AHA1740
-AHA1740_OBJS = aha1740.o
-#endif
-
-#ifdef CONFIG_SCSI_FUTURE_DOMAIN
-FDOMAIN_OBJS = fdomain.o
-#endif
-
-#ifdef CONFIG_SCSI_ULTRASTOR
-ULTRASTOR_OBJS = ultrastor.o
-#endif
-
-#ifdef CONFIG_SCSI_7000FASST
-WD7000_OBJS = wd7000.o
-#endif
-
-#if defined(CONFIG_SCSI_SEAGATE) || defined(CONFIG_SCSI_FD_88x)
-SEAGATE_OBJS = seagate.o
-#endif
-
-#ifdef CONFIG_SCSI_DEBUG
-SCSI_DEBUG_OBJS = scsi_debug.o
-#endif
-
-SCSI_OBJS = hosts.o scsi.o scsi_ioctl.o
-
-#endif
-
-OBJS = $(SCSI_OBJS) $(SD_OBJS) $(ST_OBJS) $(SR_OBJS) \
- $(AHA1542_OBJS) $(AHA1740_OBJS) $(FDOMAIN_OBJS) $(SEAGATE_OBJS) \
- $(ULTRASTOR_OBJS) $(WD7000_OBJS) $(SCSI_DEBUG_OBJS)
-
-all:
- $(MAKE) Makefile
- $(MAKE) scsi.a
-
-figure : hosts.h $(KERNELHDRS)/linux/config.h hosts.c
- $(HOSTCC) -I$(KERNELHDRS) -DFIGURE_MAX_SCSI_HOSTS hosts.c -o figure
-
-max_hosts.h : figure
- (echo "#ifndef _MAX_HOSTS_H"; \
- echo "#define _MAX_HOSTS_H"; \
- echo "#define MAX_SCSI_HOSTS `./figure`";\
- echo "#endif") > tmp_max
- cp tmp_max max_hosts.h
-
-have_makefile:
- touch have_makefile
-
-Makefile: ../../../include/linux/config.h \
- ../../../include/linux/config.site.h \
- ../../../include/linux/config.dist.h \
- Makefile.in have_makefile
- cp Makefile.in tmp_make.c
- $(CPP) -E tmp_make.c \
- | uniq > tmp_make
- rm tmp_make.c
- cp tmp_make Makefile
- rm -f tmp_make*
- $(MAKE) dep
-
-scsi.a: $(OBJS)
- rm -f scsi.a
- $(AR) rcs scsi.a $(OBJS)
- sync
-
-clean:
- rm -f core *.o *.a tmp_make tmp_max figure max_hosts.h have_makefile
-
-seagate.o: seagate.c
- $(CC) -Wall -I$(KERNELHDRS) -c seagate.c
-
-dep: max_hosts.h
- sed '/\# \X\XDependencies/q' < Makefile > tmp_make
- $(CPP) -M *.c >> tmp_make
- cp tmp_make Makefile
-
-# XXDependencies:
diff --git a/kernel/blk_drv/scsi/aha1542.c b/kernel/blk_drv/scsi/aha1542.c
index 01678b4..defad12 100644
--- a/kernel/blk_drv/scsi/aha1542.c
+++ b/kernel/blk_drv/scsi/aha1542.c
@@ -772,9 +772,9 @@ int aha1542_reset(void)
}
int aha1542_biosparam(int size, int dev, int* info){
- info[0] = 32;
- info[1] = 64;
- info[2] = (size + 2047) >> 11;
+ info[0] = 64;
+ info[1] = 32;
+ info[2] = size >> 11;
if (info[2] >= 1024) info[2] = 1024;
return 0;
}
diff --git a/kernel/blk_drv/scsi/aha1740.c b/kernel/blk_drv/scsi/aha1740.c
index d58b3e0..ddc2eac 100644
--- a/kernel/blk_drv/scsi/aha1740.c
+++ b/kernel/blk_drv/scsi/aha1740.c
@@ -418,9 +418,9 @@ int aha1740_reset(void)
int aha1740_biosparam(int size, int dev, int* info){
DEB(printk("aha1740_biosparam\n"));
- info[0] = 32;
- info[1] = 64;
- info[2] = (size + 2047) >> 11;
+ info[0] = 64;
+ info[1] = 32;
+ info[2] = size >> 11;
if (info[2] >= 1024) info[2] = 1024;
return 0;
}
diff --git a/kernel/blk_drv/scsi/fdomain.c b/kernel/blk_drv/scsi/fdomain.c
index 2d03815..fe777d6 100644
--- a/kernel/blk_drv/scsi/fdomain.c
+++ b/kernel/blk_drv/scsi/fdomain.c
@@ -1,6 +1,6 @@
/* fdomain.c -- Future Domain TMC-1660/TMC-1680 driver
* Created: Sun May 3 18:53:19 1992 by faith
- * Revised: Fri Nov 27 22:57:28 1992 by root
+ * Revised: Wed Dec 9 21:34:53 1992 by root
* Author: Rickard E. Faith, faith@cs.unc.edu
* Copyright 1992 Rickard E. Faith
*
@@ -33,11 +33,12 @@
* 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, and to Doug
- * Hoffman (hoffman@cs.unc.edu) for lending me SCSI devices to make driver
- * more robust. */
+ * (poirier@cs.unc.edu ), Ken Corey (kenc@sol.acs.unt.edu), C. de Bruin
+ * (bruin@dutiba.tudelft.nl) and Sakari Aaltonen (sakaria@vipunen.hit.fi)
+ * for alpha testing. Also thanks to Drew Eckhardt (drew@cs.colorado.edu)
+ * and Eric Youngdale (eric@tantalus.nrl.navy.mil) for answering questions,
+ * and to Doug Hoffman (hoffman@cs.unc.edu) for lending me SCSI devices to
+ * make the driver more robust. */
#include <linux/sched.h>
#include <asm/io.h>
@@ -48,7 +49,7 @@
#include <asm/system.h>
#include <linux/errno.h>
-#define VERSION "3.1" /* Change with each revision */
+#define VERSION "3.2" /* Change with each revision */
/* START OF USER DEFINABLE OPTIONS */
@@ -66,11 +67,13 @@
#define ERRORS_ONLY 1 /* Only write a line if there is an error */
#define DEBUG_DETECT 0 /* Debug fdomain_16x0_detect() */
#define DEBUG_MESSAGES 0 /* Debug MESSAGE IN PHASE */
+#define DEBUG_ABORT 1 /* Debug abort() routine */
#else
#define EVERY_ACCESS 0 /* LEAVE THESE ALONE--CHANGE THE ONES ABOVE */
#define ERRORS_ONLY 0
#define DEBUG_DETECT 0
#define DEBUG_MESSAGES 0
+#define DEBUG_ABORT 0
#endif
/* Errors are reported on the line, so we don't need to report them again */
@@ -92,9 +95,11 @@ static int interrupt_level = 0;
static int Data_Mode_Cntl_port;
static int FIFO_Data_Count_port;
static int Interrupt_Cntl_port;
+static int Interrupt_Mask_port;
static int Read_FIFO_port;
static int Read_SCSI_Data_port;
static int SCSI_Cntl_port;
+static int SCSI_Data_NoACK_port;
static int SCSI_Status_port;
static int TMC_Cntl_port;
static int TMC_Status_port;
@@ -121,8 +126,9 @@ extern void fdomain_16x0_intr( int unused );
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 };
+ SCSI_Data_NoACK = 8, Interrupt_Mask = 9,
+ 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,
@@ -386,9 +392,11 @@ int fdomain_16x0_detect( int hostnum )
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;
+ Interrupt_Mask_port = port_base + Interrupt_Mask;
Read_FIFO_port = port_base + Read_FIFO;
Read_SCSI_Data_port = port_base + Read_SCSI_Data;
SCSI_Cntl_port = port_base + SCSI_Cntl;
+ SCSI_Data_NoACK_port = port_base + SCSI_Data_NoACK;
SCSI_Status_port = port_base + SCSI_Status;
TMC_Cntl_port = port_base + TMC_Cntl;
TMC_Status_port = port_base + TMC_Status;
@@ -546,7 +554,7 @@ static int fdomain_select( int target )
unsigned long timeout;
/* Send our address OR'd with target address */
- outb( 0x40 | (1 << target), port_base + SCSI_Data_NoACK );
+ outb( 0x40 | (1 << target), SCSI_Data_NoACK_port );
if (RESELECTION && can_queue)
outb( 0x8a, SCSI_Cntl_port ); /* Bus Enable + Attention + Select */
@@ -635,7 +643,7 @@ void fdomain_16x0_intr( int unused )
#if RESELECTION
if (current_SC->SCp.phase & disconnect) {
- printk( " RECON %x ", inb( port_base + SCSI_Data_NoACK ) );
+ printk( " RECON %x ", inb( SCSI_Data_NoACK_port ) );
current_SC->SCp.phase = in_other;
outb( 0x90 | FIFO_COUNT, Interrupt_Cntl_port );
outb( 0x84, SCSI_Cntl_port );
@@ -658,7 +666,7 @@ void fdomain_16x0_intr( int unused )
outb( 0x40 | FIFO_COUNT, Interrupt_Cntl_port );
- outb( 0x40 | (1 << current_SC->target), port_base + SCSI_Data_NoACK );
+ outb( 0x40 | (1 << current_SC->target), SCSI_Data_NoACK_port );
#if RESELECTION
outb( 0x8a, SCSI_Cntl_port ); /* Bus Enable + Attention + Select */
@@ -681,10 +689,13 @@ void fdomain_16x0_intr( int unused )
#endif
my_done( DID_NO_CONNECT << 16 );
return;
- }
+ } else {
#if EVERY_ACCESS
- else printk( " AltSel " );
+ printk( " AltSel " );
#endif
+ /* Stop arbitration (also set FIFO for output and enable parity) */
+ outb( 0xd0 | PARITY_MASK, TMC_Cntl_port );
+ }
}
current_SC->SCp.phase = in_other;
in_interrupt_code = 0;
@@ -965,7 +976,7 @@ int fdomain_16x0_queue( Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
/* Start 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 */
+ outb( 0x40, SCSI_Data_NoACK_port ); /* Set our id bit */
++in_command;
outb( 0x20, Interrupt_Cntl_port );
outb( 0x14 | PARITY_MASK, TMC_Cntl_port ); /* Start arbitration */
@@ -1165,10 +1176,31 @@ int fdomain_16x0_command( Scsi_Cmnd *SCpnt )
int fdomain_16x0_abort( Scsi_Cmnd *SCpnt, int code )
{
-#if EVERY_ACCESS || ERRORS_ONLY
+#if EVERY_ACCESS || ERRORS_ONLY || DEBUG_ABORT
printk( "SCSI (Future Domain): Abort " );
#endif
+#if DEBUG_ABORT
+ printk( "Phase = %d, flag = %d, target = %d cmnd = 0x%02x pieces = %d size = %u\n",
+ current_SC->SCp.phase,
+ in_interrupt_code,
+ current_SC->target,
+ *(unsigned char *)current_SC->cmnd,
+ current_SC->use_sg,
+ current_SC->request_bufflen );
+ printk( "IMR = 0x%02x%02x\n", inb( 0x0a1 ), inb( 0x21 ) );
+ outb( 0x0a, 0xa0 );
+ printk( "IRR = 0x%02x", inb( 0xa0 ) );
+ outb( 0x0a, 0x20 );
+ printk( "%02x\n", inb( 0x20 ) );
+ outb( 0x0b, 0xa0 );
+ printk( "ISR = 0x%02x", inb( 0xa0 ) );
+ outb( 0x0b, 0x20 );
+ printk( "%02x\n", inb( 0x20 ) );
+ printk( "SCSI Status = %x\n", inb( SCSI_Status_port ) );
+ printk( "TMC Status = %x\n", inb( TMC_Status_port ) );
+ printk( "Interrupt Mask = %x\n", inb( Interrupt_Mask_port ) );
+#else
cli();
if (!in_command) {
#if EVERY_ACCESS || ERRORS_ONLY
@@ -1189,7 +1221,6 @@ int fdomain_16x0_abort( Scsi_Cmnd *SCpnt, int code )
sti();
/* Aborts are not done well. . . */
-#if 0
my_done( code << 16 );
#endif
return 0;
diff --git a/kernel/blk_drv/scsi/hosts.c b/kernel/blk_drv/scsi/hosts.c
index 93cc5cc..98b5f54 100644
--- a/kernel/blk_drv/scsi/hosts.c
+++ b/kernel/blk_drv/scsi/hosts.c
@@ -14,22 +14,12 @@
*/
#include <linux/config.h>
-
-#ifdef CONFIG_SCSI
#include "../blk.h"
#include <linux/kernel.h>
#include "scsi.h"
#ifndef NULL
- #define NULL 0L
-#endif
-
-#ifdef FIGURE_MAX_SCSI_HOSTS
- #define MAX_SCSI_HOSTS
-#endif
-
-#ifndef MAX_SCSI_HOSTS
- #include "max_hosts.h"
+#define NULL 0L
#endif
#include "hosts.h"
@@ -84,52 +74,31 @@ static const char RCSid[] = "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/hos
* idiocy.
*/
-#ifdef FIGURE_MAX_SCSI_HOSTS
- #define BLANKIFY(what) BLANK_HOST
-#else
- #define BLANKIFY(what) what
-#endif
-
Scsi_Host scsi_hosts[] =
{
#ifdef CONFIG_SCSI_AHA1542
- BLANKIFY(AHA1542),
+ AHA1542,
#endif
-
#ifdef CONFIG_SCSI_AHA1740
- BLANKIFY(AHA1740),
+ AHA1740,
#endif
-
#ifdef CONFIG_SCSI_FUTURE_DOMAIN
- BLANKIFY(FDOMAIN_16X0),
+ FDOMAIN_16X0,
#endif
-
#ifdef CONFIG_SCSI_SEAGATE
- BLANKIFY(SEAGATE_ST0X),
+ SEAGATE_ST0X,
#endif
#ifdef CONFIG_SCSI_ULTRASTOR
- BLANKIFY(ULTRASTOR_14F),
+ ULTRASTOR_14F,
#endif
#ifdef CONFIG_SCSI_7000FASST
- BLANKIFY(WD7000),
+ WD7000,
#endif
#ifdef CONFIG_SCSI_DEBUG
- BLANKIFY(SCSI_DEBUG),
+ SCSI_DEBUG,
#endif
};
-#ifdef FIGURE_MAX_SCSI_HOSTS
- #undef MAX_SCSI_HOSTS
- #define MAX_SCSI_HOSTS (sizeof(scsi_hosts) / sizeof(Scsi_Host))
-#endif
-
-#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.
*/
@@ -171,14 +140,6 @@ void scsi_init(void)
}
-#endif
-#else
-void main(void) {
- printf("0\n");
- }
-#endif
-
-
#ifndef CONFIG_BLK_DEV_SD
unsigned long sd_init(unsigned long memory_start, unsigned long memory_end){
return memory_start;
diff --git a/kernel/blk_drv/scsi/scsi.c b/kernel/blk_drv/scsi/scsi.c
index 88d3364..369d474 100644
--- a/kernel/blk_drv/scsi/scsi.c
+++ b/kernel/blk_drv/scsi/scsi.c
@@ -104,6 +104,7 @@ extern int last_reset[];
char * revision; /* Latest revision known to be bad. Not used yet */
};
+#if 0
static struct blist blacklist[] =
{{"TANDBERG","TDC 3600","U07"}, /* Locks up if polled for lun != 0 */
{"SEAGATE","ST296","921"}, /* Responds to all lun */
@@ -121,6 +122,7 @@ static int blacklisted(char * response_data){
return 1;
};
};
+#endif
/*
* As the actual SCSI command runs in the background, we must set up a
@@ -254,6 +256,7 @@ static void scan_scsis (void)
{
case TYPE_TAPE :
case TYPE_DISK :
+ case TYPE_MOD :
scsi_devices[NR_SCSI_DEVICES].writeable = 1;
break;
case TYPE_WORM :
@@ -283,6 +286,7 @@ static void scan_scsis (void)
if(NR_SR != -1) ++MAX_SR;
break;
case TYPE_DISK:
+ case TYPE_MOD:
printk("Detected scsi disk sd%d at scsi%d, id %d, lun %d\n", MAX_SD,
host_nr , dev, lun);
if(NR_SD != -1) ++MAX_SD;
@@ -291,6 +295,13 @@ static void scan_scsis (void)
break;
};
+ scsi_devices[NR_SCSI_DEVICES].scsi_level =
+ scsi_result[2] & 0x07;
+ if (scsi_devices[NR_SCSI_DEVICES].scsi_level >= 2 ||
+ (scsi_devices[NR_SCSI_DEVICES].scsi_level == 1 &&
+ (scsi_result[3] & 0x0f) == 1))
+ scsi_devices[NR_SCSI_DEVICES].scsi_level++;
+
/* These devices need this "key" to unlock the device
so we can use it */
if(strncmp("INSITE", &scsi_result[8], 6) == 0 &&
@@ -313,10 +324,11 @@ static void scan_scsis (void)
};
++NR_SCSI_DEVICES;
+#if 0
/* Some scsi devices cannot be polled for lun != 0
due to firmware bugs */
if(blacklisted(scsi_result)) break;
-
+#endif
/* Some scsi-1 peripherals do not handle lun != 0.
I am assuming that scsi-2 peripherals do better */
if((scsi_result[2] & 0x07) == 1 &&
@@ -836,7 +848,7 @@ static void scsi_done (Scsi_Cmnd * SCpnt)
#endif
status = MAYREDO;
- exit = SUGGEST_RETRY;
+ exit = DRIVER_SENSE | SUGGEST_RETRY;
break;
case SUGGEST_ABORT:
#ifdef DEBUG
@@ -844,7 +856,7 @@ static void scsi_done (Scsi_Cmnd * SCpnt)
#endif
status = FINISHED;
- exit = DRIVER_SENSE;
+ exit = DRIVER_SENSE | SUGGEST_ABORT;
break;
default:
printk ("Internal error %s %s \n", __FILE__,
@@ -1339,6 +1351,7 @@ unsigned long scsi_dev_init (unsigned long memory_start,unsigned long memory_end
sr_attach(&scsi_devices[i]);
break;
case TYPE_DISK:
+ case TYPE_MOD:
sd_attach(&scsi_devices[i]);
default:
break;
diff --git a/kernel/blk_drv/scsi/scsi.h b/kernel/blk_drv/scsi/scsi.h
index 0528775..4ed86ed 100644
--- a/kernel/blk_drv/scsi/scsi.h
+++ b/kernel/blk_drv/scsi/scsi.h
@@ -61,6 +61,7 @@
#define SEARCH_LOW 0x32
#define SET_LIMITS 0x33
#define PRE_FETCH 0x34
+#define READ_POSITION 0x34
#define SYNCRONIZE_CACHE 0x35
#define LOCK_UNLOCK_CACHE 0x36
#define READ_DEFECT_DATA 0x37
@@ -180,12 +181,12 @@
#define DRIVER_TIMEOUT 0x06
#define DRIVER_HARD 0x07
-#define SUGGEST_RETRY 0x08
-#define SUGGEST_ABORT 0x09
-#define SUGGEST_REMAP 0x0a
-#define SUGGEST_DIE 0x0b
+#define SUGGEST_RETRY 0x10
+#define SUGGEST_ABORT 0x20
+#define SUGGEST_REMAP 0x30
+#define SUGGEST_DIE 0x40
-#define DRIVER_SENSE 0x10
+#define DRIVER_SENSE 0x08
#define DRIVER_MASK 0x0f
#define SUGGEST_MASK 0xf0
@@ -219,7 +220,19 @@
#define TYPE_TAPE 0x01
#define TYPE_WORM 0x04 /* Treated as ROM by our system */
#define TYPE_ROM 0x05
+#define TYPE_MOD 0x07 /* Magneto-optical disk - treated as TYPE_DISK */
#define TYPE_NO_LUN 0x7f
+
+/*
+ SCSI command sets
+
+*/
+
+#define SCSI_UNKNOWN 0
+#define SCSI_1 1
+#define SCSI_1_CCS 2
+#define SCSI_2 3
+
/*
Every SCSI command starts with a one byte OP-code.
The next byte's high three bits are the LUN of the
@@ -239,6 +252,7 @@ typedef struct scsi_device {
int access_count; /* Count of open channels/mounts */
struct wait_queue * device_wait; /* Used to wait if device is busy */
char type;
+ char scsi_level;
unsigned writeable:1;
unsigned removable:1;
unsigned random:1;
diff --git a/kernel/blk_drv/scsi/scsi_ioctl.c b/kernel/blk_drv/scsi/scsi_ioctl.c
index 213e416..8516a03 100644
--- a/kernel/blk_drv/scsi/scsi_ioctl.c
+++ b/kernel/blk_drv/scsi/scsi_ioctl.c
@@ -14,7 +14,7 @@
#define MAX_RETRIES 5
#define MAX_TIMEOUT 200
-#define MAX_BUF 8192
+#define MAX_BUF 4096
#define max(a,b) (((a) > (b)) ? (a) : (b))
@@ -51,6 +51,9 @@ static int ioctl_probe(int dev, void *buffer)
* 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.
+ * ERY: I changed this to a dynamic allocation using scsi_malloc - we were
+ * getting a kernel stack overflow which was crashing the system when we
+ * were using 8192 bytes.
*
* This size *does not* include the initial lengths that were passed.
*
@@ -133,12 +136,13 @@ static int ioctl_internal_command(Scsi_Device *dev, char * cmd)
static int ioctl_command(Scsi_Device *dev, void *buffer)
{
- char buf[MAX_BUF];
+ char * buf;
char cmd[10];
char * cmd_in;
Scsi_Cmnd * SCpnt;
unsigned char opcode;
int inlen, outlen, cmdlen, host;
+ int needed;
int result;
if (!buffer)
@@ -150,6 +154,15 @@ static int ioctl_command(Scsi_Device *dev, void *buffer)
cmd_in = (char *) ( ((int *)buffer) + 2);
opcode = get_fs_byte(cmd_in);
+ needed = (inlen > outlen ? inlen : outlen);
+ if(needed){
+ needed = (needed + 511) & ~511;
+ if (needed > MAX_BUF) needed = MAX_BUF;
+ buf = scsi_malloc(needed);
+ if (!buf) return -ENOMEM;
+ } else
+ buf = NULL;
+
memcpy_fromfs ((void *) cmd, cmd_in, cmdlen = COMMAND_SIZE (opcode));
memcpy_fromfs ((void *) buf, (void *) (cmd_in + cmdlen), inlen);
host = dev->host_no;
@@ -172,6 +185,7 @@ static int ioctl_command(Scsi_Device *dev, void *buffer)
memcpy_tofs ((void *) cmd_in, buf, (outlen > MAX_BUF) ? MAX_BUF : outlen);
result = SCpnt->result;
SCpnt->request.dev = -1; /* Mark as not busy */
+ if (buf) scsi_free(buf, needed);
wake_up(&scsi_devices[SCpnt->index].device_wait);
return result;
#else
diff --git a/kernel/blk_drv/scsi/sd.c b/kernel/blk_drv/scsi/sd.c
index c8a4d00..9f1e83b 100644
--- a/kernel/blk_drv/scsi/sd.c
+++ b/kernel/blk_drv/scsi/sd.c
@@ -45,7 +45,7 @@ struct hd_struct * sd;
int NR_SD=0;
int MAX_SD=0;
Scsi_Disk * rscsi_disks;
-int * sd_sizes;
+static int * sd_sizes;
/* used to re-read partitions. */
extern void resetup_one_dev(struct gendisk *, unsigned int);
@@ -320,13 +320,27 @@ static void do_sd_request (void)
{
Scsi_Cmnd * SCpnt = NULL;
struct request * req = NULL;
+ int flag = 0;
while (1==1){
if (CURRENT != NULL && CURRENT->dev == -1) return;
INIT_REQUEST;
- SCpnt = allocate_device(&CURRENT,
- rscsi_disks[DEVICE_NR(MINOR(CURRENT->dev))].device->index, 0);
+/* We have to be careful here. allocate_device will get a free pointer, but
+ there is no guarantee that it is queueable. In normal usage, we want to
+ call this, because other types of devices may have the host all tied up,
+ and we want to make sure that we have at least one request pending for this
+ type of device. We can also come through here while servicing an
+ interrupt, because of the need to start another command. If we call
+ allocate_device more than once, then the system can wedge if the command
+ is not queueable. The request_queueable function is safe because it checks
+ to make sure that the host is able to take another command before it returns
+ a pointer. */
+
+ if (flag++ == 0)
+ SCpnt = allocate_device(&CURRENT,
+ rscsi_disks[DEVICE_NR(MINOR(CURRENT->dev))].device->index, 0);
+ else SCpnt = NULL;
/* This is a performance enhancement. We dig down into the request list and
try and find a queueable request (i.e. device not busy, and host able to
diff --git a/kernel/blk_drv/scsi/sd_ioctl.c b/kernel/blk_drv/scsi/sd_ioctl.c
index c093306..1d60189 100644
--- a/kernel/blk_drv/scsi/sd_ioctl.c
+++ b/kernel/blk_drv/scsi/sd_ioctl.c
@@ -14,8 +14,6 @@
extern int scsi_ioctl (Scsi_Device *dev, int cmd, void *arg);
extern int revalidate_scsidisk(int, int);
-extern int sd_sizes[];
-
int sd_ioctl(struct inode * inode, struct file * file, unsigned long cmd, unsigned long arg)
{
int dev = inode->i_rdev;
@@ -32,7 +30,7 @@ int sd_ioctl(struct inode * inode, struct file * file, unsigned long cmd, unsign
diskinfo[1] = 0;
diskinfo[2] = 0;
if(scsi_hosts[host].bios_param != NULL)
- scsi_hosts[host].bios_param(sd_sizes[MINOR(dev)],
+ scsi_hosts[host].bios_param(rscsi_disks[MINOR(dev) >> 4].capacity,
dev,
&diskinfo[0]);
put_fs_byte(diskinfo[0],
diff --git a/kernel/blk_drv/scsi/seagate.c b/kernel/blk_drv/scsi/seagate.c
index 431bed6..7b11506 100644
--- a/kernel/blk_drv/scsi/seagate.c
+++ b/kernel/blk_drv/scsi/seagate.c
@@ -19,7 +19,8 @@
#include "seagate.h"
-static int internal_command(unsigned char target, const void *cmnd,
+static int internal_command(unsigned char target, unsigned char lun,
+ const void *cmnd,
void *buff, int bufflen, int reselect);
static int incommand; /*
@@ -209,7 +210,7 @@ const char *seagate_st0x_info(void)
* waiting for a reconnect
*/
-static unsigned char current_target;
+static unsigned char current_target, current_lun;
static unsigned char *current_cmnd, *current_data;
static int current_bufflen;
static void (*done_fn)(Scsi_Cmnd *) = NULL;
@@ -258,7 +259,7 @@ static void seagate_reconnect_intr (int unused)
current_target, current_data, current_bufflen);
#endif
- temp = internal_command (current_target,
+ temp = internal_command (current_target, current_lun,
current_cmnd, current_data, current_bufflen,
RECONNECT_NOW);
@@ -292,12 +293,13 @@ int seagate_st0x_queue_command (Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
done_fn = done;
current_target = SCpnt->target;
+ current_lun = SCpnt->lun;
(const void *) current_cmnd = SCpnt->cmnd;
current_data = SCpnt->request_buffer;
current_bufflen = SCpnt->request_bufflen;
SCint = SCpnt;
- result = internal_command (SCpnt->target, SCpnt->cmnd, SCpnt->request_buffer,
+ result = internal_command (SCpnt->target, SCpnt->lun, SCpnt->cmnd, SCpnt->request_buffer,
SCpnt->request_bufflen,
CAN_RECONNECT);
if (msg_byte(result) == DISCONNECT)
@@ -312,12 +314,12 @@ int seagate_st0x_queue_command (Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
int seagate_st0x_command (Scsi_Cmnd * SCpnt)
{
- return internal_command (SCpnt->target, SCpnt->cmnd, SCpnt->request_buffer,
+ return internal_command (SCpnt->target, SCpnt->lun, SCpnt->cmnd, SCpnt->request_buffer,
SCpnt->request_bufflen,
(int) NO_RECONNECT);
}
-static int internal_command(unsigned char target, const void *cmnd,
+static int internal_command(unsigned char target, unsigned char lun, const void *cmnd,
void *buff, int bufflen, int reselect)
{
int len;
@@ -805,7 +807,7 @@ static int internal_command(unsigned char target, const void *cmnd,
*/
if (reselect)
{
- DATA = IDENTIFY(1,0);
+ DATA = IDENTIFY(1, lun);
#if (DEBUG & (PHASE_RESELECT | PHASE_MSGOUT))
printk("scsi%d : sent IDENTIFY message.\n", hostno);
#endif
diff --git a/kernel/blk_drv/scsi/sr.c b/kernel/blk_drv/scsi/sr.c
index 0bab02a..9f9fb33 100644
--- a/kernel/blk_drv/scsi/sr.c
+++ b/kernel/blk_drv/scsi/sr.c
@@ -276,14 +276,17 @@ static void do_sr_request (void)
{
Scsi_Cmnd * SCpnt = NULL;
struct request * req = NULL;
+ int flag = 0;
while (1==1){
if (CURRENT != NULL && CURRENT->dev == -1) return;
INIT_REQUEST;
- SCpnt = allocate_device(&CURRENT,
- scsi_CDs[DEVICE_NR(MINOR(CURRENT->dev))].device->index, 0);
+ if (flag++ == 0)
+ SCpnt = allocate_device(&CURRENT,
+ scsi_CDs[DEVICE_NR(MINOR(CURRENT->dev))].device->index, 0);
+ else SCpnt = NULL;
/* This is a performance enhancement. We dig down into the request list and
diff --git a/kernel/blk_drv/scsi/st.c b/kernel/blk_drv/scsi/st.c
index 7e295ad..3ff1abb 100644
--- a/kernel/blk_drv/scsi/st.c
+++ b/kernel/blk_drv/scsi/st.c
@@ -16,6 +16,7 @@
- one buffer if one drive, two buffers if more than one drive (limits the
number of simultaneously open drives to two)
- write behind
+ - seek and tell (Tandberg compatible and SCSI-2)
Devices:
Autorewind devices have minor numbers equal to the tape numbers (0 > ).
@@ -29,7 +30,7 @@
Kai Makisara, Nov 9, 1992 email makisara@vtinsx.ins.vtt.fi or
Kai.Makisara@vtt.fi
- Last changes Nov 29, 1992.
+ Last changes Dec 6, 1992.
*/
#include <linux/fs.h>
@@ -51,9 +52,13 @@
#define MAX_RETRIES 5
#define NO_TAPE NOT_READY
+/* Uncomment the following if you want the rewind, etc. commands return
+ before command completion. */
+/* #define ST_NOWAIT */
+
/* #define DEBUG */
-#define ST_TIMEOUT 1000
+#define ST_TIMEOUT 2000
#define ST_LONG_TIMEOUT 200000
/* Number of ST_BLOCK_SIZE blocks in the buffers */
@@ -174,6 +179,102 @@ static void write_behind_check(int dev)
#endif
+/* Flush the write buffer */
+static int flush_write_buffer(int dev)
+{
+ int offset, transfer, blks;
+ int result;
+ unsigned char cmd[10];
+ Scsi_Cmnd *SCpnt;
+
+#if ST_WRITE_THRESHOLD_BLOCKS < ST_BUFFER_BLOCKS
+ if (scsi_tapes[dev].buffer->writing) {
+ write_behind_check(dev);
+ if (scsi_tapes[dev].buffer->last_result) {
+#ifdef DEBUG
+ printk("st%d: Async write error %x.\n", dev,
+ scsi_tapes[dev].buffer->last_result);
+#endif
+ return (-EIO);
+ }
+ }
+#endif
+
+ result = 0;
+ if (scsi_tapes[dev].dirty==1) {
+ SCpnt = allocate_device(NULL, scsi_tapes[dev].device->index, 1);
+
+ offset = scsi_tapes[dev].buffer->buffer_bytes;
+ transfer = ((offset + scsi_tapes[dev].block_size - 1) /
+ scsi_tapes[dev].block_size) * scsi_tapes[dev].block_size;
+#ifdef DEBUG
+ printk("st%d: Flushing %d bytes.\n", dev, transfer);
+#endif
+ memset(scsi_tapes[dev].buffer->b_data + offset, 0, transfer - offset);
+
+ SCpnt->sense_buffer[0] = 0;
+ memset(cmd, 0, 10);
+ cmd[0] = WRITE_6;
+ cmd[1] = 1;
+ blks = transfer / scsi_tapes[dev].block_size;
+ cmd[2] = blks >> 16;
+ cmd[3] = blks >> 8;
+ cmd[4] = blks;
+ SCpnt->request.dev = dev;
+ scsi_do_cmd (SCpnt,
+ (void *) cmd, scsi_tapes[dev].buffer->b_data, transfer,
+ st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
+
+ if (SCpnt->request.dev == dev) sleep_on( &scsi_tapes[dev].waiting );
+
+ if (SCpnt->result != 0) {
+ printk("st%d: Error on flush:\n", dev);
+#ifdef DEBUG
+ st_chk_result(dev, SCpnt->result, SCpnt->sense_buffer);
+#endif
+ result = (-EIO);
+ }
+ else {
+ scsi_tapes[dev].dirty = 0;
+ scsi_tapes[dev].buffer->buffer_bytes = 0;
+ }
+ SCpnt->request.dev = -1; /* Mark as not busy */
+ }
+ return result;
+}
+
+
+/* Flush the tape buffer. The tape will be positioned correctly unless
+ seek_next is true. */
+static int flush_buffer(struct inode * inode, struct file * filp,
+ int seek_next)
+{
+ int dev;
+ int backspace, result;
+
+ dev = inode->i_rdev & 127;
+
+ if (scsi_tapes[dev].rw == 2) /* Writing */
+ return flush_write_buffer(dev);
+
+ backspace = (scsi_tapes[dev].buffer->buffer_bytes +
+ scsi_tapes[dev].buffer->read_pointer) / scsi_tapes[dev].block_size -
+ (scsi_tapes[dev].buffer->read_pointer + scsi_tapes[dev].block_size - 1) /
+ scsi_tapes[dev].block_size;
+ scsi_tapes[dev].buffer->buffer_bytes = 0;
+ scsi_tapes[dev].buffer->read_pointer = 0;
+ result = 0;
+ if (!seek_next && backspace > 0) {
+ result = st_int_ioctl(inode, filp, MTBSR, backspace);
+ if (!result) {
+ scsi_tapes[dev].eof = 0;
+ scsi_tapes[dev].eof_hit = 0;
+ }
+ }
+ return result;
+
+}
+
/* Open the device */
static int scsi_tape_open(struct inode * inode, struct file * filp)
@@ -240,7 +341,7 @@ static int scsi_tape_open(struct inode * inode, struct file * filp)
SCpnt->request.dev = dev;
scsi_do_cmd(SCpnt,
(void *) cmd, (void *) scsi_tapes[dev].buffer->b_data,
- ST_BLOCK_SIZE, st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
+ ST_BLOCK_SIZE, st_sleep_done, ST_LONG_TIMEOUT, MAX_RETRIES);
if (SCpnt->request.dev == dev) sleep_on( &scsi_tapes[dev].waiting );
}
@@ -325,6 +426,14 @@ static int scsi_tape_open(struct inode * inode, struct file * filp)
65536 + scsi_tapes[dev].buffer->b_data[10] * 256 +
scsi_tapes[dev].buffer->b_data[11]);
#endif
+ if (scsi_tapes[dev].block_size > ST_BUFFER_SIZE) {
+ printk("st%d: Blocksize %d too large for buffer.\n", dev,
+ scsi_tapes[dev].block_size);
+ scsi_tapes[dev].buffer->in_use = 0;
+ scsi_tapes[dev].in_use = 0;
+ return (-EIO);
+ }
+
if (scsi_tapes[dev].block_size == 0) {
printk("st%d: Fixing block size to 512 bytes.\n", dev);
if (st_int_ioctl(inode, filp, MTSETBLK, ST_BLOCK_SIZE)) {
@@ -366,7 +475,8 @@ static int scsi_tape_open(struct inode * inode, struct file * filp)
static void scsi_tape_close(struct inode * inode, struct file * filp)
{
int dev;
- int offset, transfer, blks, rewind;
+ int result;
+ int rewind;
static unsigned char cmd[10];
Scsi_Cmnd * SCpnt;
@@ -376,81 +486,34 @@ static void scsi_tape_close(struct inode * inode, struct file * filp)
if ( scsi_tapes[dev].rw == 2) {
-#if ST_WRITE_THRESHOLD_BLOCKS < ST_BUFFER_BLOCKS
- if (scsi_tapes[dev].buffer->writing) {
- write_behind_check(dev);
- if (scsi_tapes[dev].buffer->last_result) {
- /* What should actually be done here ? */
- printk("st%d: Async write error %x.\n", dev,
- scsi_tapes[dev].buffer->last_result);
- }
- }
-#endif
-
- SCpnt = allocate_device(NULL, scsi_tapes[dev].device->index, 1);
+ result = flush_write_buffer(dev);
- if (scsi_tapes[dev].dirty==1) {
- offset = scsi_tapes[dev].buffer->buffer_bytes;
- transfer = ((offset + scsi_tapes[dev].block_size - 1) /
- scsi_tapes[dev].block_size) * scsi_tapes[dev].block_size;
#ifdef DEBUG
- printk("st%d: Final transfer %d bytes (length %d).\n", dev,
- transfer, filp->f_pos);
+ printk("st%d: File length %d bytes.\n", dev, filp->f_pos);
#endif
- memset(scsi_tapes[dev].buffer->b_data + offset, 0, transfer - offset);
+
+ if (!result) {
+ SCpnt = allocate_device(NULL, scsi_tapes[dev].device->index, 1);
SCpnt->sense_buffer[0] = 0;
memset(cmd, 0, 10);
- cmd[0] = WRITE_6;
- cmd[1] = 1;
- blks = transfer / scsi_tapes[dev].block_size;
- cmd[2] = blks >> 16;
- cmd[3] = blks >> 8;
- cmd[4] = blks;
+ cmd[0] = WRITE_FILEMARKS;
+ cmd[4] = 1;
SCpnt->request.dev = dev;
- scsi_do_cmd (SCpnt,
- (void *) cmd, scsi_tapes[dev].buffer->b_data, transfer,
- st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
+ scsi_do_cmd( SCpnt,
+ (void *) cmd, (void *) scsi_tapes[dev].buffer->b_data,
+ ST_BLOCK_SIZE, st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
if (SCpnt->request.dev == dev) sleep_on( &scsi_tapes[dev].waiting );
- if (SCpnt->result != 0) {
- printk("st%d: Error on last write:\n", dev);
+ if (SCpnt->result) {
+ printk("st%d: Error on write filemark:\n", dev);
#ifdef DEBUG
st_chk_result(dev, SCpnt->result, SCpnt->sense_buffer);
#endif
- SCpnt->request.dev = -1; /* Mark as not busy */
- if (rewind)
- st_int_ioctl(inode, filp, MTREW, 1);
- scsi_tapes[dev].buffer->in_use = 0;
- scsi_tapes[dev].in_use = 0;
- return;
}
- }
-
- SCpnt->sense_buffer[0] = 0;
- memset(cmd, 0, 10);
- cmd[0] = WRITE_FILEMARKS;
- cmd[4] = 1;
- SCpnt->request.dev = dev;
- scsi_do_cmd( SCpnt,
- (void *) cmd, (void *) scsi_tapes[dev].buffer->b_data, ST_BLOCK_SIZE,
- st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
-
- if (SCpnt->request.dev == dev) sleep_on( &scsi_tapes[dev].waiting );
- if (SCpnt->result) {
- printk("st%d: Error on write filemark:\n", dev);
-#ifdef DEBUG
- st_chk_result(dev, SCpnt->result, SCpnt->sense_buffer);
-#endif
SCpnt->request.dev = -1; /* Mark as not busy */
- if (rewind)
- st_int_ioctl(inode, filp, MTREW, 1);
- scsi_tapes[dev].buffer->in_use = 0;
- scsi_tapes[dev].in_use = 0;
- return;
}
- SCpnt->request.dev = -1; /* Mark as not busy */
#ifdef DEBUG
printk("st%d: Buffer flushed, EOF written\n", dev);
@@ -491,8 +554,10 @@ int st_write(struct inode * inode, struct file * filp, char * buf, int count)
return (-EACCES);
if (scsi_tapes[dev].rw == 1) {
- printk("st%d: No write allowed after read.\n", dev);
- return (-EACCES);
+ retval = flush_buffer(inode, filp, 0);
+ if (retval)
+ return retval;
+ scsi_tapes[dev].rw = 2;
}
#if ST_WRITE_THRESHOLD_BLOCKS < ST_BUFFER_BLOCKS
@@ -625,8 +690,10 @@ int st_read(struct inode * inode, struct file * filp, char * buf, int count)
#endif
if (scsi_tapes[dev].rw == 2) {
- printk("st%d: No read allowed after write.\n", dev);
- return (-EACCES);
+ transfer = flush_buffer(inode, filp, 0);
+ if (transfer)
+ return transfer;
+ scsi_tapes[dev].rw = 1;
}
#ifdef DEBUG
@@ -850,16 +917,20 @@ static int st_int_ioctl(struct inode * inode,struct file * file,
break;
case MTREW:
cmd[0] = REZERO_UNIT;
+#ifdef ST_NOWAIT
cmd[1] = 1; /* Don't wait for completion */
timeout = ST_TIMEOUT;
+#endif
#ifdef DEBUG
printk("st%d: Rewinding tape.\n", dev);
#endif
break;
case MTOFFL:
cmd[0] = START_STOP;
+#ifdef ST_NOWAIT
cmd[1] = 1; /* Don't wait for completion */
timeout = ST_TIMEOUT;
+#endif
#ifdef DEBUG
printk("st%d: Unloading tape.\n", dev);
#endif
@@ -872,9 +943,11 @@ static int st_int_ioctl(struct inode * inode,struct file * file,
break;
case MTRETEN:
cmd[0] = START_STOP;
+#ifdef ST_NOWAIT
cmd[1] = 1; /* Don't wait for completion */
- cmd[4] = 3;
timeout = ST_TIMEOUT;
+#endif
+ cmd[4] = 3;
#ifdef DEBUG
printk("st%d: Retensioning tape.\n", dev);
#endif
@@ -895,6 +968,30 @@ static int st_int_ioctl(struct inode * inode,struct file * file,
printk("st%d: Erasing tape.\n", dev);
#endif
break;
+ case MTSEEK:
+ if (scsi_tapes[dev].device->scsi_level < SCSI_2) {
+ cmd[0] = QFA_SEEK_BLOCK;
+ cmd[2] = (arg >> 16);
+ cmd[3] = (arg >> 8);
+ cmd[4] = arg;
+ cmd[5] = 0;
+ }
+ else {
+ cmd[0] = SEEK_10;
+ cmd[1] = 4;
+ cmd[3] = (arg >> 24);
+ cmd[4] = (arg >> 16);
+ cmd[5] = (arg >> 8);
+ cmd[6] = arg;
+ }
+#ifdef ST_NOWAIT
+ cmd[1] |= 1; /* Don't wait for completion */
+ timeout = ST_TIMEOUT;
+#endif
+#ifdef DEBUG
+ printk("st%d: Seeking tape to block %d.\n", dev, arg);
+#endif
+ break;
case MTSETBLK: /* Set block length */
case MTSETDENSITY: /* Set tape density */
if (scsi_tapes[dev].dirty || scsi_tapes[dev].buffer->buffer_bytes != 0)
@@ -950,8 +1047,27 @@ static int st_int_ioctl(struct inode * inode,struct file * file,
ioctl_result = st_chk_result(dev, SCpnt->result, SCpnt->sense_buffer);
- if (!ioctl_result && cmd_in == MTBSFM)
- ioctl_result = st_int_ioctl(inode, file, MTFSF, 1);
+ if (!ioctl_result) {
+ if (cmd_in == MTBSFM)
+ ioctl_result = st_int_ioctl(inode, file, MTFSF, 1);
+ else if (cmd_in == MTSETBLK) {
+ scsi_tapes[dev].block_size = arg;
+ scsi_tapes[dev].buffer->buffer_blocks =
+ ST_BUFFER_SIZE / scsi_tapes[dev].block_size;
+ scsi_tapes[dev].buffer->buffer_size =
+ scsi_tapes[dev].buffer->buffer_blocks * scsi_tapes[dev].block_size;
+ scsi_tapes[dev].buffer->buffer_bytes =
+ scsi_tapes[dev].buffer->read_pointer = 0;
+ }
+ if (cmd_in == MTEOM || cmd_in == MTWEOF) {
+ scsi_tapes[dev].eof = 2;
+ scsi_tapes[dev].eof_hit = 0;
+ }
+ else if (cmd_in != MTSETBLK && cmd_in != MTNOP) {
+ scsi_tapes[dev].eof = 0;
+ scsi_tapes[dev].eof_hit = 0;
+ }
+ }
return ioctl_result ;
}
@@ -963,9 +1079,11 @@ static int st_ioctl(struct inode * inode,struct file * file,
unsigned int cmd_in, unsigned int arg)
{
int dev = inode->i_rdev;
- int i, cmd;
+ int i, cmd, result;
struct mtop mtc;
- char *stp, *argp;
+ struct mtpos mt_pos;
+ unsigned char scmd[10];
+ Scsi_Cmnd *SCpnt;
dev = dev & 127;
#ifdef DEBUG
@@ -980,12 +1098,16 @@ static int st_ioctl(struct inode * inode,struct file * file,
if (((cmd_in & IOCSIZE_MASK) >> IOCSIZE_SHIFT) != sizeof(mtc))
return (-EINVAL);
+
verify_area((void *)arg, sizeof(mtc));
- stp = (char *) &mtc;
- argp = (char *) arg;
- for (i=0; i < sizeof(mtc); i++)
- *stp++ = get_fs_byte(argp++);
+ memcpy_fromfs((char *) &mtc, (char *)arg, sizeof(struct mtop));
+
+ i = flush_buffer(inode, file, mtc.mt_op == MTSEEK ||
+ mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||
+ mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM);
+ if (i < 0)
+ return i;
return st_int_ioctl(inode, file, mtc.mt_op, mtc.mt_count);
}
@@ -995,12 +1117,69 @@ static int st_ioctl(struct inode * inode,struct file * file,
return (-EINVAL);
verify_area((void *)arg, sizeof(struct mtget));
- stp = (char *) scsi_tapes[dev].buffer->mt_status;
- argp = (char *) arg;
- for (i=0; i < sizeof(struct mtget); i++)
- put_fs_byte(*stp++, argp++);
+ memcpy_tofs((char *)arg, (char *)scsi_tapes[dev].buffer->mt_status,
+ sizeof(struct mtget));
return 0;
}
+ else if (cmd == (MTIOCPOS & IOCCMD_MASK)) {
+#ifdef DEBUG
+ printk("st%d: get tape position.\n", dev);
+#endif
+ if (((cmd_in & IOCSIZE_MASK) >> IOCSIZE_SHIFT) != sizeof(struct mtpos))
+ return (-EINVAL);
+
+ i = flush_buffer(inode, file, 0);
+ if (i < 0)
+ return i;
+
+ verify_area((void *)arg, sizeof(struct mtpos));
+
+ SCpnt = allocate_device(NULL, scsi_tapes[dev].device->index, 1);
+
+ SCpnt->sense_buffer[0]=0;
+ memset (scmd, 0, 10);
+ if (scsi_tapes[dev].device->scsi_level < SCSI_2) {
+ scmd[0] = QFA_REQUEST_BLOCK;
+ scmd[4] = 3;
+ }
+ else {
+ scmd[0] = READ_POSITION;
+ scmd[1] = 1;
+ }
+ SCpnt->request.dev = dev;
+ SCpnt->sense_buffer[0] = 0;
+ scsi_do_cmd(SCpnt,
+ (void *) scmd, (void *) scsi_tapes[dev].buffer->b_data,
+ ST_BLOCK_SIZE, st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
+
+ if (SCpnt->request.dev == dev) sleep_on( &scsi_tapes[dev].waiting );
+
+ if (SCpnt->result || SCpnt->sense_buffer[0]) {
+ mt_pos.mt_blkno = (-1);
+#ifdef DEBUG
+ printk("st%d: Can't read tape position.\n", dev);
+#endif
+ result = (-EIO);
+ }
+ else {
+ result = 0;
+ if (scsi_tapes[dev].device->scsi_level < SCSI_2)
+ mt_pos.mt_blkno = (scsi_tapes[dev].buffer->b_data[0] << 16)
+ + (scsi_tapes[dev].buffer->b_data[1] << 8)
+ + scsi_tapes[dev].buffer->b_data[2];
+ else
+ mt_pos.mt_blkno = (scsi_tapes[dev].buffer->b_data[4] << 24)
+ + (scsi_tapes[dev].buffer->b_data[5] << 16)
+ + (scsi_tapes[dev].buffer->b_data[6] << 8)
+ + scsi_tapes[dev].buffer->b_data[7];
+
+ }
+
+ SCpnt->request.dev = -1; /* Mark as not busy */
+
+ memcpy_tofs((char *)arg, (char *) (&mt_pos), sizeof(struct mtpos));
+ return result;
+ }
else
return (-EINVAL);
}
diff --git a/kernel/blk_drv/scsi/st.h b/kernel/blk_drv/scsi/st.h
index 08218a4..e5c9b7b 100644
--- a/kernel/blk_drv/scsi/st.h
+++ b/kernel/blk_drv/scsi/st.h
@@ -39,5 +39,9 @@ typedef struct {
} Scsi_Tape;
+/* Positioning SCSI-commands for Tandberg, etc. drives */
+#define QFA_REQUEST_BLOCK 0x02
+#define QFA_SEEK_BLOCK 0x0c
+
#endif
diff --git a/kernel/blk_drv/scsi/ultrastor.c b/kernel/blk_drv/scsi/ultrastor.c
index b6541e0..0eac5a3 100644
--- a/kernel/blk_drv/scsi/ultrastor.c
+++ b/kernel/blk_drv/scsi/ultrastor.c
@@ -420,6 +420,10 @@ int ultrastor_14f_abort(Scsi_Cmnd *SCpnt, int code)
return 0;
}
+/* Most of this is commented out because people were getting kernel crashes
+ with it enabled. If you want to re-enable this, please figure out why
+ the kernel was panicing. ERY */
+
int ultrastor_14f_reset(void)
{
unsigned char in_byte;
@@ -428,6 +432,7 @@ int ultrastor_14f_reset(void)
printk("US14F: reset: called\n");
#endif
+#if 0
/* Issue SCSI BUS reset */
outb_p(0x20, LCL_DOORBELL_INTR(PORT_ADDRESS));
@@ -437,7 +442,7 @@ int ultrastor_14f_reset(void)
while (in_byte & 0x20);
aborted = DID_RESET;
-
+#endif
#if (ULTRASTOR_DEBUG & UD_RESET)
printk("US14F: reset: returning\n");
#endif
diff --git a/kernel/blk_drv/scsi/wd7000.c b/kernel/blk_drv/scsi/wd7000.c
index 21beb60..61b5437 100644
--- a/kernel/blk_drv/scsi/wd7000.c
+++ b/kernel/blk_drv/scsi/wd7000.c
@@ -7,6 +7,8 @@
*
* Revised (and renamed) by John Boyd <boyd@cis.ohio-state.edu> to
* accomodate Eric Youngdale's modifications to scsi.c. Nov 1992.
+ *
+ * Additional changes to support scatter/gather. Dec. 1992. tw/jb
*/
#include <stdarg.h>
@@ -46,19 +48,12 @@
- For now, a pool of SCBs are kept in global storage by this driver,
and are allocated and freed as needed.
- For two reasons, I decided not to use a single SCB per OGMB:
- - the 7000-FASST2 marks OGMBs empty as soon as it has _started_ a command,
- not when it has finished. Since the SCB must be around for completion,
- problems arise when SCBs correspond to OGMBs, which may be reallocated
- earlier (or delayed unnecessarily until a command completes).
- - Scatter/gather can be implemented by this driver using an SCB per
- scatter/gather buffer, but this is difficult when SCBs and Scsi_Cmnds
- are matched 1-1 via this correspondence.
-
- Instead, mailboxes are used as transient data structures, simply for
- carrying SCB addresses to/from the 7000-FASST2. SCBs are allocated as
- "host_scribble" in an Scsi_Cmnd, and are maintained relative to that
- Scsi_Cmnd.
+ The 7000-FASST2 marks OGMBs empty as soon as it has _started_ a command,
+ not when it has finished. Since the SCB must be around for completion,
+ problems arise when SCBs correspond to OGMBs, which may be reallocated
+ earlier (or delayed unnecessarily until a command completes).
+ Mailboxes are used as transient data structures, simply for
+ carrying SCB addresses to/from the 7000-FASST2.
Note also since SCBs are not "permanently" associated with mailboxes,
there is no need to keep a global list of Scsi_Cmnd pointers indexed
@@ -66,6 +61,8 @@
indices need not be involved.
*/
+static void wd7000_set_sync(int id);
+
static struct {
struct wd_mailbox ogmb[OGMB_CNT];
struct wd_mailbox icmb[ICMB_CNT];
@@ -78,9 +75,11 @@ static Scb *scbfree = NULL;
static int wd7000_host = 0;
static unchar controlstat = 0;
+static unchar rev_1 = 0, rev_2 = 0; /* filled in by wd7000_revision */
+
#define wd7000_intr_ack() outb(0,INTR_ACK)
-static long WAITnexttimeout = 3000000;
+#define WAITnexttimeout 3000000
static inline void wd7000_enable_intr()
@@ -210,6 +209,7 @@ static int mail_out( Scb *scbptr )
ogmb = (++ogmb) % OGMB_CNT;
}
restore_flags(flags);
+ DEB(printk(", scb is %x",scbptr);)
if (i >= OGMB_CNT) {
DEB(printk(", no free OGMBs.\n");)
@@ -293,7 +293,7 @@ void wd7000_intr_handle(int irq)
{
int flag, icmb, errstatus, icmb_status;
int host_error, scsi_error;
- Scb *scb, *scbn; /* for SCSI commands */
+ Scb *scb; /* for SCSI commands */
unchar *icb; /* for host commands */
Scsi_Cmnd *SCpnt;
@@ -320,11 +320,11 @@ void wd7000_intr_handle(int irq)
mb.icmb[icmb].status = 0;
#ifdef DEBUG
- printk(" ICMB %d posted for SCB/ICB %06x, status %02x",
- icmb, scb, icmb_status );
+ printk(" ICMB %d posted for SCB/ICB %06x, status %02x, vue %02x",
+ icmb, scb, icmb_status, scb->vue );
#endif
- if (scb->op == 0) { /* an SCB is done */
+ if (!(scb->op & 0x80)) { /* an SCB is done */
SCpnt = scb->SCpnt;
if (--(SCpnt->SCp.phase) <= 0) { /* all scbs for SCpnt are done */
host_error = scb->vue | (icmb_status << 8);
@@ -332,12 +332,9 @@ void wd7000_intr_handle(int irq)
errstatus = make_code(host_error,scsi_error);
SCpnt->result = errstatus;
- scb = (Scb *) SCpnt->host_scribble; scbn = scb;
- while (scb != NULL) {
- scbn = scb->next;
- free_scb(scb);
- scb = scbn;
- }
+ if (SCpnt->host_scribble != NULL)
+ scsi_free(SCpnt->host_scribble,WD7000_SCRIBBLE);
+ free_scb(scb);
SCpnt->scsi_done(SCpnt);
}
@@ -356,6 +353,7 @@ void wd7000_intr_handle(int irq)
int wd7000_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
{
Scb *scb;
+ Sgb *sgb;
unchar *cdb;
unchar idlun;
short cdblen;
@@ -364,70 +362,54 @@ int wd7000_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
cdblen = (*cdb <= 0x1f ? 6 : 10);
idlun = ((SCpnt->target << 5) & 0xe0) | (SCpnt->lun & 7);
SCpnt->scsi_done = done;
-
- if (SCpnt->use_sg) { /* set up linked SCBs to do scatter/gather */
-#ifdef 0
+ SCpnt->SCp.phase = 1;
+ scb = alloc_scb();
+ scb->idlun = idlun;
+ memcpy(scb->cdb, cdb, cdblen);
+ scb->direc = 0x40; /* Disable direction check */
+ scb->SCpnt = SCpnt; /* so we can find stuff later */
+ SCpnt->host_scribble = NULL;
+ DEB(printk("request_bufflen is %x, bufflen is %x\n",\
+ SCpnt->request_bufflen, SCpnt->bufflen);)
+
+ if (SCpnt->use_sg) {
struct scatterlist *sg = (struct scatterlist *) SCpnt->request_buffer;
- short i;
- Scb *scbn;
-
- /*
- Allocate the scbs first, and set the next pointers, since we
- need these later.
- Save the list via host_scribble.
- */
- scbn = NULL;
- for (i = 0; i < SCpnt->use_sg; i++) {
- scb = alloc_scb(); scb->next = scbn; scbn = scb;
+ unsigned i;
+
+ if (scsi_hosts[wd7000_host].sg_tablesize <= 0) {
+ panic("wd7000_queuecommand: scatter/gather not supported.\n");
}
- SCpnt->host_scribble = (unchar *) scb;
- /*
- Note that the following is set up do to scatter/gather via
- linked commands, with an interrupt only after _all_ are
- finished. This is mostly to simplify error handling, which
- hasn't been added to the interrupt handler for the other case
- (interrupt per SCB). However, this should work with intr/SCB
- by setting phase = use_sg and setting the flag bit in each
- of the CDBs.
- */
- SCpnt->SCp.phase = 1; /* set this to the # of interrupts expected */
+#ifdef DEBUG
+ printk("Using scatter/gather with %d elements.\n",SCpnt->use_sg);
+#endif
+ /*
+ Allocate memory for a scatter/gather-list in wd7000 format.
+ Save the pointer at host_scribble.
+ */
+#ifdef DEBUG
+ if (SCpnt->use_sg > WD7000_SG)
+ panic("WD7000: requesting too many scatterblocks\n");
+#endif
+ SCpnt->host_scribble = scsi_malloc(WD7000_SCRIBBLE);
+ sgb = (Sgb *) SCpnt->host_scribble;
+ if (sgb == NULL)
+ panic("wd7000_queuecommand: scsi_malloc() failed.\n");
+
+ scb->op = 1;
+ any2scsi(scb->dataptr, sgb);
+ any2scsi(scb->maxlen, SCpnt->use_sg * sizeof (Sgb) );
for (i = 0; i < SCpnt->use_sg; i++) {
- scb->op = 0;
- scb->idlun = idlun;
- memcpy(scb->cdb, cdb, cdblen);
- /*
- Here, set CDB fields for block address & block count.
- I don't know block size; that's why this whole thing is
- commented out. Would be nice if scatterlist had both
- byte and block counts per element (block address could be
- computed).
- Also need to know for sure if any SCSI commands other than
- READ/WRITE can use scatter/gather - I would hope not.
- */
- any2scsi(scb->dataptr, sg[i].address);
- any2scsi(scb->maxlen, sg[i].length);
- if (i < SCpnt->use_sg-1) { /* if this isn't the last */
- any2scsi(scb->linkptr, scb->next); /* set link */
- scb->cdb[cdblen-1] |= 0x01; /* set link bit */
- }
- scb->direc = 0x40; /* Disable direction check */
- scb->SCpnt = SCpnt; /* so we can find stuff later */
+ any2scsi(sgb->ptr, sg[i].address);
+ any2scsi(sgb->len, sg[i].length);
+ sgb++;
}
-#else
- panic("wd7000_queuecommand: scatter/gather not implemented.\n");
-#endif
- } else { /* just one command - use scb[0] */
- SCpnt->SCp.phase = 1;
- scb = alloc_scb();
- SCpnt->host_scribble = (unchar *) scb;
+ DEB(printk("Using %d bytes for %d scatter/gather blocks\n",\
+ scsi2int(scb->maxlen), SCpnt->use_sg);)
+ } else {
scb->op = 0;
- scb->idlun = idlun;
- memcpy(scb->cdb, cdb, cdblen);
any2scsi(scb->dataptr, SCpnt->request_buffer);
any2scsi(scb->maxlen, SCpnt->request_bufflen);
- scb->direc = 0x40; /* Disable direction check */
- scb->SCpnt = SCpnt; /* so we can find stuff later */
}
return mail_out(scb);
@@ -509,6 +491,23 @@ int wd7000_init(void)
}
+void wd7000_revision(void)
+{
+ volatile unchar icb[ICB_LEN] = {0x8c}; /* read firmware revision level */
+
+ icb[ICB_PHASE] = 1;
+ mail_out( (struct scb *) icb );
+ while (icb[ICB_PHASE]) /* wait for completion */;
+ rev_1 = icb[1];
+ rev_2 = icb[2];
+
+ /*
+ For boards at rev 7.0 or later, enable scatter/gather.
+ */
+ if (rev_1 >= 7) scsi_hosts[wd7000_host].sg_tablesize = WD7000_SG;
+}
+
+
static const char *wd_bases[] = {(char *)0xce000};
typedef struct {
char * signature;
@@ -521,15 +520,13 @@ static const Signature signatures[] = {{"SSTBIOS",0xd,0x7}};
#define NUM_SIGNATURES (sizeof(signatures)/sizeof(Signature))
-int wd7000_detect(int hostnum) /* hostnum ignored for now */
+int wd7000_detect(int hostnum)
/*
* return non-zero on detection
*/
{
int i,j;
- char const * base_address = 0;
- /* Store our host number */
- wd7000_host = hostnum;
+ char const *base_address = NULL;
for(i=0;i<(sizeof(wd_bases)/sizeof(char *));i++){
for(j=0;j<NUM_SIGNATURES;j++){
@@ -540,8 +537,13 @@ int wd7000_detect(int hostnum) /* hostnum ignored for now */
}
}
}
- if (!base_address) return 0;
+ if (base_address == NULL) return 0;
+
+ /* Store our host number */
+ wd7000_host = hostnum;
+
wd7000_init();
+ wd7000_revision(); /* will set scatter/gather by rev level */
return 1;
}
@@ -567,19 +569,25 @@ static void wd7000_append_info( char *info, const char *fmt, ... )
const char *wd7000_info(void)
{
static char info[80] = "Western Digital WD-7000, Firmware Revision ";
- volatile unchar icb[ICB_LEN] = {0x8c}; /* read firmware revision level */
- unchar rl1, rl2;
+
+ wd7000_revision();
+ wd7000_append_info( info+strlen(info), "%d.%d.\n", rev_1, rev_2 );
+
+ return info;
+}
+
+
+void wd7000_set_sync(int id)
+{
+ volatile unchar icb[ICB_LEN] = {0x8a};
+ unchar speedval = 0x2c; /* Sets 4MHz for SBIC Revision A */
+ any2scsi(icb+2,1); /* Transfer 1 byte */
+ any2scsi(icb+5,&speedval); /* The speed buffer address */
+ icb[8]=0; icb[9]=2*id; /* The index into the table */
icb[ICB_PHASE] = 1;
mail_out( (struct scb *) icb );
while (icb[ICB_PHASE]) /* wait for completion */;
- rl1 = icb[1];
- rl2 = icb[2];
-
- /* now format the above, and append to info */
- wd7000_append_info( info+strlen(info), "%d.%d.\n", rl1, rl2 );
-
- return info;
}
@@ -599,7 +607,9 @@ int wd7000_abort(Scsi_Cmnd * SCpnt, int i)
int wd7000_reset(void)
{
+#ifdef DEBUG
printk("wd7000_reset\n");
+#endif
return 0;
}
diff --git a/kernel/blk_drv/scsi/wd7000.h b/kernel/blk_drv/scsi/wd7000.h
index a32498e..bc27c61 100644
--- a/kernel/blk_drv/scsi/wd7000.h
+++ b/kernel/blk_drv/scsi/wd7000.h
@@ -82,8 +82,8 @@
/*
* For INITIALIZATION:
*/
-#define BUS_ON 24 /* x 125ns, 24 = 3000ns, BIOS uses 8000ns */
-#define BUS_OFF 24 /* x 125ns, BIOS uses 1875ns */
+#define BUS_ON 48 /* x 125ns, 48 = 6000ns, BIOS uses 8000ns */
+#define BUS_OFF 24 /* x 125ns, 24 = 3000ns, BIOS uses 1875ns */
#define INTR_ACK ASC_STAT+1
@@ -143,6 +143,14 @@ typedef struct scb { /* Command Control Block 5.4.1 */
} Scb;
/*
+ * WD7000-specific scatter/gather element structure
+ */
+typedef struct sgb {
+ unchar len[3];
+ unchar ptr[3];
+} Sgb;
+
+/*
* Note: MAX_SCBS _must_ be defined large enough to keep ahead of the
* demand for SCBs, which will be at most WD7000_Q * WD7000_SG. 1 is
* added to each because they can be 0.
@@ -171,8 +179,18 @@ int wd7000_biosparam(int, int, int*);
#define NULL 0
#endif
+/*
+ * Define WD7000_SG to be the number of Sgbs that will fit in a block of
+ * size WD7000_SCRIBBLE. WD7000_SCRIBBLE must be 512, 1024, 2048, or 4096.
+ *
+ * The sg_tablesize value will default to SG_NONE for older boards (before
+ * rev 7.0), but will be changed to WD7000_SG when a newer board is
+ * detected.
+ */
+#define WD7000_SCRIBBLE 512
+
#define WD7000_Q OGMB_CNT
-#define WD7000_SG SG_NONE
+#define WD7000_SG (WD7000_SCRIBBLE / sizeof(Sgb))
#define WD7000 {\
"Western Digital WD-7000", \
@@ -183,5 +201,5 @@ int wd7000_biosparam(int, int, int*);
wd7000_reset, \
NULL, \
wd7000_biosparam, \
- WD7000_Q, 7, WD7000_SG, 1, 0, 1}
+ WD7000_Q, 7, SG_NONE, 1, 0, 1}
#endif
diff --git a/kernel/chr_drv/Makefile b/kernel/chr_drv/Makefile
index 4c04ab4..6b76915 100644
--- a/kernel/chr_drv/Makefile
+++ b/kernel/chr_drv/Makefile
@@ -16,10 +16,14 @@
.c.o:
$(CC) $(CFLAGS) -c $<
+SUBDIRS= sound
+
OBJS = tty_io.o console.o keyboard.o serial.o \
tty_ioctl.o pty.o lp.o vt.o mem.o mouse.o \
busmouse.o psaux.o msbusmouse.o atixlmouse.o
+all: chr_drv.a subdirs
+
chr_drv.a: $(OBJS)
$(AR) rcs chr_drv.a $(OBJS)
sync
@@ -30,170 +34,22 @@ console.o: console.c
keyboard.o: keyboard.c
$(CC) $(CFLAGS) $(KEYBOARD) -c -o keyboard.o keyboard.c
+subdirs: dummy
+ @for i in $(SUBDIRS); do (cd $$i && echo $$i && $(MAKE)) || exit; done
+
clean:
- rm -f core *.o *.a tmp_make keyboard.s
- for i in *.c;do rm -f `basename $$i .c`.s;done
+ rm -f core *.o *.a *.s
+ for i in $(SUBDIRS); do (cd $$i && $(MAKE) clean) || exit; done
dep:
- sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
- $(CPP) -M $(KEYBOARD) *.c >> tmp_make
- cp tmp_make Makefile
+ $(CPP) -M $(KEYBOARD) *.c > .depend
+ for i in $(SUBDIRS); do (cd $$i && $(MAKE) dep) || exit; done
-### Dependencies:
-atixlmouse.o : atixlmouse.c /usr/include/linux/kernel.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
- /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/tty.h \
- /usr/include/linux/termios.h /usr/include/asm/system.h /usr/include/linux/errno.h \
- /usr/include/asm/io.h /usr/include/asm/segment.h /usr/include/asm/irq.h
-busmouse.o : busmouse.c /usr/include/linux/kernel.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
- /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/busmouse.h \
- /usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/asm/system.h \
- /usr/include/linux/errno.h /usr/include/asm/io.h /usr/include/asm/segment.h \
- /usr/include/asm/irq.h
-console.o : console.c /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/timer.h /usr/include/linux/tty.h \
- /usr/include/linux/termios.h /usr/include/asm/system.h /usr/include/linux/config.h \
- /usr/include/linux/config.dist.h /usr/include/linux/string.h /usr/include/linux/errno.h \
- /usr/include/linux/kd.h /usr/include/linux/keyboard.h /usr/include/asm/io.h \
- /usr/include/asm/segment.h vt_kern.h
-keyboard.o : keyboard.c /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/ctype.h \
- /usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/asm/system.h \
- /usr/include/linux/ptrace.h /usr/include/linux/keyboard.h /usr/include/asm/io.h
-lp.o : lp.c /usr/include/linux/lp.h /usr/include/linux/errno.h /usr/include/linux/kernel.h \
- /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
- /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
- /usr/include/asm/io.h /usr/include/asm/segment.h
-mem.o : mem.c /usr/include/linux/types.h /usr/include/linux/errno.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/tty.h \
- /usr/include/linux/termios.h /usr/include/asm/system.h /usr/include/linux/mouse.h \
- /usr/include/linux/user.h /usr/include/linux/ptrace.h /usr/include/linux/a.out.h \
- /usr/include/linux/string.h /usr/include/asm/segment.h /usr/include/asm/io.h
-mouse.o : mouse.c /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/errno.h /usr/include/linux/mouse.h
-msbusmouse.o : msbusmouse.c /usr/include/linux/kernel.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
- /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/busmouse.h \
- /usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/asm/system.h \
- /usr/include/linux/errno.h /usr/include/asm/io.h /usr/include/asm/segment.h \
- /usr/include/asm/irq.h
-psaux.o : psaux.c /usr/include/linux/timer.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/fcntl.h \
- /usr/include/linux/errno.h /usr/include/asm/io.h /usr/include/asm/segment.h \
- /usr/include/asm/system.h
-pty.o : pty.c /usr/include/linux/errno.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/tty.h \
- /usr/include/linux/termios.h /usr/include/asm/system.h /usr/include/linux/fcntl.h \
- /usr/include/asm/io.h
-serial.o : serial.c /usr/include/linux/errno.h /usr/include/linux/signal.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
- /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/timer.h \
- /usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/asm/system.h \
- /usr/include/linux/serial.h /usr/include/asm/io.h /usr/include/asm/segment.h \
- /usr/include/asm/bitops.h
-tty_io.o : tty_io.c /usr/include/linux/types.h /usr/include/linux/errno.h /usr/include/linux/signal.h \
- /usr/include/linux/fcntl.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/time.h /usr/include/linux/param.h \
- /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
- /usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/asm/system.h \
- /usr/include/linux/ctype.h /usr/include/linux/kd.h /usr/include/linux/string.h \
- /usr/include/linux/keyboard.h /usr/include/asm/segment.h /usr/include/asm/bitops.h \
- vt_kern.h
-tty_ioctl.o : tty_ioctl.c /usr/include/linux/types.h /usr/include/linux/termios.h \
- /usr/include/linux/errno.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/tty.h /usr/include/asm/system.h \
- /usr/include/linux/fcntl.h /usr/include/asm/io.h /usr/include/asm/segment.h
-vt.o : vt.c /usr/include/linux/types.h /usr/include/linux/errno.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/tty.h \
- /usr/include/linux/termios.h /usr/include/asm/system.h /usr/include/linux/timer.h \
- /usr/include/linux/keyboard.h /usr/include/linux/kd.h /usr/include/linux/vt.h \
- /usr/include/asm/io.h /usr/include/asm/segment.h vt_kern.h
+dummy:
+
+#
+# include a dependency file if one exists
+#
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
diff --git a/kernel/chr_drv/console.c b/kernel/chr_drv/console.c
index 44f9c0b..a3b5f96 100644
--- a/kernel/chr_drv/console.c
+++ b/kernel/chr_drv/console.c
@@ -88,17 +88,13 @@ static struct {
unsigned long vc_saved_x;
unsigned long vc_saved_y;
/* mode flags */
- unsigned long vc_kbdapplic : 1; /* Application keyboard */
unsigned long vc_charset : 1; /* Character set G0 / G1 */
unsigned long vc_s_charset : 1; /* Saved character set */
- unsigned long vc_decckm : 1; /* Cursor Keys Mode */
unsigned long vc_decscnm : 1; /* Screen Mode */
unsigned long vc_decom : 1; /* Origin Mode */
unsigned long vc_decawm : 1; /* Autowrap Mode */
- unsigned long vc_decarm : 1; /* Autorepeat Mode */
unsigned long vc_deccm : 1; /* Cursor Visible */
unsigned long vc_decim : 1; /* Insert Mode */
- unsigned long vc_lnm : 1; /* Line feed New line Mode */
/* attribute flags */
unsigned long vc_intensity : 2; /* 0=half-bright, 1=normal, 2=bold */
unsigned long vc_underline : 1;
@@ -154,7 +150,6 @@ static int console_blanked = 0;
#define decawm (vc_cons[currcons].vc_decawm)
#define deccm (vc_cons[currcons].vc_deccm)
#define decim (vc_cons[currcons].vc_decim)
-#define kbdapplic (vc_cons[currcons].vc_kbdapplic)
#define need_wrap (vc_cons[currcons].vc_need_wrap)
#define color (vc_cons[currcons].vc_color)
#define s_color (vc_cons[currcons].vc_s_color)
@@ -182,7 +177,8 @@ static int console_blanked = 0;
#define is_kbd(x) vc_kbd_flag(kbd_table+currcons,x)
#define decarm VC_REPEAT
-#define decckm VC_APPLIC
+#define decckm VC_CKMODE
+#define kbdapplic VC_APPLIC
#define kbdraw VC_RAW
#define lnm VC_CRLF
@@ -868,7 +864,6 @@ static void reset_terminal(int currcons, int do_clear)
clr_kbd(decckm);
clr_kbd(kbdapplic);
clr_kbd(lnm);
-#define is_kbd(x) vc_kbd_flag(kbd_table+currcons,x)
kbd_table[currcons].flags =
(kbd_table[currcons].flags & ~LED_MASK) |
(kbd_table[currcons].default_flags & LED_MASK);
@@ -1012,10 +1007,10 @@ void con_write(struct tty_struct * tty)
reset_terminal(currcons,1);
continue;
case '>': /* Numeric keypad */
- kbdapplic = 0;
+ clr_kbd(kbdapplic);
continue;
case '=': /* Appl. keypad */
- kbdapplic = 1;
+ set_kbd(kbdapplic);
continue;
}
continue;
diff --git a/kernel/chr_drv/mem.c b/kernel/chr_drv/mem.c
index ca486b5..967efe0 100644
--- a/kernel/chr_drv/mem.c
+++ b/kernel/chr_drv/mem.c
@@ -10,6 +10,7 @@
#include <linux/kernel.h>
#include <linux/tty.h>
#include <linux/mouse.h>
+#include <linux/soundcard.h>
#include <linux/user.h>
#include <linux/a.out.h>
@@ -339,5 +340,6 @@ long chr_dev_init(long mem_start, long mem_end)
mem_start = tty_init(mem_start);
mem_start = lp_init(mem_start);
mem_start = mouse_init(mem_start);
+ mem_start = soundcard_init(mem_start);
return mem_start;
}
diff --git a/kernel/chr_drv/mouse.c b/kernel/chr_drv/mouse.c
index cecde8c..a67c567 100644
--- a/kernel/chr_drv/mouse.c
+++ b/kernel/chr_drv/mouse.c
@@ -17,6 +17,7 @@
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/mouse.h>
+#include <linux/config.h>
/*
* note that you can remove any or all of the drivers by undefining
@@ -37,22 +38,22 @@ static int mouse_open(struct inode * inode, struct file * file)
int minor = MINOR(inode->i_rdev);
switch (minor) {
-#ifdef BUSMOUSE_MINOR
+#ifdef CONFIG_BUSMOUSE
case BUSMOUSE_MINOR:
file->f_op = &bus_mouse_fops;
break;
#endif
-#ifdef PSMOUSE_MINOR
+#ifdef CONFIG_PSMOUSE
case PSMOUSE_MINOR:
file->f_op = &psaux_fops;
break;
#endif
-#ifdef MS_BUSMOUSE_MINOR
+#ifdef CONFIG_MS_BUSMOUSE
case MS_BUSMOUSE_MINOR:
file->f_op = &ms_bus_mouse_fops;
break;
#endif
-#ifdef ATIXL_BUSMOUSE_MINOR
+#ifdef CONFIG_ATIXL_BUSMOUSE
case ATIXL_BUSMOUSE_MINOR:
file->f_op = &atixl_busmouse_fops;
break;
@@ -77,16 +78,16 @@ static struct file_operations mouse_fops = {
unsigned long mouse_init(unsigned long kmem_start)
{
-#ifdef BUSMOUSE_MINOR
+#ifdef CONFIG_BUSMOUSE
kmem_start = bus_mouse_init(kmem_start);
#endif
-#ifdef PSMOUSE_MINOR
+#ifdef CONFIG_PSMOUSE
kmem_start = psaux_init(kmem_start);
#endif
-#ifdef MS_BUSMOUSE_MINOR
+#ifdef CONFIG_MS_BUSMOUSE
kmem_start = ms_bus_mouse_init(kmem_start);
#endif
-#ifdef ATIXL_BUSMOUSE_MINOR
+#ifdef CONFIG_ATIXL_BUSMOUSE
kmem_start = atixl_busmouse_init(kmem_start);
#endif
chrdev_fops[10] = &mouse_fops;
diff --git a/kernel/chr_drv/psaux.c b/kernel/chr_drv/psaux.c
index 8b1c8c1..2eb51bf 100644
--- a/kernel/chr_drv/psaux.c
+++ b/kernel/chr_drv/psaux.c
@@ -235,7 +235,7 @@ repeat:
goto repeat;
}
current->state = TASK_RUNNING;
-
+ remove_wait_queue(&queue->proc_list, &wait);
}
while (i > 0 && !queue_empty()) {
c = get_from_queue();
diff --git a/kernel/chr_drv/pty.c b/kernel/chr_drv/pty.c
index 5522bd5..46221e9 100644
--- a/kernel/chr_drv/pty.c
+++ b/kernel/chr_drv/pty.c
@@ -29,8 +29,8 @@ static void pty_close(struct tty_struct * tty, struct file * filp)
return;
wake_up_interruptible(&tty->link->write_q.proc_list);
if (IS_A_PTY_MASTER(tty->line)) {
- if (tty->link->pgrp > 0)
- kill_pg(tty->link->pgrp,SIGHUP,1);
+ if (tty->link->session > 0)
+ kill_sl(tty->link->session,SIGHUP,1);
}
}
diff --git a/kernel/chr_drv/serial.c b/kernel/chr_drv/serial.c
index 70cd2e4..5a4ac26 100644
--- a/kernel/chr_drv/serial.c
+++ b/kernel/chr_drv/serial.c
@@ -10,6 +10,9 @@
* multiple ports (or boards, if the hardware permits) to share a
* single IRQ channel.
*
+ * set_serial_info fixed to set the flags, custom divisor, and uart
+ * type fields. Fix suggested by Michael K. Johnson 12/12/92.
+ *
* This module exports the following rs232 io functions:
*
* long rs_init(long);
@@ -23,24 +26,42 @@
#include <linux/timer.h>
#include <linux/tty.h>
#include <linux/serial.h>
+#include <linux/config.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/segment.h>
#include <asm/bitops.h>
-#define WAKEUP_CHARS (3*TTY_BUF_SIZE/4)
-
/*
- * Define this to get the AUTO_IRQ code..
- */
-#undef AUTO_IRQ
-
-/*
- * Define this to get support for the nonstandard
- * serial lines.
+ * Serial driver configuration section. Here are the various options:
+ *
+ * CONFIG_AUTO_IRQ
+ * Enables automatic IRQ detection. I've put in some
+ * fixes to this which should make this work much more
+ * cleanly than it used to in 0.98pl2-6. It should be
+ * much less vulnerable to false IRQ's now.
+ *
+ * NEW_INTERRUPT_ROUTINE
+ * Enables the new interrupt routine, which is faster
+ * (which is better on slow CPU's), and handles parity
+ * errors, break conditions, and hardware handshaking.
+ * People were having problems with it earlier, but I
+ * believe they have been fixed now, so there should
+ * hopefully be no reason to #undef this option.
+ *
+ * CONFIG_AST_FOURPORT
+ * Enables support for the AST Fourport serial port.
+ *
+ * CONFIG_ACCENT_ASYNC
+ * Enables support for the Accent Async 4 port serial
+ * port.
+ *
*/
-#undef NONSTANDARD_PORTS
+
+#define NEW_INTERRUPT_ROUTINE
+
+#define WAKEUP_CHARS (3*TTY_BUF_SIZE/4)
/*
* rs_event - Bitfield of serial lines that events pending
@@ -64,12 +85,14 @@ struct struct_ISR COM2_ISR = { 3, 0x2f8, UART_ISR_proc, 0, };
struct struct_ISR COM3_ISR = { 4, 0x3e8, UART_ISR_proc, 0, };
struct struct_ISR COM4_ISR = { 3, 0x2e8, UART_ISR_proc, 0, };
-#ifdef NONSTANDARD_PORTS
+#ifdef CONFIG_AST_FOURPORT
static void FourPort_ISR_proc(async_ISR ISR, int line);
struct struct_ISR FourPort1_ISR = { 2, 0x1bf, FourPort_ISR_proc, 0, };
struct struct_ISR FourPort2_ISR = { 5, 0x2bf, FourPort_ISR_proc, 0, };
+#endif
+#ifdef CONFIG_ACCENT_ASYNC
struct struct_ISR Accent3_ISR = { 4, 0x330, UART_ISR_proc, 0, };
struct struct_ISR Accent4_ISR = { 4, 0x338, UART_ISR_proc, 0, };
#endif
@@ -88,7 +111,7 @@ struct async_struct rs_table[] = {
{ BASE_BAUD, 0x2F8, &COM2_ISR, 0, },
{ BASE_BAUD, 0x3E8, &COM3_ISR, 0, },
{ BASE_BAUD, 0x2E8, &COM4_ISR, 0, },
-#ifdef NONSTANDARD_PORTS
+#ifdef CONFIG_AST_FOURPORT
{ BASE_BAUD, 0x1A0, &FourPort1_ISR, ASYNC_FOURPORT },
{ BASE_BAUD, 0x1A8, &FourPort1_ISR, ASYNC_FOURPORT },
{ BASE_BAUD, 0x1B0, &FourPort1_ISR, ASYNC_FOURPORT },
@@ -98,10 +121,28 @@ struct async_struct rs_table[] = {
{ BASE_BAUD, 0x2A8, &FourPort2_ISR, ASYNC_FOURPORT },
{ BASE_BAUD, 0x2B0, &FourPort2_ISR, ASYNC_FOURPORT },
{ BASE_BAUD, 0x2B8, &FourPort2_ISR, ASYNC_FOURPORT | ASYNC_NOSCRATCH },
-
+#else /* CONFIG_AST_FOURPORT */
+ { BASE_BAUD, 0x000 },
+ { BASE_BAUD, 0x000 },
+ { BASE_BAUD, 0x000 },
+ { BASE_BAUD, 0x000 },
+
+ { BASE_BAUD, 0x000 },
+ { BASE_BAUD, 0x000 },
+ { BASE_BAUD, 0x000 },
+ { BASE_BAUD, 0x000 },
+#endif /* CONFIG_AST_FOURPORT */
+
+#ifdef CONFIG_ACCENT_ASYNC
{ BASE_BAUD, 0x330, &Accent3_ISR, 0 },
{ BASE_BAUD, 0x338, &Accent4_ISR, 0 },
-#endif
+#else /* CONFIG_ACCENT_ASYNC */
+ { BASE_BAUD, 0x000 },
+ { BASE_BAUD, 0x000 },
+#endif /* CONFIG_ACCENT_ASYNC */
+ { BASE_BAUD, 0x000 },
+ { BASE_BAUD, 0x000 },
+
};
#define NR_PORTS (sizeof(rs_table)/sizeof(struct async_struct))
@@ -141,6 +182,7 @@ static inline void rs_sched_event(int line,
timer_active |= 1 << RS_TIMER;
}
+#ifdef NEW_INTERRUPT_ROUTINE
/*
* This ISR handles the COM1-4 8250, 16450, and 16550A UART's. It is
* also called by the FourPort ISR, since the FourPort also uses the
@@ -174,7 +216,7 @@ static void UART_ISR_proc(async_ISR ISR, int line)
do {
restart:
- status = inb(UART_LSR + info->port);
+ status = inb_p(UART_LSR + info->port);
if (status & UART_LSR_DR) {
queue = &info->tty->read_q;
head = queue->head;
@@ -214,7 +256,7 @@ static void UART_ISR_proc(async_ISR ISR, int line)
}
queue->buf[head++] = ch;
head &= TTY_BUF_SIZE-1;
- } while ((status = inb(UART_LSR + info->port)) &
+ } while ((status = inb_p(UART_LSR + info->port)) &
UART_LSR_DR);
queue->head = head;
if ((VLEFT < RQ_THRESHOLD_LW)
@@ -268,9 +310,7 @@ static void UART_ISR_proc(async_ISR ISR, int line)
* last. We have to skip the do/while test condition
* because the THRE interrupt has probably been lost.
*/
- if ((cflag & CRTSCTS) ||
- ((status & UART_MSR_DSR) &&
- !(cflag & CNORTSCTS))) {
+ if (cflag & CRTSCTS) {
if (info->tty->stopped) {
if (status & UART_MSR_CTS) {
info->tty->stopped = 0;
@@ -279,10 +319,131 @@ static void UART_ISR_proc(async_ISR ISR, int line)
} else
info->tty->stopped = !(status & UART_MSR_CTS);
}
- } while (!(inb(UART_IIR + info->port) & UART_IIR_NO_INT));
+ } while (!(inb_p(UART_IIR + info->port) & UART_IIR_NO_INT));
}
+#else /* NEW_INTERRUPT_ROUTINE */
+/*
+ * There are several races here: we avoid most of them by disabling
+ * timer_active for the crucial part of the process.. That's a good
+ * idea anyway.
+ *
+ * The problem is that we have to output characters /both/ from interrupts
+ * and from the normal write: the latter to be sure the interrupts start up
+ * again. With serial lines, the interrupts can happen so often that the
+ * races actually are noticeable.
+ */
+static void send_intr(struct async_struct * info)
+{
+ unsigned short port = info->port;
+ int line = info->line;
+ struct tty_queue * queue = &info->tty->write_q;
+ int c, count = 0;
+
+ if (info->tty->stopped)
+ return;
+
+ if (info->type == PORT_16550A)
+ count = 16;
+ else
+ count = 1;
+
+ rs_write_active &= ~(1 << line);
+
+ if (inb_p(UART_LSR + info->port) & UART_LSR_THRE) {
+ while (count-- && !info->tty->stopped) {
+ if (queue->tail == queue->head)
+ goto end_send;
+ c = queue->buf[queue->tail];
+ queue->tail++;
+ queue->tail &= TTY_BUF_SIZE-1;
+ outb(c, UART_TX + port);
+ }
+ }
+ info->timer = jiffies + info->timeout;
+ if (info->timer < timer_table[RS_TIMER].expires)
+ timer_table[RS_TIMER].expires = info->timer;
+ rs_write_active |= 1 << line;
+ timer_active |= 1 << RS_TIMER;
+end_send:
+ if (LEFT(queue) > WAKEUP_CHARS)
+ wake_up(&queue->proc_list);
+}
+
+static void receive_intr(struct async_struct * info)
+{
+ unsigned short port = info->port;
+ struct tty_queue * queue = &info->tty->read_q;
+ int head = queue->head;
+ int maxhead = (queue->tail-1) & (TTY_BUF_SIZE-1);
+ int count = 0;
+
+ do {
+ count++;
+ queue->buf[head] = inb(UART_TX + port);
+ if (head != maxhead) {
+ head++;
+ head &= TTY_BUF_SIZE-1;
+ }
+ } while (inb(UART_LSR + port) & UART_LSR_DR);
+ queue->head = head;
+ rs_sched_event(info->line, info, RS_EVENT_READ_PROCESS);
+}
+
+static void line_status_intr(struct async_struct * info)
+{
+ unsigned char status = inb(UART_LSR + info->port);
+
+/* printk("line status: %02x\n",status); */
+}
+
+static void modem_status_intr(struct async_struct * info)
+{
+ unsigned char status = inb(UART_MSR + info->port);
+
+ if (!(info->tty->termios->c_cflag & CLOCAL)) {
+ if (((status & (UART_MSR_DCD|UART_MSR_DDCD)) == UART_MSR_DDCD)
+ && info->tty->session > 0)
+ kill_sl(info->tty->session,SIGHUP,1);
+
+ if (info->tty->termios->c_cflag & CRTSCTS)
+ info->tty->stopped = !(status & UART_MSR_CTS);
+
+ if (!info->tty->stopped)
+ send_intr(info);
+ }
+}
+
+static void (*jmp_table[4])(struct async_struct *) = {
+ modem_status_intr,
+ send_intr,
+ receive_intr,
+ line_status_intr
+};
-#ifdef NONSTANDARD_PORTS
+/*
+ * This ISR handles the COM1-4 8250, 16450, and 16550A UART's. It is
+ * also called by the FourPort ISR, since the FourPort also uses the
+ * same National Semiconduct UART's, with some interrupt multiplexing
+ * thrown in.
+ */
+static void UART_ISR_proc(async_ISR ISR, int line)
+{
+ unsigned char ident;
+ struct async_struct * info = rs_table + line;
+
+ if (!info || !info->tty || !info->port)
+ return;
+ while (1) {
+ ident = inb(UART_IIR + info->port) & 7;
+ if (ident & 1)
+ return;
+ ident = ident >> 1;
+ jmp_table[ident](info);
+ }
+}
+#endif /* NEW_INTERRUPT_ROUTINE */
+
+#ifdef CONFIG_AST_FOURPORT
/*
* Here is the fourport ISR
*/
@@ -301,7 +462,7 @@ static void FourPort_ISR_proc(async_ISR ISR, int line)
ivec = ~inb(ISR->port) & 0x0F;
} while (ivec);
}
-#endif
+#endif /* CONFIG_AST_FOURPORT */
/*
* This is the serial driver's generic interrupt routine
@@ -316,16 +477,18 @@ static void rs_interrupt(int irq)
}
}
-#ifdef AUTO_IRQ
+#ifdef CONFIG_AUTO_IRQ
/*
* This is the serial driver's interrupt routine while we are probing
* for submarines.
*/
static volatile int rs_irq_triggered;
+static volatile int rs_triggered;
static void rs_probe(int irq)
{
rs_irq_triggered = irq;
+ rs_triggered |= 1 << irq;
return;
}
#endif
@@ -361,8 +524,8 @@ static void rs_timer(void)
wake_up_interruptible(&info->tty->write_q.proc_list);
}
if (!clear_bit(RS_EVENT_HUP_PGRP, &info->event)) {
- if (info->tty->pgrp > 0)
- kill_pg(info->tty->pgrp,SIGHUP,1);
+ if (info->tty->session > 0)
+ kill_sl(info->tty->session,SIGHUP,1);
}
if (!clear_bit(RS_EVENT_BREAK_INT, &info->event)) {
flush_input(info->tty);
@@ -423,7 +586,11 @@ void rs_write(struct tty_struct * tty)
info = rs_table + DEV_TO_SL(tty->line);
if (!test_bit(info->line, &rs_write_active)) {
cli();
+#ifdef NEW_INTERRUPT_ROUTINE
UART_ISR_proc(info->ISR, info->line);
+#else
+ send_intr(info);
+#endif
sti();
}
@@ -443,12 +610,10 @@ static void rs_throttle(struct tty_struct * tty, int status)
info = rs_table + DEV_TO_SL(tty->line);
if (tty->termios->c_iflag & IXOFF) {
info->x_char = STOP_CHAR(tty);
- } else if ((tty->termios->c_cflag & CRTSCTS) ||
- ((inb(UART_MSR + info->port) & UART_MSR_DSR) &&
- !(tty->termios->c_cflag & CNORTSCTS))) {
- mcr = inb(UART_MCR + info->port);
+ } else {
+ mcr = inb_p(UART_MCR + info->port);
mcr &= ~UART_MCR_RTS;
- outb_p(mcr, UART_MCR + info->port);
+ outb(mcr, UART_MCR + info->port);
}
break;
case TTY_THROTTLE_RQ_AVAIL:
@@ -460,9 +625,7 @@ static void rs_throttle(struct tty_struct * tty, int status)
else
info->x_char = START_CHAR(tty);
sti();
- } else if ((tty->termios->c_cflag & CRTSCTS) ||
- ((inb(UART_MSR + info->port) & UART_MSR_DSR) &&
- !(tty->termios->c_cflag & CNORTSCTS))) {
+ } else {
mcr = inb(UART_MCR + info->port);
mcr |= UART_MCR_RTS;
outb_p(mcr, UART_MCR + info->port);
@@ -486,6 +649,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
line = DEV_TO_SL(tty->line);
if ((line < 0) || (line >= NR_PORTS))
return;
+ tty->stopped = 0; /* Force flush to succeed */
wait_until_sent(tty);
info = rs_table + line;
if (!info->port)
@@ -681,6 +845,15 @@ static int set_serial_info(struct async_struct * info,
if (!new_info)
return -EFAULT;
memcpy_fromfs(&tmp,new_info,sizeof(tmp));
+
+ info->flags = tmp.flags & ASYNC_FLAGS;
+
+ if ( (tmp.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
+ info->custom_divisor = tmp.custom_divisor;
+
+ if ((tmp.type >= PORT_UNKNOWN) && (tmp.type <= PORT_MAX))
+ info->type = tmp.type;
+
new_port = tmp.port;
new_irq = tmp.irq;
if (new_irq > 15 || new_port > 0xffff)
@@ -890,9 +1063,37 @@ int rs_open(struct tty_struct *tty, struct file * filp)
return 0;
}
+static void show_serial_version()
+{
+ printk("Serial driver version 3.1 with");
+#ifdef CONFIG_AST_FOURPORT
+ printk(" AST_FOURPORT");
+#define SERIAL_OPT
+#endif
+#ifdef CONFIG_ACCENT_ASYNC
+ printk(" ACCENT_ASYNC");
+#define SERIAL_OPT
+#endif
+#ifdef CONFIG_AUTO_IRQ
+ printk (" AUTO_IRQ");
+#define SERIAL_OPT
+#endif
+#ifdef NEW_INTERRUPT_ROUTINE
+ printk(" NEW_INTERRUPT_ROUTINE");
+#define SERIAL_OPT
+#endif
+#ifdef SERIAL_OPT
+ printk(" enabled\n");
+#else
+ printk(" no serial options enabled\n");
+#endif
+#undef SERIAL_OPT
+}
+
+
static void init(struct async_struct * info)
{
-#ifdef AUTO_IRQ
+#ifdef CONFIG_AUTO_IRQ
unsigned char status1, status2, scratch, save_ICP=0;
unsigned short ICP=0, port = info->port;
unsigned long timeout;
@@ -941,7 +1142,7 @@ static void init(struct async_struct * info)
info->type = PORT_UNKNOWN;
return;
}
-#else /* AUTO_IRQ */
+#else /* CONFIG_AUTO_IRQ */
unsigned char status1, status2, scratch, scratch2;
unsigned short port = info->port;
@@ -959,7 +1160,7 @@ static void init(struct async_struct * info)
info->type = PORT_UNKNOWN;
return;
}
-#endif /* AUTO_IRQ */
+#endif /* CONFIG_AUTO_IRQ */
if (!(info->flags & ASYNC_NOSCRATCH)) {
scratch = inb(UART_SCR + port);
@@ -1000,14 +1201,17 @@ long rs_init(long kmem_start)
{
int i;
struct async_struct * info;
-#ifdef AUTO_IRQ
+#ifdef CONFIG_AUTO_IRQ
int irq_lines = 0;
struct sigaction sa;
+ unsigned long timeout;
+
/*
* We will be auto probing for irq's, so turn on interrupts now!
*/
sti();
+ rs_triggered = 0;
sa.sa_handler = rs_probe;
sa.sa_flags = (SA_INTERRUPT);
sa.sa_mask = 0;
@@ -1018,12 +1222,28 @@ long rs_init(long kmem_start)
for (i = 0; i < 16; i++) {
IRQ_ISR[i] = 0;
-#ifdef AUTO_IRQ
+#ifdef CONFIG_AUTO_IRQ
if (!irqaction(i, &sa))
irq_lines |= 1 << i;
#endif
}
+#ifdef CONFIG_AUTO_IRQ
+ timeout = jiffies+5;
+ while (timeout >= jiffies)
+ ;
+ for (i = 0; i < 16; i++) {
+ if ((rs_triggered & (1 << i)) &&
+ (irq_lines & (1 << i))) {
+ irq_lines &= ~(1 << i);
+ printk("Wild interrupt? (IRQ %d)\n", i);
+ free_irq(i);
+ }
+ }
+#endif
+ show_serial_version();
for (i = 0, info = rs_table; i < NR_PORTS; i++,info++) {
+ if (!info->port)
+ continue;
info->line = i;
info->tty = 0;
info->type = PORT_UNKNOWN;
@@ -1061,13 +1281,16 @@ long rs_init(long kmem_start)
break;
}
}
-#ifdef AUTO_IRQ
+#ifdef CONFIG_AUTO_IRQ
+ /*
+ * Turn interrupts back off, since they were off when we
+ * started this. See start_kernel() in init/main.c.
+ */
cli();
for (i = 0; i < 16; i++) {
if (irq_lines & (1 << i))
free_irq(i);
}
- sti();
#endif
return kmem_start;
}
diff --git a/kernel/chr_drv/sound/Makefile b/kernel/chr_drv/sound/Makefile
new file mode 100644
index 0000000..703254e
--- /dev/null
+++ b/kernel/chr_drv/sound/Makefile
@@ -0,0 +1,44 @@
+# Makefile for the Linux sound card driver
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now inherited from the
+# parent makes. (hopefully)
+#
+# Stolen from the kernel Makefiles, Craig Metz - cmetz@thor.tjhsst.edu
+#
+
+.c.s:
+ $(CC) $(CFLAGS) -S $<
+.s.o:
+ $(AS) -c -o $*.o $<
+.c.o:
+ $(CC) $(CFLAGS) $(SOUND_SUPPORT) -c $<
+
+OBJS = sound_stub.o
+
+all: sound.a
+
+sound.a: $(OBJS)
+ $(AR) rcs sound.a $(OBJS)
+ sync
+
+clean:
+ rm -f core *.o *.a *.BAK *.BA *.B
+ rm -f soundload sounddrv
+ for i in *.c;do rm -f `basename $$i .c`.s;done
+
+indent:
+ for n in *.c;do echo indent $$n;indent $$n;done
+
+dep:
+ $(CPP) -M $(SOUND_SUPPORT) *.c > .depend
+
+#
+# include a dependency file if one exists
+#
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
diff --git a/kernel/chr_drv/sound/sound_stub.c b/kernel/chr_drv/sound/sound_stub.c
new file mode 100644
index 0000000..33cc58d
--- /dev/null
+++ b/kernel/chr_drv/sound/sound_stub.c
@@ -0,0 +1,15 @@
+/*
+
+This file contains just a stub version of the Sound Driver.
+
+The real version is available at tsx-11.mit.edu
+(pub/linux/ALPHA/sound/snd-driv-0.x.tar.Z)
+
+Hannu Savolainen
+hsavolai@cs.helsinki.fi
+*/
+
+long soundcard_init(long mem_start)
+{
+ return mem_start;
+}
diff --git a/kernel/chr_drv/tty_io.c b/kernel/chr_drv/tty_io.c
index b468cba..2e7b4c3 100644
--- a/kernel/chr_drv/tty_io.c
+++ b/kernel/chr_drv/tty_io.c
@@ -54,7 +54,6 @@ struct tty_struct * redirect = NULL;
struct wait_queue * keypress_wait = NULL;
static int initialize_tty_struct(struct tty_struct *tty, int line);
-static void reset_tty_termios(int line);
void put_tty_queue(char c, struct tty_queue * queue)
{
@@ -277,8 +276,11 @@ static void __wait_for_canon_input(struct tty_struct *);
static void wait_for_canon_input(struct tty_struct * tty)
{
- if (!available_canon_input(tty))
+ if (!available_canon_input(tty)) {
+ if (current->signal & ~current->blocked)
+ return;
__wait_for_canon_input(tty);
+ }
}
static int read_chan(struct tty_struct * tty, struct file * file, char * buf, int nr)
@@ -409,6 +411,8 @@ static void __wait_for_canon_input(struct tty_struct * tty)
current->state = TASK_INTERRUPTIBLE;
if (available_canon_input(tty))
break;
+ if (current->signal & ~current->blocked)
+ break;
schedule();
}
current->state = TASK_RUNNING;
@@ -423,8 +427,6 @@ static int available_canon_input(struct tty_struct * tty)
TTY_WRITE_FLUSH(tty->link);
else
return 1;
- if (current->signal & ~current->blocked)
- return 1;
if (FULL(&tty->read_q))
return 1;
if (tty->secondary.data)
@@ -588,62 +590,65 @@ static int tty_open(struct inode * inode, struct file * filp)
* There be race-conditions here... Lots of them. Careful now.
*/
tty = o_tty = NULL;
- if (!tty_table[dev]) {
+ tty = tty_table[dev];
+ if (!tty) {
tty = (struct tty_struct *) get_free_page(GFP_KERNEL);
- if (tty) {
+ if (tty_table[dev]) {
+ /*
+ * Stop our allocation of tty if race
+ * condition detected.
+ */
+ if (tty)
+ free_page((unsigned long) tty);
+ tty = tty_table[dev];
+ } else {
+ if (!tty)
+ return -ENOMEM;
retval = initialize_tty_struct(tty, dev);
if (retval) {
- free_page((unsigned long)tty);
+ free_page((unsigned long) tty);
return retval;
}
+ tty_table[dev] = tty;
}
}
+ tty->count++; /* bump count to preserve tty */
if (IS_A_PTY(dev)) {
- if (!tty_table[PTY_OTHER(dev)]) {
+ o_tty = tty_table[PTY_OTHER(dev)];
+ if (!o_tty) {
o_tty = (struct tty_struct *) get_free_page(GFP_KERNEL);
- if (o_tty) {
+ if (tty_table[PTY_OTHER(dev)]) {
+ /*
+ * Stop our allocation of o_tty if race
+ * condition detected.
+ */
+ free_page((unsigned long) o_tty);
+ o_tty = tty_table[PTY_OTHER(dev)];
+ } else {
+ if (!o_tty) {
+ tty->count--;
+ return -ENOMEM;
+ }
retval = initialize_tty_struct(o_tty, PTY_OTHER(dev));
if (retval) {
- free_page((unsigned long) tty);
+ tty->count--;
free_page((unsigned long) o_tty);
return retval;
}
+ tty_table[PTY_OTHER(dev)] = o_tty;
}
}
- if (!o_tty && !tty_table[PTY_OTHER(dev)]) {
- free_page((unsigned long) tty);
- return -ENOMEM;
- }
- }
- if (tty_table[dev]) {
- free_page((unsigned long) tty);
- tty = tty_table[dev];
- } else if (tty)
- tty_table[dev] = tty;
- else {
- free_page((unsigned long) o_tty);
- return -ENOMEM;
- }
- if (IS_A_PTY(dev)) {
- if (tty_table[PTY_OTHER(dev)]) {
- free_page((unsigned long) o_tty);
- o_tty = tty_table[PTY_OTHER(dev)];
- } else
- tty_table[PTY_OTHER(dev)] = o_tty;
- tty->link = o_tty;
+ tty->link = o_tty;
o_tty->link = tty;
}
if (IS_A_PTY_MASTER(dev)) {
- if (tty->count)
+ if (tty->count > 1) {
+ tty->count--;
return -EAGAIN;
- if (tty->link && tty->link->count++ == 0)
- reset_tty_termios(PTY_OTHER(dev));
- reset_tty_termios(dev);
- } else if (IS_A_PTY_SLAVE(dev)) {
- if (tty->count == 0)
- reset_tty_termios(dev);
- }
- tty->count++;
+ }
+ if (tty->link)
+ tty->link->count++;
+ }
retval = 0;
/* clean up the packet stuff. */
@@ -680,6 +685,8 @@ static void tty_release(struct inode * inode, struct file * filp)
{
int dev;
struct tty_struct * tty;
+ unsigned long free_tty_struct;
+ struct termios *free_termios;
dev = filp->f_rdev;
if (MAJOR(dev) != 4) {
@@ -717,11 +724,37 @@ static void tty_release(struct inode * inode, struct file * filp)
if (tty->link) {
if (tty->link->count)
return;
- free_page((unsigned long) tty_table[PTY_OTHER(dev)]);
+ /*
+ * Free the tty structure, being careful to avoid race conditions
+ */
+ free_tty_struct = (unsigned long) tty_table[PTY_OTHER(dev)];
tty_table[PTY_OTHER(dev)] = 0;
+ free_page(free_tty_struct);
+ /*
+ * If this is a PTY, free the termios structure, being
+ * careful to avoid race conditions
+ */
+ if (IS_A_PTY(dev)) {
+ free_termios = tty_termios[PTY_OTHER(dev)];
+ tty_termios[PTY_OTHER(dev)] = 0;
+ kfree_s(free_termios, sizeof(struct termios));
+ }
+ }
+ /*
+ * Free the tty structure, being careful to avoid race conditions
+ */
+ free_tty_struct = (unsigned long) tty_table[dev];
+ tty_table[dev] = 0;
+ free_page(free_tty_struct);
+ /*
+ * If this is a PTY, free the termios structure, being careful
+ * to avoid race conditions
+ */
+ if (IS_A_PTY(dev)) {
+ free_termios = tty_termios[dev];
+ tty_termios[dev] = 0;
+ kfree_s(free_termios, sizeof(struct termios));
}
- free_page((unsigned long) tty_table[dev]);
- tty_table[dev] = 0;
}
static int tty_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
@@ -742,7 +775,10 @@ static int tty_select(struct inode * inode, struct file * filp, int sel_type, se
}
switch (sel_type) {
case SEL_IN:
- if (!EMPTY(&tty->secondary))
+ if (L_CANON(tty)) {
+ if (available_canon_input(tty))
+ return 1;
+ } else if (!EMPTY(&tty->secondary))
return 1;
if (tty->link && !tty->link->count)
return 1;
@@ -750,7 +786,7 @@ static int tty_select(struct inode * inode, struct file * filp, int sel_type, se
/* see if the status byte can be read. */
if (tty->packet && tty->link &&
tty->link->status_changed)
- return 1;
+ return 1;
select_wait(&tty->secondary.proc_list, wait);
return 0;
@@ -826,16 +862,39 @@ void do_SAK( struct tty_struct *tty)
*/
static int initialize_tty_struct(struct tty_struct *tty, int line)
{
+ struct termios *tp = tty_termios[line];
+
memset(tty, 0, sizeof(struct tty_struct));
tty->line = line;
tty->pgrp = -1;
tty->winsize.ws_row = 24;
tty->winsize.ws_col = 80;
if (!tty_termios[line]) {
- tty_termios[line] = kmalloc(sizeof(struct termios), GFP_KERNEL);
- if (!tty_termios[line])
- return -ENOMEM;
- reset_tty_termios(line);
+ tp = kmalloc(sizeof(struct termios), GFP_KERNEL);
+ if (!tty_termios[line]) {
+ if (!tp)
+ return -ENOMEM;
+ memset(tp, 0, sizeof(struct termios));
+ memcpy(tp->c_cc, INIT_C_CC, NCCS);
+ if (IS_A_CONSOLE(line)) {
+ tp->c_iflag = ICRNL | IXON;
+ tp->c_oflag = OPOST | ONLCR;
+ tp->c_cflag = B38400 | CS8 | CREAD;
+ tp->c_lflag = ISIG | ICANON | ECHO |
+ ECHOCTL | ECHOKE;
+ } else if (IS_A_SERIAL(line)) {
+ tp->c_cflag = B2400 | CS8 | CREAD | HUPCL;
+ } else if (IS_A_PTY_MASTER(line)) {
+ tp->c_cflag = B9600 | CS8 | CREAD;
+ } else if (IS_A_PTY_SLAVE(line)) {
+ tp->c_iflag = ICRNL | IXON;
+ tp->c_oflag = OPOST | ONLCR;
+ tp->c_cflag = B38400 | CS8 | CREAD;
+ tp->c_lflag = ISIG | ICANON | ECHO |
+ ECHOCTL | ECHOKE;
+ }
+ tty_termios[line] = tp;
+ }
}
tty->termios = tty_termios[line];
@@ -851,33 +910,6 @@ static int initialize_tty_struct(struct tty_struct *tty, int line)
return 0;
}
-static void reset_tty_termios(int line)
-{
- struct termios *tp = tty_termios[line];
-
- if (!tp) {
- printk("termios of line was NULL\n");
- return;
- }
- memset(tp, 0, sizeof(struct termios));
- memcpy(tp->c_cc, INIT_C_CC, NCCS);
- if (IS_A_CONSOLE(line)) {
- tp->c_iflag = ICRNL | IXON;
- tp->c_oflag = OPOST | ONLCR;
- tp->c_cflag = B38400 | CS8 | CREAD;
- tp->c_lflag = ISIG | ICANON | ECHO | ECHOCTL | ECHOKE;
- } else if (IS_A_SERIAL(line)) {
- tp->c_cflag = B2400 | CS8 | CREAD | HUPCL;
- } else if (IS_A_PTY_MASTER(line)) {
- tp->c_cflag = B9600 | CS8 | CREAD;
- } else if (IS_A_PTY_SLAVE(line)) {
- tp->c_iflag = ICRNL | IXON;
- tp->c_oflag = OPOST | ONLCR;
- tp->c_cflag = B38400 | CS8 | CREAD;
- tp->c_lflag = ISIG | ICANON | ECHO | ECHOCTL | ECHOKE;
- }
-}
-
long tty_init(long kmem_start)
{
int i;
diff --git a/kernel/exit.c b/kernel/exit.c
index 5df7516..2088f0c 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -188,6 +188,10 @@ int session_of_pgrp(int pgrp)
return fallback;
}
+/*
+ * kill_pg() sends a signal to a process group: this is what the tty
+ * control characters do (^C, ^Z etc)
+ */
int kill_pg(int pgrp, int sig, int priv)
{
struct task_struct **p;
@@ -206,6 +210,29 @@ int kill_pg(int pgrp, int sig, int priv)
return(found ? 0 : retval);
}
+/*
+ * kill_sl() sends a signal to the session leader: this is used
+ * to send SIGHUP to the controlling process of a terminal when
+ * the connection is lost.
+ */
+int kill_sl(int sess, int sig, int priv)
+{
+ struct task_struct **p;
+ int err,retval = -ESRCH;
+ int found = 0;
+
+ if (sig<0 || sig>32 || sess<=0)
+ return -EINVAL;
+ for (p = &LAST_TASK ; p > &FIRST_TASK ; --p)
+ if (*p && (*p)->session == sess && (*p)->leader) {
+ if ((err = send_sig(sig,*p,priv)) != 0)
+ retval = err;
+ else
+ found++;
+ }
+ return(found ? 0 : retval);
+}
+
int kill_proc(int pid, int sig, int priv)
{
struct task_struct **p;
diff --git a/kernel/irq.c b/kernel/irq.c
index a287bf1..55ec8c7 100644
--- a/kernel/irq.c
+++ b/kernel/irq.c
@@ -26,13 +26,72 @@
#include <linux/errno.h>
#include <linux/signal.h>
#include <linux/sched.h>
+#include <linux/interrupt.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/irq.h>
+
void irq13(void);
+static unsigned long intr_count=0;
+
+/* I'll use an array for speed. and bitmap for speed. */
+int bh_active=0;
+struct bh_struct bh_base[32];
+
+/* interrupts should be on at the interrupt priority controller level. */
+/* returns with interrupts off at the processor level. */
+
+void do_bottom_half(void)
+{
+ struct bh_struct *bh;
+ int mask;
+ int count;
+ static int in_bh = 0;
+
+ cli();
+ if (intr_count > 1) {
+ intr_count--;
+ return;
+ }
+ /* don't just decrement it in case it is already 0 */
+
+ intr_count = 0;
+
+ /* any sort of real time test should go here. */
+ if (in_bh != 0) {
+ return;
+ }
+
+ in_bh = 1;
+ do {
+ count = 0;
+ for (mask = 1, bh = bh_base; mask ; bh++, mask = mask << 1) {
+ if (mask > bh_active)
+ break;
+ if (!(mask & bh_active))
+ continue;
+
+ count++;
+ bh_active &= ~mask;
+
+ /* turn the interrupts back on. */
+ sti();
+
+ if (bh->routine != NULL)
+ bh->routine(bh->data);
+ else
+ printk ("irq.c:bad bottom half entry.\n");
+
+ /* and back off. */
+ cli();
+ }
+ } while (count > 0);
+ in_bh = 0;
+}
+
/*
* This builds up the IRQ handler stubs using some ugly macros in irq.h
*
@@ -119,7 +178,7 @@ static struct sigaction irq_sigaction[16] = {
* IRQ's should use this format: notably the keyboard/timer
* routines.
*/
-int do_IRQ(int irq, struct pt_regs * regs)
+void do_IRQ(int irq, struct pt_regs * regs)
{
struct sigaction * sa = irq + irq_sigaction;
@@ -131,7 +190,7 @@ int do_IRQ(int irq, struct pt_regs * regs)
* stuff - the handler is also running with interrupts disabled unless
* it explicitly enables them later.
*/
-int do_fast_IRQ(int irq)
+void do_fast_IRQ(int irq)
{
struct sigaction * sa = irq + irq_sigaction;
@@ -233,4 +292,13 @@ void init_IRQ(void)
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");
+
+ /* intialize the bottom half routines. */
+ for (i = 0; i < 32; i++)
+ {
+ bh_base[i].routine = NULL;
+ bh_base[i].data = NULL;
+ }
+ bh_active = 0;
+
}
diff --git a/kernel/sched.c b/kernel/sched.c
index b648da0..69e3543 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -13,6 +13,7 @@
#define TIMER_IRQ 0
+#include <linux/config.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/timer.h>
@@ -407,10 +408,10 @@ static void do_timer(struct pt_regs * regs)
}
} else {
current->stime++;
-#ifdef PROFILE_SHIFT
+#ifdef CONFIG_PROFILE
if (prof_buffer && current != task[0]) {
unsigned long eip = regs->eip;
- eip >>= PROFILE_SHIFT;
+ eip >>= 2;
if (eip < prof_len)
prof_buffer[eip]++;
}
@@ -566,8 +567,8 @@ void sched_init(void)
}
/* Clear NT, so that we won't have troubles with that later on */
__asm__("pushfl ; andl $0xffffbfff,(%esp) ; popfl");
- ltr(0);
- lldt(0);
+ load_TR(0);
+ load_ldt(0);
outb_p(0x36,0x43); /* binary, mode 3, LSB/MSB, ch 0 */
outb_p(LATCH & 0xff , 0x40); /* LSB */
outb(LATCH >> 8 , 0x40); /* MSB */
diff --git a/kernel/traps.c b/kernel/traps.c
index 169851d..9b546e5 100644
--- a/kernel/traps.c
+++ b/kernel/traps.c
@@ -69,7 +69,7 @@ void alignment_check(void);
printk("EIP: %04x:%p\nEFLAGS: %p\n", 0xffff & esp[1],esp[0],esp[2]);
printk("fs: %04x\n",_fs());
printk("base: %p, limit: %p\n",get_base(current->ldt[1]),get_limit(0x17));
- str(i);
+ store_TR(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])));
diff --git a/lib/Makefile b/lib/Makefile
index 693db67..af32e9a 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -21,30 +21,15 @@ lib.a: $(OBJS)
sync
clean:
- rm -f core *.o *.a tmp_make
- for i in *.c;do rm -f `basename $$i .c`.s;done
+ rm -f core *.o *.a *.s
dep:
- sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
- $(CPP) -M *.c >> tmp_make
- cp tmp_make Makefile
+ $(CPP) -M *.c > .depend
+
+#
+# include a dependency file if one exists
+#
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
-### Dependencies:
-_exit.o : _exit.c /usr/include/linux/unistd.h
-close.o : close.c /usr/include/linux/unistd.h
-ctype.o : ctype.c /usr/include/linux/ctype.h
-dup.o : dup.c /usr/include/linux/unistd.h
-errno.o : errno.c
-execve.o : execve.c /usr/include/linux/unistd.h
-malloc.o : malloc.c /usr/include/linux/kernel.h /usr/include/linux/mm.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/string.h \
- /usr/include/asm/system.h
-open.o : open.c /usr/include/linux/unistd.h /usr/lib/gcc-lib/i386-linux/2.3.2/include/stdarg.h
-setsid.o : setsid.c /usr/include/linux/types.h /usr/include/linux/unistd.h
-string.o : string.c /usr/include/linux/types.h /usr/include/linux/string.h
-wait.o : wait.c /usr/include/linux/unistd.h /usr/include/linux/types.h
-write.o : write.c /usr/include/linux/unistd.h /usr/include/linux/types.h
diff --git a/mm/Makefile b/mm/Makefile
index 097aa59..ed3c2e3 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -20,43 +20,14 @@ mm.o: $(OBJS)
$(LD) -r -o mm.o $(OBJS)
clean:
- rm -f core *.o *.a tmp_make
- for i in *.c;do rm -f `basename $$i .c`.s;done
+ rm -f core *.o *.a *.s
dep:
- sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
- $(CPP) -M *.c >> tmp_make
- cp tmp_make Makefile
+ $(CPP) -M *.c > .depend
-### Dependencies:
-memory.o : memory.c /usr/include/asm/system.h /usr/include/linux/signal.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
- /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/errno.h \
- /usr/include/linux/string.h
-mmap.o : mmap.c /usr/include/linux/stat.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/errno.h \
- /usr/include/linux/mman.h /usr/include/linux/string.h /usr/include/asm/segment.h \
- /usr/include/asm/system.h
-swap.o : swap.c /usr/include/linux/mm.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
- /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/kernel.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/errno.h /usr/include/linux/string.h \
- /usr/include/linux/stat.h /usr/include/asm/system.h
+#
+# include a dependency file if one exists
+#
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
diff --git a/net/Makefile b/net/Makefile
index 4247e95..b59d8d8 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -10,11 +10,14 @@
# only these two lines should need to be changed to remove inet sockets.
# (and the tcp/tcpip.o in net.o)
-SUBDIRS = tcp
-SOCK_FLAGS = -DINET_SOCKETS
+SUBDIRS = tcp
+
+ifdef CONFIG_TCPIP
+NET_SUBDIRS = tcp
+endif
.c.o:
- $(CC) $(CFLAGS) $(SOCK_FLAGS) -c $<
+ $(CC) $(CFLAGS) -c $<
.s.o:
$(AS) -o $*.o $<
.c.s:
@@ -27,42 +30,24 @@ net.o: $(OBJS) subdirs
subdirs: dummy
- for i in $(SUBDIRS); do (cd $$i && echo $$i && $(MAKE)) || exit; done
+ for i in $(NET_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
+ rm -f core *.o *.a *.s
@for i in $(SUBDIRS); do (cd $$i && echo $$i && $(MAKE) clean) || exit; done
dep:
- sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
- $(CPP) -M *.c >> tmp_make
- cp tmp_make Makefile
+ $(CPP) -M *.c > .depend
@for i in $(SUBDIRS); do (cd $$i && echo $$i && $(MAKE) dep) || exit; done
+socket.o: Makefile
+
dummy:
-### Dependencies:
-socket.o : socket.c /usr/include/linux/signal.h /usr/include/linux/errno.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/types.h /usr/include/linux/dirent.h \
- /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/kernel.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/stat.h \
- /usr/include/linux/socket.h /usr/include/linux/fcntl.h /usr/include/linux/termios.h \
- /usr/include/asm/system.h /usr/include/asm/segment.h kern_sock.h socketcall.h
-unix.o : unix.c /usr/include/linux/signal.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/kernel.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/errno.h /usr/include/linux/string.h \
- /usr/include/linux/stat.h /usr/include/linux/socket.h /usr/include/linux/un.h \
- /usr/include/linux/fcntl.h /usr/include/linux/termios.h /usr/include/asm/system.h \
- /usr/include/asm/segment.h kern_sock.h
+#
+# include a dependency file if one exists
+#
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
+
diff --git a/net/socket.c b/net/socket.c
index e8c3ab6..f59b6d1 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -7,6 +7,7 @@
#include <linux/socket.h>
#include <linux/fcntl.h>
#include <linux/termios.h>
+#include <linux/config.h>
#include <asm/system.h>
#include <asm/segment.h>
@@ -17,7 +18,7 @@
extern int sys_close(int fd);
extern struct proto_ops unix_proto_ops;
-#ifdef INET_SOCKETS
+#ifdef CONFIG_TCPIP
extern struct proto_ops inet_proto_ops;
#endif
@@ -27,7 +28,7 @@ static struct {
struct proto_ops *ops;
} proto_table[] = {
{AF_UNIX, "AF_UNIX", &unix_proto_ops},
-#ifdef INET_SOCKETS
+#ifdef CONFIG_TCPIP
{AF_INET, "AF_INET", &inet_proto_ops},
#endif
};
@@ -616,9 +617,20 @@ sock_connect(int fd, struct sockaddr *uservaddr, int addrlen)
PRINTK("sys_connect: fd = %d\n", fd);
if (!(sock = sockfd_lookup(fd, &file)))
return -EBADF;
- if (sock->state != SS_UNCONNECTED) {
- PRINTK("sys_connect: socket not unconnected\n");
- return -EINVAL;
+ switch (sock->state) {
+ case SS_UNCONNECTED:
+ /* This is ok... continue with connect */
+ break;
+ case SS_CONNECTED:
+ /* Socket is already connected */
+ return -EISCONN;
+ case SS_CONNECTING:
+ /* Not yet connected... */
+ /* we will check this. */
+ return (sock->ops->connect(sock, uservaddr, addrlen, file->f_flags));
+ default:
+ PRINTK("sys_connect: socket not unconnected\n");
+ return -EINVAL;
}
i = sock->ops->connect(sock, uservaddr, addrlen, file->f_flags);
if (i < 0) {
diff --git a/net/tcp/Makefile b/net/tcp/Makefile
index 6fbd5a7..b7695a3 100644
--- a/net/tcp/Makefile
+++ b/net/tcp/Makefile
@@ -27,201 +27,17 @@ subdirs: dummy
clean:
- rm -f core *.o *.a tmp_make
- for i in *.c;do rm -f `basename $$i .c`.s;done
+ rm -f core *.o *.a *.s
dep:
- sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
- $(CPP) -M *.c >> tmp_make
- cp tmp_make Makefile
+ $(CPP) -M *.c > .depend
tar:
tar -cvf /dev/f1 .
-### Dependencies:
-Space.o : Space.c dev.h /usr/include/linux/stddef.h
-arp.o : arp.c /usr/include/linux/types.h /usr/include/linux/string.h /usr/include/linux/kernel.h \
- /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/dirent.h \
- /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h \
- /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h \
- /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h \
- /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h /usr/include/linux/signal.h \
- /usr/include/linux/time.h /usr/include/linux/param.h /usr/include/linux/resource.h \
- /usr/include/linux/vm86.h /usr/include/linux/math_emu.h /usr/include/linux/socket.h \
- /usr/include/netinet/in.h /usr/include/features.h /usr/include/sys/cdefs.h /usr/include/sys/socket.h \
- /usr/include/asm/system.h timer.h ip.h dev.h /usr/include/linux/sock_ioctl.h \
- eth.h tcp.h sock.h arp.h
-dev.o : dev.c /usr/include/asm/segment.h /usr/include/asm/system.h /usr/include/linux/types.h \
- /usr/include/linux/kernel.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
- /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
- /usr/include/linux/string.h /usr/include/linux/socket.h /usr/include/netinet/in.h \
- /usr/include/features.h /usr/include/sys/cdefs.h /usr/include/sys/socket.h dev.h \
- eth.h timer.h ip.h /usr/include/linux/sock_ioctl.h tcp.h sock.h /usr/include/linux/errno.h \
- arp.h
-eth.o : eth.c /usr/include/asm/segment.h /usr/include/asm/system.h /usr/include/linux/types.h \
- /usr/include/linux/kernel.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
- /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
- /usr/include/linux/string.h /usr/include/linux/socket.h /usr/include/netinet/in.h \
- /usr/include/features.h /usr/include/sys/cdefs.h /usr/include/sys/socket.h dev.h \
- eth.h timer.h ip.h /usr/include/linux/sock_ioctl.h tcp.h sock.h /usr/include/linux/errno.h \
- arp.h
-icmp.o : icmp.c /usr/include/linux/types.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/fcntl.h /usr/include/linux/socket.h \
- /usr/include/netinet/in.h /usr/include/features.h /usr/include/sys/cdefs.h /usr/include/sys/socket.h \
- timer.h ip.h dev.h /usr/include/linux/sock_ioctl.h eth.h tcp.h sock.h /usr/include/linux/errno.h \
- /usr/include/linux/timer.h /usr/include/asm/system.h /usr/include/asm/segment.h \
- icmp.h
-ip.o : ip.c /usr/include/asm/segment.h /usr/include/asm/system.h /usr/include/linux/types.h \
- /usr/include/linux/kernel.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
- /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
- /usr/include/linux/string.h /usr/include/linux/socket.h /usr/include/netinet/in.h \
- /usr/include/features.h /usr/include/sys/cdefs.h /usr/include/sys/socket.h timer.h \
- ip.h dev.h /usr/include/linux/sock_ioctl.h eth.h tcp.h sock.h /usr/include/linux/errno.h \
- arp.h icmp.h
-loopback.o : loopback.c /usr/include/linux/config.h /usr/include/linux/config.dist.h \
- /usr/include/linux/kernel.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/types.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/tty.h /usr/include/linux/termios.h \
- /usr/include/asm/system.h /usr/include/linux/ptrace.h /usr/include/linux/string.h \
- /usr/include/asm/segment.h /usr/include/asm/io.h /usr/include/errno.h /usr/include/features.h \
- /usr/include/sys/cdefs.h /usr/include/linux/errno.h /usr/include/linux/fcntl.h \
- /usr/include/netinet/in.h /usr/include/sys/socket.h /usr/include/linux/socket.h \
- dev.h eth.h timer.h ip.h /usr/include/linux/sock_ioctl.h tcp.h sock.h arp.h
-pack_type.o : pack_type.c /usr/include/linux/stddef.h dev.h eth.h
-packet.o : packet.c /usr/include/linux/types.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/fcntl.h /usr/include/linux/socket.h \
- /usr/include/netinet/in.h /usr/include/features.h /usr/include/sys/cdefs.h /usr/include/sys/socket.h \
- timer.h ip.h dev.h /usr/include/linux/sock_ioctl.h eth.h tcp.h sock.h /usr/include/linux/errno.h \
- /usr/include/linux/timer.h /usr/include/asm/system.h /usr/include/asm/segment.h \
- ../kern_sock.h
-protocols.o : protocols.c /usr/include/asm/segment.h /usr/include/asm/system.h \
- /usr/include/linux/types.h /usr/include/linux/kernel.h /usr/include/linux/sched.h \
- /usr/include/linux/head.h /usr/include/linux/fs.h /usr/include/linux/limits.h \
- /usr/include/linux/wait.h /usr/include/linux/dirent.h /usr/include/linux/vfs.h \
- /usr/include/linux/pipe_fs_i.h /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h \
- /usr/include/linux/msdos_fs_i.h /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h \
- /usr/include/linux/ext_fs_sb.h /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h \
- /usr/include/linux/mm.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/string.h /usr/include/linux/socket.h \
- /usr/include/netinet/in.h /usr/include/features.h /usr/include/sys/cdefs.h /usr/include/sys/socket.h \
- timer.h ip.h dev.h /usr/include/linux/sock_ioctl.h eth.h tcp.h sock.h icmp.h
-raw.o : raw.c /usr/include/linux/types.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/fcntl.h /usr/include/linux/socket.h \
- /usr/include/netinet/in.h /usr/include/features.h /usr/include/sys/cdefs.h /usr/include/sys/socket.h \
- timer.h ip.h dev.h /usr/include/linux/sock_ioctl.h eth.h tcp.h sock.h /usr/include/linux/errno.h \
- /usr/include/linux/timer.h /usr/include/asm/system.h /usr/include/asm/segment.h \
- ../kern_sock.h
-sock.o : sock.c /usr/include/linux/errno.h /usr/include/linux/types.h /usr/include/linux/socket.h \
- /usr/include/netinet/in.h /usr/include/features.h /usr/include/sys/cdefs.h /usr/include/sys/socket.h \
- /usr/include/linux/kernel.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
- /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
- /usr/include/linux/timer.h /usr/include/linux/string.h /usr/include/linux/sock_ioctl.h \
- ../kern_sock.h timer.h ip.h dev.h eth.h tcp.h udp.h sock.h /usr/include/asm/segment.h \
- /usr/include/asm/system.h /usr/include/linux/fcntl.h
-tcp.o : tcp.c /usr/include/linux/types.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/string.h /usr/include/linux/socket.h \
- /usr/include/netinet/in.h /usr/include/features.h /usr/include/sys/cdefs.h /usr/include/sys/socket.h \
- /usr/include/linux/fcntl.h timer.h ip.h dev.h /usr/include/linux/sock_ioctl.h \
- eth.h icmp.h tcp.h sock.h /usr/include/linux/errno.h /usr/include/linux/timer.h \
- /usr/include/asm/system.h /usr/include/asm/segment.h /usr/include/linux/termios.h \
- ../kern_sock.h
-timer.o : timer.c /usr/include/linux/types.h /usr/include/linux/errno.h /usr/include/linux/socket.h \
- /usr/include/netinet/in.h /usr/include/features.h /usr/include/sys/cdefs.h /usr/include/sys/socket.h \
- /usr/include/linux/kernel.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
- /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
- /usr/include/linux/timer.h /usr/include/asm/system.h timer.h ip.h dev.h /usr/include/linux/sock_ioctl.h \
- eth.h tcp.h sock.h arp.h ../kern_sock.h
-udp.o : udp.c /usr/include/linux/types.h /usr/include/linux/sched.h /usr/include/linux/head.h \
- /usr/include/linux/fs.h /usr/include/linux/limits.h /usr/include/linux/wait.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/kernel.h /usr/include/linux/signal.h /usr/include/linux/time.h \
- /usr/include/linux/param.h /usr/include/linux/resource.h /usr/include/linux/vm86.h \
- /usr/include/linux/math_emu.h /usr/include/linux/fcntl.h /usr/include/linux/socket.h \
- /usr/include/netinet/in.h /usr/include/features.h /usr/include/sys/cdefs.h /usr/include/sys/socket.h \
- timer.h ip.h dev.h /usr/include/linux/sock_ioctl.h eth.h tcp.h sock.h /usr/include/linux/errno.h \
- /usr/include/linux/timer.h /usr/include/linux/termios.h /usr/include/asm/system.h \
- /usr/include/asm/segment.h ../kern_sock.h udp.h icmp.h
-we.o : we.c /usr/include/linux/config.h /usr/include/linux/config.dist.h /usr/include/linux/kernel.h \
- /usr/include/linux/sched.h /usr/include/linux/head.h /usr/include/linux/fs.h \
- /usr/include/linux/limits.h /usr/include/linux/wait.h /usr/include/linux/types.h \
- /usr/include/linux/dirent.h /usr/include/linux/vfs.h /usr/include/linux/pipe_fs_i.h \
- /usr/include/linux/minix_fs_i.h /usr/include/linux/ext_fs_i.h /usr/include/linux/msdos_fs_i.h \
- /usr/include/linux/iso_fs_i.h /usr/include/linux/minix_fs_sb.h /usr/include/linux/ext_fs_sb.h \
- /usr/include/linux/msdos_fs_sb.h /usr/include/linux/iso_fs_sb.h /usr/include/linux/mm.h \
- /usr/include/linux/signal.h /usr/include/linux/time.h /usr/include/linux/param.h \
- /usr/include/linux/resource.h /usr/include/linux/vm86.h /usr/include/linux/math_emu.h \
- /usr/include/linux/tty.h /usr/include/linux/termios.h /usr/include/asm/system.h \
- /usr/include/linux/ptrace.h /usr/include/linux/string.h /usr/include/asm/segment.h \
- /usr/include/asm/io.h /usr/include/errno.h /usr/include/features.h /usr/include/sys/cdefs.h \
- /usr/include/linux/errno.h /usr/include/linux/fcntl.h /usr/include/netinet/in.h \
- /usr/include/sys/socket.h /usr/include/linux/socket.h dev.h eth.h timer.h ip.h \
- /usr/include/linux/sock_ioctl.h tcp.h sock.h arp.h wereg.h
+#
+# include a dependency file if one exists
+#
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
diff --git a/net/tcp/Space.c b/net/tcp/Space.c
index b6684ed..f859ef6 100644
--- a/net/tcp/Space.c
+++ b/net/tcp/Space.c
@@ -1,8 +1,14 @@
/* Space.c */
/* Holds initial configuration information for devices. */
-/* $Id: Space.c,v 0.8.4.3 1992/11/15 14:55:30 bir7 Exp $ */
+/* $Id: Space.c,v 0.8.4.5 1992/12/12 19:25:04 bir7 Exp $ */
/* $Log: Space.c,v $
+ * Revision 0.8.4.5 1992/12/12 19:25:04 bir7
+ * Cleaned up Log messages.
+ *
+ * Revision 0.8.4.4 1992/12/05 21:35:53 bir7
+ * Updated dev->init type.
+ *
* Revision 0.8.4.3 1992/11/15 14:55:30 bir7
* Removed ctrl-h so diff no longer thinks it's a binary file.
*
@@ -13,15 +19,15 @@
* version change only.
*
* Revision 0.8.3.2 1992/11/10 00:14:47 bir7
- * Changed malloc to kmalloc and added Id
+ * Changed malloc to kmalloc and added Id and Log
*
*/
#include "dev.h"
#include <linux/stddef.h>
-
-extern void wd8003_init(struct device *);
+extern int wd8003_init(struct device *);
+extern int loopback_init(struct device *dev);
static struct device wd8003_dev =
{
@@ -57,8 +63,6 @@ static struct device wd8003_dev =
0 /* addr len */
};
-extern void loopback_init(struct device *dev);
-
static struct device loopback_dev =
{
"loopback",
diff --git a/net/tcp/arp.c b/net/tcp/arp.c
index c9f33fa..7ca4205 100644
--- a/net/tcp/arp.c
+++ b/net/tcp/arp.c
@@ -19,8 +19,14 @@
The Author may be reached as bir7@leland.stanford.edu or
C/O Department of Mathematics; Stanford University; Stanford, CA 94305
*/
-/* $Id: arp.c,v 0.8.4.3 1992/11/15 14:55:30 bir7 Exp $ */
+/* $Id: arp.c,v 0.8.4.5 1992/12/12 19:25:04 bir7 Exp $ */
/* $Log: arp.c,v $
+ * Revision 0.8.4.5 1992/12/12 19:25:04 bir7
+ * Cleaned up Log messages.
+ *
+ * Revision 0.8.4.4 1992/12/03 19:52:20 bir7
+ * Added paranoid queue checking.
+ *
* Revision 0.8.4.3 1992/11/15 14:55:30 bir7
* Put more cli/sti pairs in send_q and another sanity check
* in arp_queue.
@@ -40,6 +46,7 @@
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/sched.h>
+#include <linux/config.h>
#include <linux/socket.h>
#include <netinet/in.h>
@@ -66,14 +73,42 @@ static void
send_arp_q(void)
{
struct sk_buff *skb;
+ struct sk_buff *skb2;
+
cli();
if (arp_q == NULL) return;
skb = arp_q;
do {
+ if (skb->magic != ARP_QUEUE_MAGIC)
+ {
+ printk ("arp.c skb with bad magic - %X: squashing queue\n");
+ cli();
+ arp_q = NULL;
+ sti();
+ return;
+ }
+ /* extra consistancy check. */
+ if (skb->next == NULL
+#ifdef CONFIG_MAX_16M
+ || (unsigned long)(skb->next) > 16*1024*1024
+#endif
+ )
+
+ {
+ printk ("dev.c: *** bug bad skb->next, squashing queue \n");
+ cli();
+ arp_q = NULL;
+ sti();
+ return;
+ }
+
+ skb->magic = 0;
+ skb2=skb->next;
+
sti();
- if (!skb->dev->rebuild_header (skb+1, skb->dev))
- {
+ if (!skb->dev->rebuild_header (skb+1, skb->dev))
+ {
cli();
if (skb->next == skb)
{
@@ -90,12 +125,12 @@ send_arp_q(void)
skb->arp = 1;
sti();
skb->dev->queue_xmit (skb, skb->dev, 0);
+
+ if (arp_q == NULL) break;
+
cli();
- if (arp_q == NULL) break;
- skb = arp_q;
- continue;
}
- skb=skb->next;
+ skb=skb2;
} while (skb != arp_q);
sti();
@@ -201,6 +236,7 @@ arp_response (struct arp *arp1, struct device *dev)
GFP_ATOMIC);
if (skb == NULL) return (1);
+ skb->lock = 0;
skb->mem_addr = skb;
skb->mem_len = sizeof (*skb) + sizeof (*arp2) + 2*arp1->hlen +
2*arp1->plen + dev->hard_header_len;
@@ -396,6 +432,7 @@ arp_snd (unsigned long paddr, struct device *dev, unsigned long saddr)
2*dev->addr_len+8, GFP_ATOMIC);
if (skb == NULL) return;
+ skb->lock = 0;
skb->sk = NULL;
skb->mem_addr = skb;
skb->mem_len = sizeof (*arp) + sizeof (*skb) + dev->hard_header_len +
@@ -495,7 +532,8 @@ arp_queue(struct sk_buff *skb)
if (skb->next != NULL)
{
sti();
- printk ("arp.c: arp_queue skb already on queue. \n");
+ printk ("arp.c: arp_queue skb already on queue magic=%X. \n",
+ skb->magic);
return;
}
if (arp_q == NULL)
@@ -511,5 +549,6 @@ arp_queue(struct sk_buff *skb)
skb->next->prev = skb;
skb->prev->next = skb;
}
+ skb->magic = ARP_QUEUE_MAGIC;
sti();
}
diff --git a/net/tcp/arp.h b/net/tcp/arp.h
index 038f695..844d23f 100644
--- a/net/tcp/arp.h
+++ b/net/tcp/arp.h
@@ -19,8 +19,11 @@
The Author may be reached as bir7@leland.stanford.edu or
C/O Department of Mathematics; Stanford University; Stanford, CA 94305
*/
-/* $Id: arp.h,v 0.8.4.2 1992/11/15 14:55:30 bir7 Exp $ */
+/* $Id: arp.h,v 0.8.4.3 1992/12/03 19:54:12 bir7 Exp $ */
/* $Log: arp.h,v $
+ * Revision 0.8.4.3 1992/12/03 19:54:12 bir7
+ * Added paranoid queue checking.
+ *
* Revision 0.8.4.2 1992/11/15 14:55:30 bir7
* make arp_q global so sock.c can mess with it.
*
@@ -29,6 +32,9 @@
*
* Revision 0.8.3.2 1992/11/10 00:14:47 bir7
* Changed malloc to kmalloc and added $iId$ and $Log: arp.h,v $
+ * Revision 0.8.4.3 1992/12/03 19:54:12 bir7
+ * Added paranoid queue checking.
+ *
* Revision 0.8.4.2 1992/11/15 14:55:30 bir7
* make arp_q global so sock.c can mess with it.
*
@@ -76,4 +82,7 @@ void arp_queue (struct sk_buff *skb);
#define ARP_REPLY 2
#define ARP_TIMEOUT 8640000 /* about 8 hours. */
#define ARP_RES_TIME 250 /* 2.5 seconds. */
+
+#define ARP_QUEUE_MAGIC 0x0432447A
+
#endif
diff --git a/net/tcp/dev.c b/net/tcp/dev.c
index 176fdc7..3a8cb12 100644
--- a/net/tcp/dev.c
+++ b/net/tcp/dev.c
@@ -19,8 +19,26 @@
The Author may be reached as bir7@leland.stanford.edu or
C/O Department of Mathematics; Stanford University; Stanford, CA 94305
*/
-/* $Id: dev.c,v 0.8.4.4 1992/11/18 15:38:03 bir7 Exp $ */
+/* $Id: dev.c,v 0.8.4.10 1992/12/12 19:25:04 bir7 Exp $ */
/* $Log: dev.c,v $
+ * Revision 0.8.4.10 1992/12/12 19:25:04 bir7
+ * Cleaned up Log messages.
+ *
+ * Revision 0.8.4.9 1992/12/12 01:50:49 bir7
+ * *** empty log message ***
+ *
+ * Revision 0.8.4.8 1992/12/08 20:49:15 bir7
+ * Edited ctrl-h's out of log messages.
+ *
+ * Revision 0.8.4.7 1992/12/06 23:29:59 bir7
+ * Converted to using lower half interrupt routine.
+ *
+ * Revision 0.8.4.6 1992/12/05 21:35:53 bir7
+ * Updated dev->init type.
+ *
+ * Revision 0.8.4.5 1992/12/03 19:52:20 bir7
+ * Added paranoid queue checking.
+ *
* Revision 0.8.4.4 1992/11/18 15:38:03 bir7
* Fixed bug in copying packets and changed some printk's
*
@@ -34,12 +52,13 @@
* version change only.
*
* Revision 0.8.3.5 1992/11/10 00:14:47 bir7
- * Changed malloc to kmalloc and added $iId$
+ * Changed malloc to kmalloc and added Id and Log
*
*/
#include <asm/segment.h>
#include <asm/system.h>
+#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
@@ -54,6 +73,7 @@
#include "tcp.h"
#include "sock.h"
#include <linux/errno.h>
+#include <linux/interrupt.h>
#include "arp.h"
#undef DEV_DEBUG
@@ -182,6 +202,7 @@ dev_queue_xmit (struct sk_buff *skb, struct device *dev, int pri)
skb->next->prev = skb;
skb->prev->next = skb;
}
+ skb->magic = DEV_QUEUE_MAGIC;
sti();
}
@@ -192,160 +213,164 @@ dev_queue_xmit (struct sk_buff *skb, struct device *dev, int pri)
1 <- exit even if you have more packets.
0 <- call me again no matter what.
- -1 <- last packet not processed, try again. */
+ -1 <- last packet not processed, try again.
+
+ It's changed now
+ 1 <- exit I can't do any more
+ 0 <- feed me more.
+
+ */
+
+static struct sk_buff *backlog = NULL;
int
-dev_rint(unsigned char *buff, unsigned long len, int flags,
+dev_rint(unsigned char *buff, long len, int flags,
struct device * dev)
{
struct sk_buff *skb=NULL;
- struct packet_type *ptype;
- unsigned short type;
- unsigned char flag =0;
unsigned char *to;
int amount;
- /* try to grab some memory. */
- if (len > 0 && buff != NULL)
- {
- skb = kmalloc (sizeof (*skb) + len, GFP_ATOMIC);
- if (skb != NULL)
- {
- skb->mem_len = sizeof (*skb) + len;
- skb->mem_addr = skb;
- }
- }
+ if (dev == NULL || buff == NULL || len <= 0) return (1);
- /* firs we copy the packet into a buffer, and save it for later. */
- if (buff != NULL && skb != NULL)
+ if (flags & IN_SKBUFF)
{
- if ( !(flags & IN_SKBUFF))
- {
- to = (unsigned char *)(skb+1);
- while (len > 0)
- {
- amount = min (len, (unsigned long) dev->rmem_end -
- (unsigned long) buff);
- memcpy (to, buff, amount);
- len -= amount;
- buff += amount;
- to += amount;
- if ((unsigned long)buff == dev->rmem_end)
- buff = (unsigned char *)dev->rmem_start;
- }
- }
- else
- {
- kfree_s (skb->mem_addr, skb->mem_len);
- skb = (struct sk_buff *)buff;
- }
-
- skb->len = len;
- skb->dev = dev;
- skb->sk = NULL;
-
- /* now add it to the dev backlog. */
- cli();
- if (dev-> backlog == NULL)
- {
- skb->prev = skb;
- skb->next = skb;
- dev->backlog = skb;
- }
- else
- {
- skb ->prev = dev->backlog->prev;
- skb->next = dev->backlog;
- skb->next->prev = skb;
- skb->prev->next = skb;
- }
- sti();
- return (0);
+ skb = (struct sk_buff *)buff;
}
-
- if (skb != NULL)
- kfree_s (skb->mem_addr, skb->mem_len);
-
- /* anything left to process? */
-
- if (dev->backlog == NULL)
+ else
{
- if (buff == NULL)
- {
- sti();
- return (1);
- }
-
- if (skb != NULL)
- {
- sti();
- return (-1);
- }
-
- sti();
- printk ("dev_rint:Dropping packets due to lack of memory\n");
- return (1);
+ skb = kmalloc (sizeof (*skb) + len, GFP_ATOMIC);
+ if (skb == NULL)
+ {
+ printk ("dev_rint:dropping packet due to lack of memory.\n");
+ return (1);
+ }
+ skb->lock = 0;
+ skb->mem_len = sizeof (*skb) + len;
+ skb->mem_addr = skb;
+ /* first we copy the packet into a buffer, and save it for later. */
+
+ to = (unsigned char *)(skb+1);
+ while (len > 0)
+ {
+ amount = min (len, (unsigned long) dev->rmem_end -
+ (unsigned long) buff);
+ memcpy (to, buff, amount);
+ len -= amount;
+ buff += amount;
+ to += amount;
+ if ((unsigned long)buff == dev->rmem_end)
+ buff = (unsigned char *)dev->rmem_start;
+ }
}
- skb= dev->backlog;
- if (skb->next == skb)
+ skb->len = len;
+ skb->dev = dev;
+ skb->sk = NULL;
+
+ /* now add it to the backlog. */
+ cli();
+ if (backlog == NULL)
{
- dev->backlog = NULL;
+ skb->prev = skb;
+ skb->next = skb;
+ backlog = skb;
}
else
{
- dev->backlog = skb->next;
- skb->next->prev = skb->prev;
- skb->prev->next = skb->next;
+ skb ->prev = backlog->prev;
+ skb->next = backlog;
+ skb->next->prev = skb;
+ skb->prev->next = skb;
}
sti();
+
+ if (backlog != NULL)
+ bh_active |= 1 << INET_BH;
- /* bump the pointer to the next structure. */
- skb->h.raw = (unsigned char *)(skb+1) + dev->hard_header_len;
- skb->len -= dev->hard_header_len;
+ return (0);
+}
- /* convert the type to an ethernet type. */
- type = dev->type_trans (skb, dev);
+void
+inet_bh(void *tmp)
+{
+ struct sk_buff *skb;
+ struct packet_type *ptype;
+ unsigned short type;
+ unsigned char flag =0;
+ static int in_bh=0;
- /* if there get to be a lot of types we should changes this to
- a bunch of linked lists like we do for ip protocols. */
- for (ptype = ptype_base; ptype != NULL; ptype=ptype->next)
+ cli();
+ if (in_bh != 0)
+ {
+ sti();
+ return;
+ }
+ in_bh=1;
+
+ /* anything left to process? */
+
+ while (backlog != NULL)
{
- if (ptype->type == type)
- {
- struct sk_buff *skb2;
- /* copy the packet if we need to. */
- if (ptype->copy)
- {
- skb2 = kmalloc (skb->mem_len, GFP_ATOMIC);
- if (skb2 == NULL) continue;
- memcpy (skb2, skb, skb->mem_len);
- skb2->mem_addr = skb2;
- skb2->h.raw = (void *)((unsigned long)skb2
- + (unsigned long)skb->h.raw
- - (unsigned long)skb);
-
- }
- else
- {
- skb2 = skb;
- flag = 1;
- }
-
- ptype->func (skb2, dev, ptype);
- }
- }
+ cli();
+ skb= backlog;
+ if (skb->next == skb)
+ {
+ backlog = NULL;
+ }
+ else
+ {
+ backlog = skb->next;
+ skb->next->prev = skb->prev;
+ skb->prev->next = skb->next;
+ }
+ sti();
+
+ /* bump the pointer to the next structure. */
+ skb->h.raw = (unsigned char *)(skb+1) + skb->dev->hard_header_len;
+ skb->len -= skb->dev->hard_header_len;
+
+ /* convert the type to an ethernet type. */
+ type = skb->dev->type_trans (skb, skb->dev);
+
+ /* if there get to be a lot of types we should changes this to
+ a bunch of linked lists like we do for ip protocols. */
+ for (ptype = ptype_base; ptype != NULL; ptype=ptype->next)
+ {
+ if (ptype->type == type)
+ {
+ struct sk_buff *skb2;
+ /* copy the packet if we need to. */
+ if (ptype->copy)
+ {
+ skb2 = kmalloc (skb->mem_len, GFP_ATOMIC);
+ if (skb2 == NULL) continue;
+ memcpy (skb2, skb, skb->mem_len);
+ skb2->mem_addr = skb2;
+ skb2->lock = 0;
+ skb2->h.raw = (void *)((unsigned long)skb2
+ + (unsigned long)skb->h.raw
+ - (unsigned long)skb);
- if (!flag)
- {
- PRINTK ("discarding packet type = %X\n", type);
- kfree_skb (skb, FREE_READ);
+ }
+ else
+ {
+ skb2 = skb;
+ flag = 1;
+ }
+
+ ptype->func (skb2, skb->dev, ptype);
+ }
+ }
+
+ if (!flag)
+ {
+ PRINTK ("discarding packet type = %X\n", type);
+ kfree_skb (skb, FREE_READ);
+ }
}
-
- if (buff == NULL)
- return (0);
- else
- return (-1);
+ in_bh = 0;
+ sti();
}
/* This routine is called when an device interface is ready to
@@ -366,19 +391,46 @@ dev_tint(unsigned char *buff, struct device *dev)
{
cli();
skb=dev->buffs[i];
+ if (skb->magic != DEV_QUEUE_MAGIC)
+ {
+ printk ("dev.c skb with bad magic-%X: squashing queue\n",
+ skb->magic);
+ cli();
+ dev->buffs[i] = NULL;
+ sti();
+ continue;
+ }
+
+ skb->magic = 0;
+
if (skb->next == skb)
{
dev->buffs[i] = NULL;
}
else
{
- dev->buffs[i]=skb->next;
- skb->prev->next = skb->next;
- skb->next->prev = skb->prev;
+ /* extra consistancy check. */
+ if (skb->next == NULL
+#ifdef CONFIG_MAX_16M
+ || (unsigned long)(skb->next) > 16*1024*1024
+#endif
+ )
+
+ {
+ printk ("dev.c: *** bug bad skb->next, squashing queue \n");
+ cli();
+ dev->buffs[i] = NULL;
+ }
+ else
+ {
+ dev->buffs[i]= skb->next;
+ skb->prev->next = skb->next;
+ skb->next->prev = skb->prev;
+ }
}
skb->next = NULL;
skb->prev = NULL;
- tmp = skb->len;
+
if (!skb->arp)
{
if (dev->rebuild_header (skb+1, dev))
@@ -390,6 +442,7 @@ dev_tint(unsigned char *buff, struct device *dev)
}
}
+ tmp = skb->len;
if (tmp <= dev->mtu)
{
if (dev->send_packet != NULL)
@@ -404,7 +457,12 @@ dev_tint(unsigned char *buff, struct device *dev)
}
else
{
- printk ("**** bug len bigger than mtu. \n");
+ printk ("dev.c:**** bug len bigger than mtu, "
+ "squashing queue. \n");
+ cli();
+ dev->buffs[i] = NULL;
+ continue;
+
}
sti();
if (skb->free)
diff --git a/net/tcp/dev.h b/net/tcp/dev.h
index 807af06..2e9d188 100644
--- a/net/tcp/dev.h
+++ b/net/tcp/dev.h
@@ -19,17 +19,27 @@
The Author may be reached as bir7@leland.stanford.edu or
C/O Department of Mathematics; Stanford University; Stanford, CA 94305
*/
-/* $Id: dev.h,v 0.8.4.1 1992/11/10 00:17:18 bir7 Exp $ */
+/* $Id: dev.h,v 0.8.4.5 1992/12/08 20:49:15 bir7 Exp $ */
/* $Log: dev.h,v $
+ * Revision 0.8.4.5 1992/12/08 20:49:15 bir7
+ * Edited ctrl-h's out of log messages.
+ *
+ * Revision 0.8.4.4 1992/12/06 23:29:59 bir7
+ * Converted to using lower half interrupt routine.
+ *
+ * Revision 0.8.4.3 1992/12/05 21:35:53 bir7
+ * Updated dev->init type.
+ *
+ * Revision 0.8.4.2 1992/12/03 19:54:12 bir7
+ * Added paranoid queue checking.
+ *
* Revision 0.8.4.1 1992/11/10 00:17:18 bir7
* version change only.
*
* Revision 0.8.3.2 1992/11/10 00:14:47 bir7
- * Changed malloc to kmalloc and added $iId$ and $Log: dev.h,v $
- * Revision 0.8.4.1 1992/11/10 00:17:18 bir7
- * version change only.
- *.
- * */
+ * Changed malloc to kmalloc and added Id and Log
+ *
+ */
#ifndef _TCP_DEV_H
#define _TCP_DEV_H
@@ -54,10 +64,10 @@ struct device
interrupt:1,
up:1;
struct device *next;
- void (*init)(struct device *dev);
+ int (*init)(struct device *dev);
unsigned long trans_start;
struct sk_buff *buffs[DEV_NUMBUFFS];
- struct sk_buff *backlog;
+ struct sk_buff *backlog; /* no longer used. */
int (*open)(struct device *dev);
int (*stop)(struct device *dev);
int (*hard_start_xmit) (struct sk_buff *skb, struct device *dev);
@@ -94,15 +104,17 @@ struct packet_type
/* used by dev_rint */
#define IN_SKBUFF 1
+#define DEV_QUEUE_MAGIC 0x17432895
+
extern struct packet_type *ptype_base;
void dev_queue_xmit (struct sk_buff *skb, struct device *dev, int pri);
-int dev_rint (unsigned char *buff, unsigned long len, int flags,
- struct device *dev);
+int dev_rint (unsigned char *buff, long len, int flags, struct device *dev);
unsigned long dev_tint (unsigned char *buff, struct device *dev);
void dev_add_pack (struct packet_type *pt);
void dev_remove_pack (struct packet_type *pt);
struct device *get_dev (char *name);
+void inet_bh (void *tmp);
#endif
diff --git a/net/tcp/eth.c b/net/tcp/eth.c
index 27a3688..afe678c 100644
--- a/net/tcp/eth.c
+++ b/net/tcp/eth.c
@@ -19,8 +19,11 @@
The Author may be reached as bir7@leland.stanford.edu or
C/O Department of Mathematics; Stanford University; Stanford, CA 94305
*/
-/* $Id: eth.c,v 0.8.4.2 1992/11/10 10:38:48 bir7 Exp $ */
+/* $Id: eth.c,v 0.8.4.3 1992/12/12 19:25:04 bir7 Exp $ */
/* $Log: eth.c,v $
+ * Revision 0.8.4.3 1992/12/12 19:25:04 bir7
+ * Cleaned up Log messages.
+ *
* Revision 0.8.4.2 1992/11/10 10:38:48 bir7
* Change free_s to kfree_s and accidently changed free_skb to kfree_skb.
*
@@ -28,7 +31,7 @@
* version change only.
*
* Revision 0.8.3.2 1992/11/10 00:14:47 bir7
- * Changed malloc to kmalloc and added $iId$
+ * Changed malloc to kmalloc and added Id and Log
*
*
*/
diff --git a/net/tcp/icmp.c b/net/tcp/icmp.c
index 0ce368d..8378b72 100644
--- a/net/tcp/icmp.c
+++ b/net/tcp/icmp.c
@@ -23,8 +23,20 @@
The author of this file may be reached at rth@sparta.com or Sparta, Inc.
7926 Jones Branch Dr. Suite 900, McLean Va 22102.
*/
-/* $Id: icmp.c,v 0.8.4.3 1992/11/18 15:38:03 bir7 Exp $ */
+/* $Id: icmp.c,v 0.8.4.7 1992/12/12 19:25:04 bir7 Exp $ */
/* $Log: icmp.c,v $
+ * Revision 0.8.4.7 1992/12/12 19:25:04 bir7
+ * Cleaned up Log messages.
+ *
+ * Revision 0.8.4.6 1992/12/12 01:50:49 bir7
+ * Fixed bug in call to err routine.
+ *
+ * Revision 0.8.4.5 1992/12/05 21:35:53 bir7
+ * fixed type mismatch.
+ *
+ * Revision 0.8.4.4 1992/12/03 19:52:20 bir7
+ * Fixed minor pugs in icmp_reply.
+ *
* Revision 0.8.4.3 1992/11/18 15:38:03 bir7
* Fixed some printk's.
*
@@ -35,7 +47,7 @@
* version change only.
*
* Revision 0.8.3.3 1992/11/10 00:14:47 bir7
- * Changed malloc to kmalloc and added $iId$ and
+ * Changed malloc to kmalloc and added Id and Log
*
*/
@@ -104,9 +116,12 @@ icmp_reply (struct sk_buff *skb_in, int type, int code, struct device *dev)
struct ip_header *iph;
int offset;
struct icmp_header *icmph;
-
int len;
- /* get some memory for the replay. */
+
+ PRINTK ("icmp_reply (skb_in = %X, type = %d, code = %d, dev=%X)\n",
+ skb_in, type, code, dev);
+
+ /* get some memory for the reply. */
len = sizeof (*skb) + 8 /* amount of header to return. */ +
sizeof (struct icmp_header) +
64 /* enough for an ip header. */ +
@@ -115,6 +130,7 @@ icmp_reply (struct sk_buff *skb_in, int type, int code, struct device *dev)
skb = kmalloc (len, GFP_ATOMIC);
if (skb == NULL) return;
+ skb->lock = 0;
skb->mem_addr = skb;
skb->mem_len = len;
@@ -208,12 +224,19 @@ icmp_rcv(struct sk_buff *skb1, struct device *dev, struct options *opt,
/* get the protocol(s) */
hash = iph->protocol & (MAX_IP_PROTOS -1 );
- for (ipprot = ip_protos[hash]; ipprot != NULL; ipprot=ipprot->next)
+
+ /* this can change while we are doing it. */
+ for (ipprot = ip_protos[hash]; ipprot != NULL; )
{
- /* pass it off to everyone who wants it. */
- ipprot->err_handler (err, (unsigned char *)iph+4*iph->ihl,
+ struct ip_protocol *nextip;
+ nextip = ipprot->next;
+ /* pass it off to everyone who wants it. */
+ if (iph->protocol == ipprot->protocol && ipprot->err_handler)
+ ipprot->err_handler (err, (unsigned char *)(icmph+1),
iph->daddr, iph->saddr, ipprot);
+ ipprot = nextip;
}
+
skb1->sk = NULL;
kfree_skb (skb1, FREE_READ);
return (0);
@@ -255,6 +278,7 @@ icmp_rcv(struct sk_buff *skb1, struct device *dev, struct options *opt,
return (0);
}
skb->sk = NULL;
+ skb->lock = 0;
skb->mem_addr = skb;
skb->mem_len = size;
diff --git a/net/tcp/ip.c b/net/tcp/ip.c
index 368b442..1399552 100644
--- a/net/tcp/ip.c
+++ b/net/tcp/ip.c
@@ -19,13 +19,24 @@
The Author may be reached as bir7@leland.stanford.edu or
C/O Department of Mathematics; Stanford University; Stanford, CA 94305
*/
-/* $Id: ip.c,v 0.8.4.4 1992/11/18 15:38:03 bir7 Exp $ */
+/* $Id: ip.c,v 0.8.4.8 1992/12/12 19:25:04 bir7 Exp $ */
/* $Log: ip.c,v $
+ * Revision 0.8.4.8 1992/12/12 19:25:04 bir7
+ * Cleaned up Log messages.
+ *
+ * Revision 0.8.4.7 1992/12/06 23:29:59 bir7
+ * Changed retransmit to double rtt.
+ *
+ * Revision 0.8.4.6 1992/12/05 21:35:53 bir7
+ * fixed checking of wrong fragmentation bit.
+ *
+ * Revision 0.8.4.5 1992/12/03 19:52:20 bir7
+ * added paranoid queue checking
+ *
* Revision 0.8.4.4 1992/11/18 15:38:03 bir7
* Fixed bug in copying packet and checking packet type.
*
* Revision 0.8.4.3 1992/11/17 14:19:47 bir7
- * *** empty log message ***
*
* Revision 0.8.4.2 1992/11/10 10:38:48 bir7
* Change free_s to kfree_s and accidently changed free_skb to kfree_skb.
@@ -34,9 +45,9 @@
* version change only.
*
* Revision 0.8.3.3 1992/11/10 00:14:47 bir7
- * Changed malloc to kmalloc and added $iId$ and
+ * Changed malloc to kmalloc and added Id and Log
*
-*/
+ */
#include <asm/segment.h>
#include <asm/system.h>
@@ -722,7 +733,7 @@ ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
}
/* deal with fragments. or don't for now.*/
- if ((iph->frag_off & 64) || (net16(iph->frag_off)&0x1fff))
+ if ((iph->frag_off & 32) || (net16(iph->frag_off)&0x1fff))
{
printk ("packet fragmented. \n");
skb->sk = NULL;
@@ -732,9 +743,6 @@ ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
skb->h.raw += iph->ihl*4;
- /* add it to the arp table if it's talking to us. That way we
- will be able to talk to them also. */
-
hash = iph->protocol & (MAX_IP_PROTOS -1);
for (ipprot = ip_protos[hash]; ipprot != NULL; ipprot=ipprot->next)
{
@@ -754,6 +762,7 @@ ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
if (skb2 == NULL) continue;
memcpy (skb2, skb, skb->mem_len);
skb2->mem_addr = skb2;
+ skb2->lock = 0;
skb2->h.raw = (void *)((unsigned long)skb2
+ (unsigned long)skb->h.raw
- (unsigned long)skb);
@@ -792,6 +801,13 @@ ip_queue_xmit (volatile struct sock *sk, struct device *dev,
struct ip_header *iph;
unsigned char *ptr;
if (sk == NULL) free = 1;
+
+ if (dev == NULL)
+ {
+ printk ("ip.c: ip_queue_xmit dev = NULL\n");
+ return;
+ }
+
skb->free = free;
skb->dev = dev;
skb->when = jiffies;
@@ -803,6 +819,11 @@ ip_queue_xmit (volatile struct sock *sk, struct device *dev,
ip_send_check (iph);
print_iph(iph);
skb->next = NULL;
+
+ /* see if this is the one
+ trashing our queue. */
+ skb->magic = 1;
+
if (!free)
{
skb->link3 = NULL;
@@ -880,12 +901,20 @@ ip_retransmit (volatile struct sock *sk, int all)
sk->retransmits++;
sk->prot->retransmits ++;
if (!all) break;
+
/* this should cut it off before we send too
many packets. */
if (sk->retransmits > sk->cong_window) break;
skb=skb->link3;
}
- sk->time_wait.len = sk->rtt*2;
+ /* double the rtt time every time we retransmit.
+ This will cause exponential back off on how
+ hard we try to get through again. Once we
+ get through, the rtt will settle back down
+ reasonably quickly. */
+
+ sk->rtt *= 2;
+ sk->time_wait.len = sk->rtt;
sk->timeout = TIME_WRITE;
reset_timer ((struct timer *)&sk->time_wait);
}
diff --git a/net/tcp/loopback.c b/net/tcp/loopback.c
index e41d7e8..25041d3 100644
--- a/net/tcp/loopback.c
+++ b/net/tcp/loopback.c
@@ -19,8 +19,14 @@
The Author may be reached as bir7@leland.stanford.edu or
C/O Department of Mathematics; Stanford University; Stanford, CA 94305
*/
-/* $Id: loopback.c,v 0.8.4.3 1992/11/18 15:38:03 bir7 Exp $ */
+/* $Id: loopback.c,v 0.8.4.5 1992/12/12 19:25:04 bir7 Exp $ */
/* $Log: loopback.c,v $
+ * Revision 0.8.4.5 1992/12/12 19:25:04 bir7
+ * Cleaned up Log messages.
+ *
+ * Revision 0.8.4.4 1992/12/05 21:35:53 bir7
+ * changed dev->init to return an int.
+ *
* Revision 0.8.4.3 1992/11/18 15:38:03 bir7
* Fixed bug in start_xmit.
*
@@ -31,7 +37,7 @@
* version change only.
*
* Revision 0.8.3.2 1992/11/10 00:14:47 bir7
- * Changed malloc to kmalloc and added $iId$ and
+ * Changed malloc to kmalloc and added Id and Log
* */
#include <linux/config.h>
@@ -123,7 +129,7 @@ loopback_xmit(struct sk_buff *skb, struct device *dev)
return (0);
}
-void
+int
loopback_init(struct device *dev)
{
printk ("Loopback device init\n");
@@ -140,4 +146,5 @@ loopback_init(struct device *dev)
dev->rebuild_header = eth_rebuild_header;
dev->type_trans = eth_type_trans;
dev->loopback = 1;
+ return (0);
}
diff --git a/net/tcp/pack_type.c b/net/tcp/pack_type.c
index d708b7a..f5b3d5d 100644
--- a/net/tcp/pack_type.c
+++ b/net/tcp/pack_type.c
@@ -19,8 +19,11 @@
The Author may be reached as bir7@leland.stanford.edu or
C/O Department of Mathematics; Stanford University; Stanford, CA 94305
*/
-/* $Id: pack_type.c,v 0.8.4.2 1992/11/10 10:38:48 bir7 Exp $ */
+/* $Id: pack_type.c,v 0.8.4.3 1992/12/12 19:25:04 bir7 Exp $ */
/* $Log: pack_type.c,v $
+ * Revision 0.8.4.3 1992/12/12 19:25:04 bir7
+ * Cleaned up Log messages.
+ *
* Revision 0.8.4.2 1992/11/10 10:38:48 bir7
* Change free_s to kfree_s and accidently changed free_skb to kfree_skb.
*
@@ -28,8 +31,9 @@
* version change only.
*
* Revision 0.8.3.2 1992/11/10 00:14:47 bir7
- * Changed malloc to kmalloc and added $iId$
- * */
+ * Changed malloc to kmalloc and added Id and Log
+ *
+ */
#include <linux/stddef.h>
#include "dev.h"
diff --git a/net/tcp/packet.c b/net/tcp/packet.c
index d594ed3..3513390 100644
--- a/net/tcp/packet.c
+++ b/net/tcp/packet.c
@@ -19,8 +19,14 @@
The Author may be reached as bir7@leland.stanford.edu or
C/O Department of Mathematics; Stanford University; Stanford, CA 94305
*/
-/* $Id: packet.c,v 0.8.4.3 1992/11/17 14:19:47 bir7 Exp $ */
+/* $Id: packet.c,v 0.8.4.5 1992/12/12 19:25:04 bir7 Exp $ */
/* $Log: packet.c,v $
+ * Revision 0.8.4.5 1992/12/12 19:25:04 bir7
+ * Cleaned up Log messages.
+ *
+ * Revision 0.8.4.4 1992/12/12 01:50:49 bir7
+ * Fixed bug in call to err routine.
+ *
* Revision 0.8.4.3 1992/11/17 14:19:47 bir7
* *** empty log message ***
*
@@ -31,7 +37,7 @@
* version change only.
*
* Revision 0.8.3.3 1992/11/10 00:14:47 bir7
- * Changed malloc to kmalloc and added $iId$
+ * Changed malloc to kmalloc and added Id and Log
* */
#include <linux/types.h>
@@ -150,6 +156,7 @@ packet_sendto (volatile struct sock *sk, unsigned char *from, int len,
print_sk (sk);
return (-EAGAIN);
}
+ skb->lock = 0;
skb->mem_addr = skb;
skb->mem_len = len + sizeof (*skb) +sk->prot->max_header;
skb->sk = sk;
@@ -222,6 +229,9 @@ packet_recvfrom (volatile struct sock *sk, unsigned char *to, int len,
if (len == 0) return (0);
if (len < 0) return (-EINVAL);
+
+ if (sk->shutdown & RCV_SHUTDOWN) return (0);
+
if (addr_len)
{
verify_area (addr_len, sizeof(*addr_len));
@@ -324,6 +334,7 @@ struct proto packet_prot =
udp_select,
NULL,
packet_init,
+ NULL,
128,
0,
{NULL,}
diff --git a/net/tcp/raw.c b/net/tcp/raw.c
index abfbeae..9592601 100644
--- a/net/tcp/raw.c
+++ b/net/tcp/raw.c
@@ -19,8 +19,17 @@
The Author may be reached as bir7@leland.stanford.edu or
C/O Department of Mathematics; Stanford University; Stanford, CA 94305
*/
-/* $Id: raw.c,v 0.8.4.6 1992/11/18 15:38:03 bir7 Exp $ */
+/* $Id: raw.c,v 0.8.4.9 1992/12/12 19:25:04 bir7 Exp $ */
/* $Log: raw.c,v $
+ * Revision 0.8.4.9 1992/12/12 19:25:04 bir7
+ * Cleaned up Log messages.
+ *
+ * Revision 0.8.4.8 1992/12/12 01:50:49 bir7
+ * Fixed bug in call to err routine.
+ *
+ * Revision 0.8.4.7 1992/12/06 11:31:47 bir7
+ * added raw_err.
+ *
* Revision 0.8.4.6 1992/11/18 15:38:03 bir7
* Works now.
*
@@ -38,7 +47,7 @@
* version change only.
*
* Revision 0.8.3.3 1992/11/10 00:14:47 bir7
- * Changed malloc to kmalloc and added $iId$ and
+ * Changed malloc to kmalloc and added Id and Log
* */
#include <linux/types.h>
@@ -56,7 +65,7 @@
#include <asm/segment.h>
#include <linux/mm.h>
#include <linux/kernel.h>
-#include "../kern_sock.h" /* for PRINTK */
+#include "icmp.h"
#ifdef PRINTK
@@ -79,6 +88,40 @@ min(unsigned long a, unsigned long b)
return (b);
}
+/* raw_err gets called by the icmp module. */
+void
+raw_err (int err, unsigned char *header, unsigned long daddr,
+ unsigned long saddr, struct ip_protocol *protocol)
+{
+ volatile struct sock *sk;
+
+ PRINTK ("raw_err (err=%d, header=%X, daddr=%X, saddr=%X, ip_protocl=%X)\n");
+
+ if (protocol == NULL) return;
+
+ sk = protocol->data;
+
+ if (sk == NULL) return;
+
+ /* This is meaningless in raw sockets. */
+ if (err & 0xff00 == (ICMP_SOURCE_QUENCH << 8))
+ {
+ if (sk->cong_window > 1)
+ sk->cong_window = sk->cong_window/2;
+ return;
+ }
+
+ sk->err = icmp_err_convert[err & 0xff].errno;
+ /* none of them are fatal for raw sockets. */
+/* if (icmp_err_convert[err & 0xff].fatal)
+ {
+ sk->prot->close(sk, 0);
+ } */
+
+ return;
+
+}
+
/* this should be the easiest of all, all we do is copy it into
a buffer. */
int
@@ -239,6 +282,7 @@ raw_sendto (volatile struct sock *sk, unsigned char *from, int len,
sti();
}
}
+ skb->lock = 0;
skb->mem_addr = skb;
skb->mem_len = len + sizeof (*skb) +sk->prot->max_header;
skb->sk = sk;
@@ -296,6 +340,7 @@ raw_init (volatile struct sock *sk)
p->handler = raw_rcv;
p->protocol = sk->protocol;
p->data = (void *)sk;
+ p->err_handler = raw_err;
add_ip_protocol (p);
/* we need to remember this somewhere. */
@@ -323,6 +368,8 @@ raw_recvfrom (volatile struct sock *sk, unsigned char *to, int len,
if (len == 0) return (0);
if (len < 0) return (-EINVAL);
+
+ if (sk->shutdown & RCV_SHUTDOWN) return (0);
if (addr_len)
{
verify_area (addr_len, sizeof(*addr_len));
@@ -426,6 +473,7 @@ struct proto raw_prot =
udp_select,
NULL,
raw_init,
+ NULL,
128,
0,
{NULL,}
diff --git a/net/tcp/sock.c b/net/tcp/sock.c
index 7f4ad2f..3351e03 100644
--- a/net/tcp/sock.c
+++ b/net/tcp/sock.c
@@ -19,13 +19,30 @@
The Author may be reached as bir7@leland.stanford.edu or
C/O Department of Mathematics; Stanford University; Stanford, CA 94305
*/
-/* $Id: sock.c,v 0.8.4.6 1992/11/18 15:38:03 bir7 Exp $ */
+/* $Id: sock.c,v 0.8.4.12 1992/12/12 19:25:04 bir7 Exp $ */
/* $Log: sock.c,v $
+ * Revision 0.8.4.12 1992/12/12 19:25:04 bir7
+ * Made memory leak checking more leanent.
+ *
+ * Revision 0.8.4.11 1992/12/12 01:50:49 bir7
+ * Fixed memory leak in accept.
+ *
+ * Revision 0.8.4.10 1992/12/08 20:49:15 bir7
+ * Added support for -EINPROGRESS
+ *
+ * Revision 0.8.4.9 1992/12/06 23:29:59 bir7
+ * Added mss and support for half completed packets.
+ *
+ * Revision 0.8.4.8 1992/12/05 21:35:53 bir7
+ * changed dev->init to return an int.
+ *
+ * Revision 0.8.4.7 1992/12/03 19:52:20 bir7
+ * added paranoid queue checking
+ *
* Revision 0.8.4.6 1992/11/18 15:38:03 bir7
* Fixed minor problem in setsockopt.
*
* Revision 0.8.4.5 1992/11/17 14:19:47 bir7
- * *** empty log message ***
*
* Revision 0.8.4.4 1992/11/16 16:13:40 bir7
* Fixed some error returns and undid one of the accept changes.
@@ -60,10 +77,24 @@
#include "tcp.h"
#include "udp.h"
#include "sock.h"
+#include "arp.h"
#include <asm/segment.h>
#include <asm/system.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
+#include <linux/interrupt.h>
+
+#undef ISOCK_DEBUG
+
+#ifdef PRINTK
+#undef PRINTK
+#endif
+
+#ifdef ISOCK_DEBUG
+#define PRINTK printk
+#else
+#define PRINTK dummy_routine
+#endif
#ifdef MEM_DEBUG
#define MPRINTK printk
@@ -216,6 +247,7 @@ kfree_skb (struct sk_buff *skb, int rw)
skb->free = 1;
return;
}
+ skb->magic = 0;
if (skb->sk)
{
if (rw)
@@ -418,16 +450,25 @@ destroy_sock(volatile struct sock *sk)
delete_timer((struct timer *)&sk->time_wait);
+ if (sk->send_tmp) kfree_skb (sk->send_tmp, FREE_WRITE);
+
/* cleanup up the write buffer. */
for (skb = sk->wfront; skb != NULL; )
{
struct sk_buff *skb2;
skb2=skb->next;
+ if (skb->magic != TCP_WRITE_QUEUE_MAGIC)
+ {
+ printk ("sock.c:destroy_sock write queue with bad magic (%X)\n",
+ skb->magic);
+ break;
+ }
kfree_skb(skb, FREE_WRITE);
skb=skb2;
}
sk->wfront = NULL;
+ sk->wback = NULL;
if (sk->rqueue != NULL)
{
@@ -459,6 +500,9 @@ destroy_sock(volatile struct sock *sk)
maybe the arp queue */
cli();
/* see if it's in a transmit queue. */
+ /* this can be simplified quite a bit. Look
+ at tcp.c:tcp_ack to see how. */
+
if (skb->next != NULL)
{
extern struct sk_buff *arp_q;
@@ -470,6 +514,15 @@ destroy_sock(volatile struct sock *sk)
if (skb == arp_q)
{
+ if (skb->magic != ARP_QUEUE_MAGIC)
+ {
+ sti();
+ printk ("sock.c: destroy_sock skb on arp queue with"
+ "bas magic (%X)\n", skb->magic);
+ cli();
+ arp_q = NULL;
+ continue;
+ }
arp_q = skb->next;
}
else
@@ -478,17 +531,31 @@ destroy_sock(volatile struct sock *sk)
{
if (skb->dev && skb->dev->buffs[i] == skb)
{
+ if (skb->magic != DEV_QUEUE_MAGIC)
+ {
+ sti();
+ printk ("sock.c: destroy sock skb on dev queue"
+ "with bad magic (%X)\n", skb->magic);
+ cli();
+ break;
+ }
skb->dev->buffs[i]= skb->next;
break;
}
}
}
- }
+ }
else
{
-
if (skb == arp_q)
{
+ if (skb->magic != ARP_QUEUE_MAGIC)
+ {
+ sti();
+ printk ("sock.c: destroy_sock skb on arp queue with"
+ "bas magic (%X)\n", skb->magic);
+ cli();
+ }
arp_q = NULL;
}
else
@@ -497,6 +564,14 @@ destroy_sock(volatile struct sock *sk)
{
if (skb->dev && skb->dev->buffs[i] == skb)
{
+ if (skb->magic != DEV_QUEUE_MAGIC)
+ {
+ sti();
+ printk ("sock.c: destroy sock skb on dev queue"
+ "with bad magic (%X)\n", skb->magic);
+ cli();
+ break;
+ }
skb->dev->buffs[i]= NULL;
break;
}
@@ -542,7 +617,7 @@ destroy_sock(volatile struct sock *sk)
/* now if everything is gone we can free the socket structure,
otherwise we need to keep it around until everything is gone. */
- if (sk->rmem_alloc == 0 && sk->wmem_alloc == 0)
+ if (sk->rmem_alloc <= 0 && sk->wmem_alloc <= 0)
{
kfree_s ((void *)sk,sizeof (*sk));
}
@@ -573,6 +648,7 @@ ip_proto_fcntl (struct socket *sock, unsigned int cmd, unsigned long arg)
printk ("Warning: sock->data = NULL: %d\n" ,__LINE__);
return (0);
}
+
switch (cmd)
{
case F_SETOWN:
@@ -675,6 +751,7 @@ ip_proto_getsockopt(struct socket *sock, int level, int optname,
printk ("Warning: sock->data = NULL: %d\n" ,__LINE__);
return (0);
}
+
switch (optname)
{
default:
@@ -748,6 +825,9 @@ ip_proto_listen(struct socket *sock, int backlog)
sk->dummy_th.source = net16(sk->num);
}
+ /* we might as well re use these. */
+ sk->max_ack_backlog = backlog;
+ sk->ack_backlog = 0;
sk->state = TCP_LISTEN;
return (0);
}
@@ -756,7 +836,7 @@ ip_proto_listen(struct socket *sock, int backlog)
static int ip_proto_init(void)
{
int i;
- struct device *dev;
+ struct device *dev, *dev2;
struct ip_protocol *p;
seq_offset = CURRENT_TIME*250;
/* add all the protocols. */
@@ -777,11 +857,26 @@ static int ip_proto_init(void)
}
/* add the devices */
+ /* if the call to dev->init fails, the dev is removed
+ from the chain disconnecting the device until the
+ next reboot. */
+
+ dev2 = NULL;
for (dev = dev_base; dev != NULL; dev=dev->next)
{
- if (dev->init)
- dev->init(dev);
+ if (dev->init && dev->init(dev))
+ {
+ if (dev2 == NULL)
+ dev_base = dev->next;
+ else
+ dev2->next = dev->next;
+ }
+ else
+ {
+ dev2 = dev;
+ }
}
+ bh_base[INET_BH].routine = inet_bh;
timer_table[NET_TIMER].fn = net_timer;
return (0);
}
@@ -897,6 +992,9 @@ ip_proto_create (struct socket *sock, int protocol)
sk->state = TCP_CLOSE;
sk->dead = 0;
sk->ack_timed = 0;
+ sk->send_tmp = NULL;
+ sk->mss = 0; /* we will try not to send any packets smaller
+ than this. */
/* this is how many unacked bytes we will accept for
this socket. */
@@ -979,6 +1077,7 @@ ip_proto_release(struct socket *sock, struct socket *peer)
volatile struct sock *sk;
sk = sock->data;
if (sk == NULL) return (0);
+ PRINTK ("ip_proto_release (sock = %X, peer = %X)\n", sock, peer);
wake_up (sk->sleep);
/* start closing the connection. This may take a while. */
/* if linger is set, we don't return until the close is
@@ -1098,6 +1197,23 @@ ip_proto_connect (struct socket *sock, struct sockaddr * uaddr,
return (0);
}
+ if (sk->state == TCP_ESTABLISHED)
+ {
+ sock->state = SS_CONNECTED;
+ return (-EISCONN);
+ }
+
+ if (sock->state == SS_CONNECTING)
+ {
+ if (sk->state == TCP_SYN_SENT || sk->state == TCP_SYN_RECV)
+ return (-EINPROGRESS);
+
+ if (sk->err) return (-sk->err);
+
+ sock->state = SS_CONNECTED;
+ return (-EISCONN);
+ }
+
/* we may need to bind the socket. */
if (sk->num == 0)
{
@@ -1116,26 +1232,29 @@ ip_proto_connect (struct socket *sock, struct sockaddr * uaddr,
if (err < 0) return (err);
}
- sock->state = SS_CONNECTED;
-
- if (flags & O_NONBLOCK) return (-EINPROGRESS);
+ sock->state = SS_CONNECTING;
+ if (sk->state != TCP_ESTABLISHED && (flags & O_NONBLOCK))
+ return (-EINPROGRESS);
cli(); /* avoid the race condition */
- while (sk->state != TCP_ESTABLISHED && sk->state < TCP_CLOSING)
+ while (sk->state == TCP_SYN_SENT || sk->state == TCP_SYN_RECV)
{
interruptible_sleep_on (sk->sleep);
if (current->signal & ~current->blocked)
{
sti();
sk->intr = 1;
+ sock->state = SS_UNCONNECTED;
return (-ERESTARTSYS);
}
}
sti();
+ sock->state = SS_CONNECTED;
sk->intr = 0;
if (sk->state != TCP_ESTABLISHED && sk->err)
{
+ sock->state = SS_UNCONNECTED;
return (-sk->err);
}
return (0);
@@ -1157,8 +1276,17 @@ ip_proto_accept (struct socket *sock, struct socket *newsock, int flags)
printk ("Warning: sock->data = NULL: %d\n" ,__LINE__);
return (0);
}
+
+ /* we've been passed an extra socket. We need to free it up because
+ the tcp module creates it's own when it accepts one. */
+ if (newsock->data)
+ kfree_s (newsock->data, sizeof (struct sock));
+
newsock->data = NULL;
- if (sk1->prot->accept == NULL) return (-EOPNOTSUPP);
+
+
+if (sk1->prot->accept == NULL) return (-EOPNOTSUPP);
+
/* restore the state if we have been interrupted, and
then returned. */
if (sk1->pair != NULL )
@@ -1228,7 +1356,7 @@ ip_proto_getname(struct socket *sock, struct sockaddr *uaddr,
}
if (peer)
{
- if (sk->state != TCP_ESTABLISHED)
+ if (!tcp_connected(sk->state))
return (-ENOTCONN);
sin.sin_port = sk->dummy_th.dest;
sin.sin_addr.s_addr = sk->daddr;
@@ -1256,10 +1384,6 @@ ip_proto_read (struct socket *sock, char *ubuf, int size, int noblock)
printk ("Warning: sock->data = NULL: %d\n" ,__LINE__);
return (0);
}
- if (sk->shutdown & RCV_SHUTDOWN)
- {
- return (0); /* this seems to be what sunos does. */
- }
/* we may need to bind the socket. */
if (sk->num == 0)
@@ -1284,11 +1408,6 @@ ip_proto_recv (struct socket *sock, void *ubuf, int size, int noblock,
printk ("Warning: sock->data = NULL: %d\n" ,__LINE__);
return (0);
}
- if (sk->shutdown & RCV_SHUTDOWN)
- {
- return (0);
- }
-
/* we may need to bind the socket. */
if (sk->num == 0)
@@ -1318,7 +1437,6 @@ ip_proto_write (struct socket *sock, char *ubuf, int size, int noblock)
return (-EPIPE);
}
-
/* we may need to bind the socket. */
if (sk->num == 0)
{
@@ -1349,7 +1467,6 @@ ip_proto_send (struct socket *sock, void *ubuf, int size, int noblock,
return (-EPIPE);
}
-
/* we may need to bind the socket. */
if (sk->num == 0)
{
@@ -1406,10 +1523,6 @@ ip_proto_recvfrom (struct socket *sock, void *ubuf, int size, int noblock,
printk ("Warning: sock->data = NULL: %d\n" ,__LINE__);
return (0);
}
- if (sk->shutdown & RCV_SHUTDOWN)
- {
- return (0);
- }
if (sk->prot->recvfrom == NULL) return (-EOPNOTSUPP);
@@ -1442,8 +1555,13 @@ ip_proto_shutdown (struct socket *sock, int how)
printk ("Warning: sock->data = NULL: %d\n" ,__LINE__);
return (0);
}
- if (sk->state != TCP_ESTABLISHED) return (-ENOTCONN);
+ if (sock->state == SS_CONNECTING && sk->state == TCP_ESTABLISHED)
+ sock->state = SS_CONNECTED;
+
+ if (!tcp_connected(sk->state)) return (-ENOTCONN);
sk->shutdown |= how;
+ if (sk->prot->shutdown)
+ sk->prot->shutdown (sk, how);
return (0);
}
@@ -1589,7 +1707,7 @@ sock_wfree (volatile struct sock *sk, void *mem, unsigned long size)
{
sk->wmem_alloc -= size;
/* in case it might be waiting for more memory. */
- if (!sk->dead && sk->wmem_alloc > SK_WMEM_MAX/2) wake_up(sk->sleep);
+ if (!sk->dead) wake_up(sk->sleep);
if (sk->destroy && sk->wmem_alloc == 0 && sk->rmem_alloc == 0)
{
MPRINTK ("recovered lost memory, destroying sock = %X\n",sk);
diff --git a/net/tcp/sock.h b/net/tcp/sock.h
index 13c6b6d..3d8716d 100644
--- a/net/tcp/sock.h
+++ b/net/tcp/sock.h
@@ -19,8 +19,17 @@
The Author may be reached as bir7@leland.stanford.edu or
C/O Department of Mathematics; Stanford University; Stanford, CA 94305
*/
-/* $Id: sock.h,v 0.8.4.2 1992/11/10 10:38:48 bir7 Exp $ */
+/* $Id: sock.h,v 0.8.4.5 1992/12/12 01:50:49 bir7 Exp $ */
/* $Log: sock.h,v $
+ * Revision 0.8.4.5 1992/12/12 01:50:49 bir7
+ * Fixed support for half duplex connections.
+ *
+ * Revision 0.8.4.4 1992/12/06 23:29:59 bir7
+ * Added mss and support for half completed packets.
+ *
+ * Revision 0.8.4.3 1992/12/03 19:54:12 bir7
+ * Added paranoid queue checking.
+ *
* Revision 0.8.4.2 1992/11/10 10:38:48 bir7
* Change free_s to kfree_s and accidently changed free_skb to kfree_skb.
*
@@ -28,14 +37,9 @@
* version change only.
*
* Revision 0.8.3.4 1992/11/10 00:14:47 bir7
- * Changed malloc to kmalloc and added $iId$ and $Log: sock.h,v $
- * Revision 0.8.4.2 1992/11/10 10:38:48 bir7
- * Change free_s to kfree_s and accidently changed free_skb to kfree_skb.
+ * Changed malloc to kmalloc and added Id and Log
*
- * Revision 0.8.4.1 1992/11/10 00:17:18 bir7
- * version change only.
- *.
- * */
+ */
#ifndef _TCP_SOCK_H
#define _TCP_SOCK_H
@@ -65,6 +69,7 @@ struct sock
struct sk_buff *send_tail;
struct sk_buff *send_head;
struct sk_buff *back_log;
+ struct sk_buff *send_tmp;
long retransmits;
struct sk_buff *wback, *wfront, *rqueue;
struct proto *prot;
@@ -80,6 +85,7 @@ struct sock
unsigned short packets_out;
unsigned short urg;
unsigned short shutdown;
+ unsigned short mss;
short rtt;
short err;
unsigned char protocol;
@@ -129,6 +135,7 @@ struct proto
int (*select)(volatile struct sock *sk, int which, select_table *wait);
int (*ioctl) (volatile struct sock *sk, int cmd, unsigned long arg);
int (*init) (volatile struct sock *sk);
+ void (*shutdown) (volatile struct sock *sk, int how);
unsigned short max_header;
unsigned long retransmits;
volatile struct sock *sock_array[SOCK_ARRAY_SIZE];
@@ -168,6 +175,7 @@ struct sk_buff
unsigned long len;
unsigned long saddr;
unsigned long daddr;
+ int magic;
unsigned long acked:1,used:1,free:1,arp:1, urg_used:1, lock:1;
};
diff --git a/net/tcp/tcp.c b/net/tcp/tcp.c
index 71b7e80..9d5d681 100644
--- a/net/tcp/tcp.c
+++ b/net/tcp/tcp.c
@@ -18,15 +18,34 @@
The Author may be reached as bir7@leland.stanford.edu or
C/O Department of Mathematics; Stanford University; Stanford, CA 94305
+
+ Modifications for half-duplex connections base on those by,
+ Tim MacKenzie (tym@dibbler.cs.moansh.edu.au)
+
*/
-/* $Id: tcp.c,v 0.8.4.6 1992/11/18 15:38:03 bir7 Exp $ */
+/* $Id: tcp.c,v 0.8.4.12 1992/12/12 19:25:04 bir7 Exp $ */
/* $Log: tcp.c,v $
+ * Revision 0.8.4.12 1992/12/12 19:25:04 bir7
+ * Fixed anti-memory Leak in shutdown.
+ *
+ * Revision 0.8.4.11 1992/12/12 01:50:49 bir7
+ * Fixed several bugs including half-duplex connections.
+ *
+ * Revision 0.8.4.10 1992/12/08 20:49:15 bir7
+ * Fixed minor bugs and checked out MSS.
+ *
+ * Revision 0.8.4.9 1992/12/06 23:29:59 bir7
+ * Added support for mss and half completed packets. Also added
+ * support for shrinking windows.
+ *
+ * Revision 0.8.4.8 1992/12/05 21:35:53 bir7
+ *
+ * Revision 0.8.4.7 1992/12/03 19:52:20 bir7
+ * fixed = <-> == bug.
+ *
* Revision 0.8.4.6 1992/11/18 15:38:03 bir7
* fixed minor problem in waiting for memory.
*
- * Revision 0.8.4.5 1992/11/17 14:19:47 bir7
- * *** empty log message ***
- *
* Revision 0.8.4.4 1992/11/16 16:13:40 bir7
* Fixed some error returns and undid one of the accept changes.
*
@@ -41,8 +60,9 @@
* version change only.
*
* Revision 0.8.3.3 1992/11/10 00:14:47 bir7
- * Changed malloc to kmalloc and added $iId$ and
- * */
+ * Changed malloc to kmalloc and added Id and Log
+ *
+ */
#include <linux/types.h>
#include <linux/sched.h>
@@ -56,6 +76,7 @@
#include "icmp.h"
#include "tcp.h"
#include "sock.h"
+#include "arp.h"
#include <linux/errno.h>
#include <linux/timer.h>
#include <asm/system.h>
@@ -63,7 +84,6 @@
#include <linux/mm.h>
/* #include <signal.h>*/
#include <linux/termios.h> /* for ioctl's */
-#include "../kern_sock.h" /* for PRINTK */
#ifdef PRINTK
#undef PRINTK
@@ -179,8 +199,12 @@ tcp_err (int err, unsigned char *header, unsigned long daddr,
struct tcp_header *th;
volatile struct sock *sk;
+ PRINTK ("tcp_err(err=%d, header=%X, daddr=%X saddr=%X, protocol=%X)\n",
+ err, header, daddr, saddr, protocol);
+
th = (struct tcp_header *)header;
sk = get_sock (&tcp_prot, net16(th->dest), saddr, th->source, daddr);
+ print_th (th);
if (sk == NULL) return;
@@ -226,8 +250,10 @@ tcp_select (volatile struct sock *sk, int sel_type, select_table *wait)
{
case TCP_LISTEN:
case TCP_ESTABLISHED:
+ case TCP_FIN_WAIT1:
case TCP_SYN_SENT:
case TCP_SYN_RECV:
+ case TCP_FIN_WAIT2:
return (0);
default:
return (1);
@@ -235,18 +261,28 @@ tcp_select (volatile struct sock *sk, int sel_type, select_table *wait)
case SEL_OUT:
select_wait (sk->sleep, wait);
- if (sk->state != TCP_ESTABLISHED) return (1);
- /* hack so it will probably be able to write something
- if it says it's ok to write. */
- if (sk->prot->wspace(sk) >= MIN_WRITE_SPACE) return (1);
- return (0);
+
+ switch(sk->state)
+ {
+ default:
+ return (1);
+
+ case TCP_SYN_SENT:
+ case TCP_SYN_RECV:
+ return (0);
+
+ case TCP_ESTABLISHED:
+ case TCP_CLOSE_WAIT:
+ /* hack so it will probably be able to write something
+ if it says it's ok to write. */
+ if (sk->prot->wspace(sk) >= MIN_WRITE_SPACE) return (1);
+ return (0);
+ }
case SEL_EX:
select_wait(sk->sleep,wait);
if (sk->err) return (1);
- if (sk->state == TCP_FIN_WAIT1 ||
- sk->state == TCP_FIN_WAIT2 ||
- sk->state == TCP_TIME_WAIT ||
+ if (sk->state == TCP_TIME_WAIT ||
sk->state == TCP_LAST_ACK)
return (1);
return (0);
@@ -257,6 +293,7 @@ tcp_select (volatile struct sock *sk, int sel_type, select_table *wait)
static int
tcp_ioctl (volatile struct sock *sk, int cmd, unsigned long arg)
{
+ PRINTK ("tcp_ioctl (sk=%X, cmd = %d, arg=%X)\n", sk, cmd, arg);
switch (cmd)
{
default:
@@ -266,23 +303,33 @@ tcp_ioctl (volatile struct sock *sk, int cmd, unsigned long arg)
/* case FIONREAD:*/
{
unsigned long amount;
+ unsigned long counted;
+ int sum;
struct sk_buff *skb;
if (sk->state == TCP_LISTEN)
return (-EINVAL);
+ counted = sk->copied_seq;
amount = 0;
if (sk->rqueue != NULL)
{
skb = sk->rqueue->next;
- /* go until a push or until we are out of data. */
+ /* go until a push or until we are out of data. */
do {
- amount += skb -> len;
+ if (before (counted+1, skb->h.th->seq)) break;
+ sum = skb->len + skb->h.th->seq - counted;
+ if (sum > 0)
+ {
+ amount += sum;
+ counted += sum;
+ }
if (skb->h.th->psh) break;
skb = skb->next;
+
} while (skb != sk->rqueue->next);
}
-
+ PRINTK ("returning %d\n", amount);
verify_area ((void *)arg, sizeof (unsigned long));
put_fs_long (amount, (unsigned long *)arg);
return (0);
@@ -391,7 +438,7 @@ tcp_check (struct tcp_header *th, int len, unsigned long saddr,
static void
tcp_send_check (struct tcp_header *th, unsigned long saddr,
unsigned long daddr, int len, volatile struct sock *sk)
- {
+{
th->check = 0;
if (sk && sk->no_check) return;
@@ -399,12 +446,54 @@ tcp_send_check (struct tcp_header *th, unsigned long saddr,
return;
}
- /* This routine sends an ack and also updates the window. */
- static void
- tcp_send_ack (unsigned long sequence, unsigned long ack,
+static void
+tcp_send_partial(volatile struct sock *sk)
+{
+ struct sk_buff *skb;
+
+ if (sk == NULL || sk->send_tmp == NULL) return;
+
+ skb = sk->send_tmp;
+ /* we need to complete and send the packet. */
+ tcp_send_check (skb->h.th, sk->saddr, sk->daddr,
+ skb->len-(unsigned long)skb->h.th +
+ (unsigned long)(skb+1), sk);
+
+ skb->h.seq = sk->send_seq;
+ if (after (sk->send_seq , sk->window_seq) ||
+ sk->packets_out >= sk->cong_window)
+ {
+ PRINTK ("sk->cong_window = %d, sk->packets_out = %d\n",
+ sk->cong_window, sk->packets_out);
+ PRINTK ("sk->send_seq = %d, sk->window_seq = %d\n",
+ sk->send_seq, sk->window_seq);
+ skb->next = NULL;
+ skb->magic = TCP_WRITE_QUEUE_MAGIC;
+ if (sk->wback == NULL)
+ {
+ sk->wfront=skb;
+ }
+ else
+ {
+ sk->wback->next = skb;
+ }
+ sk->wback = skb;
+ }
+ else
+ {
+ sk->prot->queue_xmit (sk, skb->dev, skb,0);
+ }
+ sk->send_tmp = NULL;
+}
+
+
+
+/* This routine sends an ack and also updates the window. */
+static void
+tcp_send_ack (unsigned long sequence, unsigned long ack,
volatile struct sock *sk,
struct tcp_header *th, unsigned long daddr)
- {
+{
struct sk_buff *buff;
struct tcp_header *t1;
struct device *dev=NULL;
@@ -418,7 +507,7 @@ tcp_send_check (struct tcp_header *th, unsigned long saddr,
{
/* force it to send an ack. */
sk->ack_backlog++;
- if (sk->timeout != TIME_WRITE && sk->state < TCP_CLOSING)
+ if (sk->timeout != TIME_WRITE && tcp_connected (sk->state))
{
sk->timeout = TIME_WRITE;
sk->time_wait.len = 10; /* got to do it quickly. */
@@ -429,6 +518,7 @@ tcp_send_check (struct tcp_header *th, unsigned long saddr,
buff->mem_addr = buff;
buff->mem_len = MAX_ACK_SIZE;
+ buff->lock = 0;
buff->len=sizeof (struct tcp_header);
buff->sk = sk;
t1 = (struct tcp_header *)(buff + 1);
@@ -504,8 +594,8 @@ tcp_build_header(struct tcp_header *th, volatile struct sock *sk, int push)
the transmit system. */
static int
-tcp_write(volatile struct sock *sk, unsigned char *from,
- int len, int nonblock, unsigned flags)
+tcp_write (volatile struct sock *sk, unsigned char *from,
+ int len, int nonblock, unsigned flags)
{
int copied=0;
int copy;
@@ -515,34 +605,45 @@ tcp_write(volatile struct sock *sk, unsigned char *from,
struct proto *prot;
struct device *dev=NULL;
- PRINTK ("in TCP_WRITE sk = %X:\n",sk);
+ PRINTK ("tcp_write (sk=%X, from=%X, len=%d, nonblock=%d, flags=%X)\n",
+ sk, from, len, nonblock, flags);
+
print_sk (sk);
- sk->inuse = 1; /* no one else will use this socket. */
prot = sk->prot;
while (len > 0)
{
/* first thing we do is make sure that we are established. */
- while (sk->state != TCP_ESTABLISHED)
+ sk->inuse = 1; /* no one else will use this socket. */
+ while (sk->state != TCP_ESTABLISHED && sk->state != TCP_CLOSE_WAIT)
{
if (sk->state != TCP_SYN_SENT &&
sk->state != TCP_SYN_RECV)
{
release_sock (sk);
+ PRINTK ("tcp_write: return 1\n");
+ if (copied) return (copied);
+
+ if (sk->err)
+ {
+ tmp = -sk->err;
+ sk->err = 0;
+ return (tmp);
+ }
+
if (sk->keepopen)
{
send_sig (SIGPIPE, current, 0);
- return (-EINTR);
}
- if (copied) return (copied);
- if (sk->err) return (-sk->err);
return (-EPIPE);
}
if (nonblock)
{
+ PRINTK ("tcp_write: return 2\n");
release_sock (sk);
+ if (copied) return (copied);
return (-EAGAIN);
}
@@ -554,12 +655,13 @@ tcp_write(volatile struct sock *sk, unsigned char *from,
go to sleep. */
release_sock (sk);
cli();
- if (sk->state != TCP_ESTABLISHED)
+ if (sk->state != TCP_ESTABLISHED && sk->state != TCP_CLOSE_WAIT)
{
interruptible_sleep_on (sk->sleep);
if (current->signal & ~current->blocked)
{
sti();
+ PRINTK ("tcp_write: return 3\n");
if (copied) return (copied);
return (-ERESTARTSYS);
}
@@ -567,29 +669,87 @@ tcp_write(volatile struct sock *sk, unsigned char *from,
sti();
sk->inuse = 1;
}
+
+ /* Now we need to check if we have a half built packet. */
+ if (sk->send_tmp != NULL)
+ {
+ /* if sk->mss has been changed this could cause problems. */
+ /* add more stuff to the end of skb->len*/
+ skb = sk->send_tmp;
+ if (!(flags & MSG_OOB))
+ {
+ copy = min (sk->mss - skb->len + 128 + prot->max_header, len);
+
+ /* this is really a bug. */
+ if (copy <= 0)
+ copy = 0;
+
+ memcpy_fromfs ((unsigned char *)(skb+1) + skb->len, from, copy);
+ skb->len += copy;
+ from += copy;
+ copied += copy;
+ len -= copy;
+ sk->send_seq += copy;
+ }
+
+ if (skb->len - (unsigned long)skb->h.th +
+ (unsigned long)(skb+1) >= sk->mss
+ || (flags & MSG_OOB))
+ {
+ tcp_send_partial (sk);
+ }
+ continue;
+
+ }
+
/* we also need to worry about the window. The smallest we
will send is about 200 bytes. */
-
copy = min (sk->mtu, diff(sk->window_seq, sk->send_seq));
/* redundent check here. */
if (copy < 200 || copy > sk->mtu) copy = sk->mtu;
copy = min (copy, len);
- skb=prot->wmalloc (sk, copy + prot->max_header+sizeof (*skb),0,
- GFP_KERNEL);
+ /* we should really check the window here also. */
+ if (sk->packets_out && copy < sk->mss && !(flags & MSG_OOB))
+ {
+ /* we will release the socket incase we sleep here. */
+ release_sock (sk);
+ skb=prot->wmalloc (sk,
+ sk->mss + 128 + prot->max_header + sizeof (*skb),
+ 0, GFP_KERNEL);
+ sk->inuse = 1;
+ sk->send_tmp = skb;
+ if (skb != NULL)
+ skb->mem_len = sk->mss + 128 + prot->max_header+sizeof (*skb);
+ }
+ else
+ {
+ /* we will release the socket incase we sleep here. */
+ release_sock (sk);
+ skb=prot->wmalloc (sk, copy + prot->max_header+sizeof (*skb),0,
+ GFP_KERNEL);
+ sk->inuse = 1;
+ if (skb != NULL)
+ skb->mem_len = copy+prot->max_header+sizeof (*skb);
+ }
/* if we didn't get any memory, we need to sleep. */
if (skb == NULL)
{
- if (nonblock || copied)
+ if (nonblock)
{
- break;
+ release_sock (sk);
+ PRINTK ("tcp_write: return 4\n");
+ if (copied) return (copied);
+ return (-EAGAIN);
}
+
/* here is another race condition. */
tmp = sk->wmem_alloc;
release_sock (sk);
+
/* again we will try to avoid it. */
cli ();
if (tmp <= sk->wmem_alloc)
@@ -598,6 +758,7 @@ tcp_write(volatile struct sock *sk, unsigned char *from,
if (current->signal & ~current->blocked)
{
sti();
+ PRINTK ("tcp_write: return 5\n");
if (copied) return (copied);
return (-ERESTARTSYS);
}
@@ -606,10 +767,13 @@ tcp_write(volatile struct sock *sk, unsigned char *from,
sti();
continue;
}
+
skb->mem_addr = skb;
- skb->mem_len = copy+prot->max_header+sizeof (*skb);
skb->len = 0;
skb->sk = sk;
+ skb->lock = 0;
+ skb->free = 0;
+
buff =(unsigned char *)( skb+1);
/* we need to optimize this. Perhaps some hints here
would be good. */
@@ -620,16 +784,22 @@ tcp_write(volatile struct sock *sk, unsigned char *from,
{
prot->wfree (sk, skb->mem_addr, skb->mem_len);
release_sock (sk);
+ PRINTK ("tcp_write: return 6\n");
+ if (copied) return (copied);
return (tmp);
}
skb->len += tmp;
skb->dev = dev;
buff+=tmp;
+ skb->h.th =(struct tcp_header *) buff;
tmp = tcp_build_header((struct tcp_header *)buff, sk, len-copy);
+
if (tmp < 0)
{
prot->wfree (sk, skb->mem_addr, skb->mem_len);
release_sock (sk);
+ PRINTK ("tcp_write: return 7\n");
+ if (copied) return (copied);
return (tmp);
}
@@ -641,15 +811,22 @@ tcp_write(volatile struct sock *sk, unsigned char *from,
skb->len += tmp;
memcpy_fromfs (buff+tmp, from, copy);
- tcp_send_check ((struct tcp_header *)buff, sk->saddr, sk->daddr,
- copy +sizeof (struct tcp_header), sk);
-
from += copy;
copied += copy;
len -= copy;
skb->len += copy;
skb->free = 0;
sk->send_seq += copy;
+
+ if (sk->send_tmp != NULL)
+ {
+ continue;
+ }
+
+ tcp_send_check ((struct tcp_header *)buff, sk->saddr, sk->daddr,
+ copy +sizeof (struct tcp_header), sk);
+
+
skb->h.seq = sk->send_seq;
if (after (sk->send_seq , sk->window_seq) ||
sk->packets_out >= sk->cong_window)
@@ -659,6 +836,7 @@ tcp_write(volatile struct sock *sk, unsigned char *from,
PRINTK ("sk->send_seq = %d, sk->window_seq = %d\n",
sk->send_seq, sk->window_seq);
skb->next = NULL;
+ skb->magic = TCP_WRITE_QUEUE_MAGIC;
if (sk->wback == NULL)
{
sk->wfront=skb;
@@ -676,9 +854,27 @@ tcp_write(volatile struct sock *sk, unsigned char *from,
}
sk->err = 0;
release_sock (sk);
+ PRINTK ("tcp_write: return 8\n");
return (copied);
}
+static int
+tcp_sendto (volatile struct sock *sk, unsigned char *from,
+ int len, int nonblock, unsigned flags,
+ struct sockaddr_in *addr, int addr_len)
+{
+ struct sockaddr_in sin;
+ if (addr_len < sizeof (sin))
+ return (-EINVAL);
+ memcpy_fromfs (&sin, addr, sizeof (sin));
+ if (sin.sin_family && sin.sin_family != AF_INET)
+ return (-EINVAL);
+ if (sin.sin_port != sk->dummy_th.dest)
+ return (-EINVAL);
+ if (sin.sin_addr.s_addr != sk->daddr)
+ return (-EINVAL);
+ return (tcp_write (sk, from, len, nonblock, flags));
+}
static void
tcp_read_wakeup(volatile struct sock *sk)
@@ -709,6 +905,7 @@ tcp_read_wakeup(volatile struct sock *sk)
buff->mem_addr = buff;
buff->mem_len = MAX_ACK_SIZE;
+ buff->lock = 0;
buff->len=sizeof (struct tcp_header);
buff->sk = sk;
@@ -751,7 +948,7 @@ tcp_read_wakeup(volatile struct sock *sk)
static void
cleanup_rbuf (volatile struct sock *sk)
{
- PRINTK ("cleaning rbuf for sk=%X\n",sk);
+/* PRINTK ("cleaning rbuf for sk=%X\n",sk);*/
/* we have to loop through all the buffer headers, and
try to free up all the space we can. */
while (sk->rqueue != NULL )
@@ -774,28 +971,26 @@ cleanup_rbuf (volatile struct sock *sk)
/* at this point we should send an ack if the difference in
the window, and the amount of space is bigger than
TCP_WINDOW_DIFF */
- PRINTK ("sk->window left = %d, sk->prot->rspace(sk)=%d\n",
- sk->window - sk->bytes_rcv, sk->prot->rspace(sk));
+/* PRINTK ("sk->window left = %d, sk->prot->rspace(sk)=%d\n",
+ sk->window - sk->bytes_rcv, sk->prot->rspace(sk));*/
if ((sk->prot->rspace(sk) >
- (sk->window - sk->bytes_rcv + TCP_WINDOW_DIFF)) ||
- (sk->window - sk->bytes_rcv < 2*sk->mtu))
+ (sk->window - sk->bytes_rcv + TCP_WINDOW_DIFF)))
{
- /* force it to send an ack. */
- sk->ack_backlog++;
- if (sk->timeout != TIME_WRITE && sk->state == TCP_ESTABLISHED)
- {
- sk->time_wait.len = TCP_ACK_TIME;
- sk->timeout=TIME_WRITE;
- reset_timer ((struct timer *)&sk->time_wait);
- }
+ sk->ack_backlog++;
+ /* force it to send an ack soon. */
+ if ( before (jiffies + TCP_ACK_TIME, sk->time_wait.when))
+ {
+ sk->time_wait.len = TCP_ACK_TIME;
+ reset_timer ((struct timer *)&sk->time_wait);
+ }
}
}
/* handle reading urgent data. */
static int
-tcp_read_urg(volatile struct sock * sk,
+tcp_read_urg(volatile struct sock * sk, int nonblock,
unsigned char *to, int len, unsigned flags)
{
int copied = 0;
@@ -808,13 +1003,45 @@ tcp_read_urg(volatile struct sock * sk,
sk->inuse = 1;
while (sk->urg==0 || sk->rqueue == NULL)
{
- /* now at this point, we may have gotten some data. */
- release_sock (sk);
- if (sk->state > TCP_CLOSING)
+ if (sk->err)
+ {
+ int tmp;
+ release_sock (sk);
+ if (copied) return (copied);
+ tmp = -sk->err;
+ sk->err = 0;
+ return (tmp);
+ }
+
+ if (sk->state == TCP_CLOSE)
+ {
+ release_sock (sk);
+ if (copied) return (copied);
+ if (!sk->done)
+ {
+ sk->done = 1;
+ return (0);
+ }
+ return (-ENOTCONN);
+ }
+
+ if (sk->shutdown & RCV_SHUTDOWN)
{
- if (copied) return (copied);
- return (-ENOTCONN);
+ release_sock(sk);
+ if (copied == 0)
+ sk->done = 1;
+ return (copied);
}
+
+ if (nonblock)
+ {
+ release_sock (sk);
+ if (copied) return (copied);
+ return (-EAGAIN);
+ }
+
+ /* now at this point, we may have gotten some data. */
+ release_sock (sk);
cli();
if (sk->urg == 0 || sk->rqueue == NULL)
{
@@ -886,7 +1113,7 @@ tcp_read(volatile struct sock *sk, unsigned char *to,
/* urgent data needs to be handled specially. */
if ((flags & MSG_OOB))
- return (tcp_read_urg (sk, to, len, flags));
+ return (tcp_read_urg (sk, nonblock, to, len, flags));
/* so no-one else will use this socket. */
sk->inuse = 1;
@@ -895,10 +1122,11 @@ tcp_read(volatile struct sock *sk, unsigned char *to,
else
skb = NULL;
+ PRINTK("tcp_read (sk=%X, to=%X, len=%d, nonblock=%d, flags=%X)\n",
+ sk, to, len, nonblock, flags);
+
while ( len > 0)
{
- PRINTK("tcp_read (sk=%X, to=%X, len=%d, nonblock=%d, flags=%X)\n",
- sk, to, len, nonblock, flags);
while ( skb == NULL || before (sk->copied_seq+1, skb->h.th->seq) ||
skb->used) /* skb->used just checks to see if we've
gone all the way around. */
@@ -910,34 +1138,54 @@ tcp_read(volatile struct sock *sk, unsigned char *to,
cleanup_rbuf(sk);
- release_sock (sk); /* now we may have some data waiting. */
-
+ if (sk->err)
+ {
+ int tmp;
+ release_sock (sk);
+ if (copied) return (copied);
+ tmp = -sk->err;
+ sk->err = 0;
+ return (tmp);
+ }
- PRINTK ("tcp_read about to sleep. state = %d\n",sk->state);
- cli();
+ if (sk->state == TCP_CLOSE)
+ {
+ release_sock (sk);
+ if (copied) return (copied);
+ if (!sk->done)
+ {
+ sk->done = 1;
+ return (0);
+ }
+ return (-ENOTCONN);
+ }
- if (sk->state == TCP_CLOSE || sk->state == TCP_TIME_WAIT)
+ if (sk->shutdown & RCV_SHUTDOWN)
{
- sti();
- if (copied) return (copied);
- if (sk->err) return (-sk->err);
- if (!sk->done)
- {
- sk->done = 1;
- return (0);
- }
- return (-ENOTCONN);
+ release_sock (sk);
+ if (copied == 0) sk->done = 1;
+ return (copied);
}
-
- if (nonblock || ((flags & MSG_PEEK) && copied))
+
+ if (nonblock)
{
- sti();
release_sock (sk);
if (copied) return (copied);
return (-EAGAIN);
}
+ if ((flags & MSG_PEEK) && copied != 0)
+ {
+ release_sock (sk);
+ return (copied);
+ }
+
+ PRINTK ("tcp_read about to sleep. state = %d\n",sk->state);
+
+ release_sock (sk); /* now we may have some data waiting. */
+ cli();
+
if ( sk->rqueue == NULL ||
before (sk->copied_seq+1, sk->rqueue->next->h.th->seq))
{
@@ -1027,9 +1275,132 @@ tcp_read(volatile struct sock *sk, unsigned char *to,
cleanup_rbuf (sk);
release_sock (sk);
if (copied == 0 && nonblock) return (-EAGAIN);
+ PRINTK ("tcp_read returning %d\n", copied);
return (copied);
}
+
+/* sends a fin without closing the connection. Not called
+ at interrupt time. */
+
+void
+tcp_shutdown (volatile struct sock *sk, int how)
+{
+ /* we need to grab some memory, and put together a fin, and then
+ put it into the queue to be sent. */
+ struct sk_buff *buff;
+ struct tcp_header *t1,*th;
+ struct proto *prot;
+ int tmp;
+ struct device *dev=NULL;
+
+/* Written; Tim MacKenzie (tym@dibbler.cs.monash.edu.au) 4 Dec '92.
+ * Most of this is guesswork, so maybe it will work...
+ */
+
+ if (!(how & SEND_SHUTDOWN)) return;
+
+ /* clear out any half completed packets. */
+ if (sk->send_tmp)
+ tcp_send_partial(sk);
+
+ prot = (struct proto *)sk->prot;
+ th=(struct tcp_header *)&sk->dummy_th;
+ buff=prot->wmalloc(sk, MAX_RESET_SIZE,1, GFP_KERNEL);
+ if (buff == NULL) return;
+
+ sk->inuse = 1;
+
+ PRINTK("tcp_shutdown_send buff = %X\n", buff);
+ buff->mem_addr = buff;
+ buff->mem_len = MAX_RESET_SIZE;
+ buff->lock = 0;
+ buff->sk = sk;
+ buff->len = sizeof (*t1);
+
+ t1=(struct tcp_header *)(buff + 1);
+ /* put in the ip_header and routing stuff. */
+ tmp = prot->build_header (buff,sk->saddr, sk->daddr, &dev,
+ IPPROTO_TCP, sk->opt,
+ sizeof(struct tcp_header));
+ if (tmp < 0)
+ {
+ prot->wfree (sk,buff->mem_addr, buff->mem_len);
+ PRINTK ("Unable to build header for fin.\n");
+ release_sock(sk);
+ return;
+ }
+
+ t1 = (struct tcp_header *)((char *)t1 +tmp);
+ buff ->len += tmp;
+ buff->dev = dev;
+
+ memcpy (t1, th, sizeof (*t1));
+
+ t1->seq = net32(sk->send_seq);
+ sk->fin_seq = th->seq+1; /* Contains the one that needs to be acked */
+
+ sk->send_seq++;
+ buff->h.seq = sk->send_seq;
+ t1->ack = 1;
+
+ t1->ack_seq = net32(sk->acked_seq);
+ t1->window = net16(sk->prot->rspace(sk));
+ t1->fin = 1;
+ t1->rst = 0;
+
+ t1->doff = sizeof (*t1)/4;
+ tcp_send_check (t1, sk->saddr, sk->daddr, sizeof (*t1), sk);
+
+ /* can't just queue this up. It should go at the end of
+ the write queue. */
+ if (sk->wback != NULL)
+ {
+ buff->next = NULL;
+ sk->wback->next = buff;
+ sk->wback = buff;
+ buff->magic = TCP_WRITE_QUEUE_MAGIC;
+ }
+ else
+ {
+ sk->prot->queue_xmit (sk, dev, buff,0);
+ }
+
+ if (sk->state == TCP_ESTABLISHED)
+ {
+ sk->state = TCP_FIN_WAIT1;
+ }
+ else
+ {
+ sk->state = TCP_FIN_WAIT2;
+ }
+ release_sock(sk);
+}
+
+
+static int
+tcp_recvfrom (volatile struct sock *sk, unsigned char *to,
+ int to_len, int nonblock, unsigned flags,
+ struct sockaddr_in *addr, int *addr_len)
+{
+ int result = tcp_read(sk, to, to_len, nonblock, flags);
+ struct sockaddr_in sin;
+ int len;
+ if (result < 0)
+ return (result);
+ len = get_fs_long(addr_len);
+ if (len > sizeof (sin))
+ len = sizeof (sin);
+ sin.sin_family = AF_INET;
+ sin.sin_port = sk->dummy_th.dest;
+ sin.sin_addr.s_addr = sk->daddr;
+ verify_area (addr, len);
+ memcpy_tofs (addr, &sin, len);
+ verify_area (addr_len, sizeof (len));
+ put_fs_long (len, addr_len);
+ return (result);
+}
+
/* this routine will send a reset to the other tcp. */
static void
tcp_reset(unsigned long saddr, unsigned long daddr, struct tcp_header *th,
@@ -1046,6 +1417,7 @@ tcp_reset(unsigned long saddr, unsigned long daddr, struct tcp_header *th,
PRINTK("tcp_reset buff = %X\n", buff);
buff->mem_addr = buff;
buff->mem_len = MAX_RESET_SIZE;
+ buff->lock = 0;
buff->len = sizeof (*t1);
buff->sk = NULL;
buff->dev = dev;
@@ -1115,6 +1487,13 @@ tcp_conn_request(volatile struct sock *sk, struct sk_buff *skb,
return;
}
+ /* make sure we can accept more. This will prevent a flurry of
+ syns from eating up all our memory. */
+ if (sk->ack_backlog >= sk->max_ack_backlog)
+ {
+ kfree_skb (skb, FREE_READ);
+ return;
+ }
/* we need to build a new sock struct. */
/* It is sort of bad to have a socket without an inode attached to
@@ -1143,7 +1522,7 @@ tcp_conn_request(volatile struct sock *sk, struct sk_buff *skb,
newsk->intr = 0;
newsk->proc = 0;
newsk->done = 0;
-
+ newsk->send_tmp = NULL;
newsk->pair = NULL;
newsk->wmem_alloc = 0;
newsk->rmem_alloc = 0;
@@ -1190,7 +1569,7 @@ tcp_conn_request(volatile struct sock *sk, struct sk_buff *skb,
}
else
{
- ptr = (unsigned char *)(skb+1);
+ ptr = (unsigned char *)(skb->h.th + 1);
if (ptr[0] != 2 || ptr[1] != 4)
{
newsk->mtu=576-HEADER_SIZE;
@@ -1213,6 +1592,7 @@ tcp_conn_request(volatile struct sock *sk, struct sk_buff *skb,
return;
}
+ buff->lock = 0;
buff->mem_addr = buff;
buff->mem_len = MAX_SYN_SIZE;
buff->len=sizeof (struct tcp_header)+4;
@@ -1287,6 +1667,7 @@ tcp_conn_request(volatile struct sock *sk, struct sk_buff *skb,
sk->rqueue->prev = skb;
skb->prev->next = skb;
}
+ sk->ack_backlog++;
release_sock (newsk);
}
@@ -1326,36 +1707,47 @@ tcp_close (volatile struct sock *sk, int timeout)
}
sk->rqueue = NULL;
+ /* get rid on any half completed packets. */
+ if (sk->send_tmp)
+ {
+ tcp_send_partial (sk);
+ }
switch (sk->state)
{
- case TCP_FIN_WAIT1:
- case TCP_FIN_WAIT2:
- case TCP_LAST_ACK:
- if (timeout)
- tcp_time_wait(sk);
- release_sock (sk);
- if (!need_reset)
- return;
- break;
-
- case TCP_TIME_WAIT:
- if (timeout)
- sk->state = TCP_CLOSE;
- release_sock (sk);
- return;
- case TCP_LISTEN:
- sk->state = TCP_CLOSE;
- release_sock(sk);
- return;
+ case TCP_FIN_WAIT1:
+ case TCP_FIN_WAIT2:
+ case TCP_LAST_ACK:
+ /* start a timer. */
+ sk->time_wait.len = 4*sk->rtt;;
+ sk->timeout = TIME_CLOSE;
+ reset_timer ((struct timer *)&sk->time_wait);
+ if (timeout)
+ tcp_time_wait(sk);
+ release_sock (sk);
+ if (!need_reset)
+ return;
+ break;
+
+ case TCP_TIME_WAIT:
+ if (timeout)
+ sk->state = TCP_CLOSE;
+ release_sock (sk);
+ return;
+
+ case TCP_LISTEN:
+ sk->state = TCP_CLOSE;
+ release_sock(sk);
+ return;
- case TCP_CLOSE:
+ case TCP_CLOSE:
- release_sock(sk);
- return;
+ release_sock(sk);
+ return;
+ case TCP_CLOSE_WAIT:
case TCP_ESTABLISHED:
case TCP_SYN_SENT:
case TCP_SYN_RECV:
@@ -1363,17 +1755,19 @@ tcp_close (volatile struct sock *sk, int timeout)
prot = (struct proto *)sk->prot;
th=(struct tcp_header *)&sk->dummy_th;
- buff=prot->wmalloc(sk, MAX_FIN_SIZE,1, GFP_ATOMIC);
- if (buff == NULL)
- {
- /* this will force it to try again later. */
+ buff=prot->wmalloc(sk, MAX_FIN_SIZE,1, GFP_ATOMIC);
+ if (buff == NULL)
+ {
+ /* this will force it to try again later. */
+ if (sk->state != TCP_CLOSE_WAIT)
sk->state = TCP_ESTABLISHED;
- sk->timeout = TIME_CLOSE;
- sk->time_wait.len = 100; /* wait a second. */
- reset_timer ((struct timer *)&sk->time_wait);
- return;
- }
+ sk->timeout = TIME_CLOSE;
+ sk->time_wait.len = 100; /* wait a second. */
+ reset_timer ((struct timer *)&sk->time_wait);
+ return;
+ }
+ buff->lock = 0;
buff->mem_addr = buff;
buff->mem_len = MAX_FIN_SIZE;
buff->sk = sk;
@@ -1390,6 +1784,7 @@ tcp_close (volatile struct sock *sk, int timeout)
release_sock(sk);
return;
}
+
t1 = (struct tcp_header *)((char *)t1 +tmp);
buff ->len += tmp;
buff->dev = dev;
@@ -1398,6 +1793,7 @@ tcp_close (volatile struct sock *sk, int timeout)
sk->send_seq++;
buff->h.seq = sk->send_seq;
t1->ack = 1;
+
/* ack everything immediately from now on. */
sk->delay_acks = 0;
t1->ack_seq = net32(sk->acked_seq);
@@ -1426,9 +1822,18 @@ tcp_close (volatile struct sock *sk, int timeout)
sk->wback->next = buff;
}
sk->wback = buff;
+ buff->magic = TCP_WRITE_QUEUE_MAGIC;
}
- sk->state = TCP_FIN_WAIT1;
+
+ if (sk->state == TCP_CLOSE_WAIT)
+ {
+ sk->state = TCP_FIN_WAIT2;
+ }
+ else
+ {
+ sk->state = TCP_FIN_WAIT1;
+ }
}
release_sock (sk);
}
@@ -1440,6 +1845,7 @@ static void
tcp_write_xmit (volatile struct sock *sk)
{
struct sk_buff *skb;
+ PRINTK ("tcp_write_xmit (sk=%X)\n",sk);
while (sk->wfront != NULL && before (sk->wfront->h.seq, sk->window_seq) &&
sk->packets_out < sk->cong_window)
{
@@ -1447,6 +1853,17 @@ tcp_write_xmit (volatile struct sock *sk)
sk->wfront = skb->next;
if (sk->wfront == NULL)
sk->wback = NULL;
+ skb->next = NULL;
+ if (skb->magic != TCP_WRITE_QUEUE_MAGIC)
+ {
+ PRINTK ("tcp.c skb with bad magic (%X) on write queue. Squashing "
+ "queue\n", skb->magic);
+ sk->wfront = NULL;
+ sk->wback = NULL;
+ return;
+ }
+ skb->magic = 0;
+ PRINTK("Sending a packet.\n");
sk->prot->queue_xmit (sk, skb->dev, skb, skb->free);
}
}
@@ -1461,9 +1878,13 @@ tcp_ack (volatile struct sock *sk, struct tcp_header *th, unsigned long saddr)
unsigned long ack;
ack = net32(th->ack_seq);
- if (!between (ack , sk->rcv_ack_seq, sk->send_seq))
+ PRINTK ("tcp_ack ack=%d, window=%d, "
+ "sk->rcv_ack_seq=%d, sk->window_seq = %d\n",
+ ack, net16(th->window), sk->rcv_ack_seq, sk->window_seq);
+ if (after (ack, sk->send_seq+1) || before (ack, sk->rcv_ack_seq-1))
{
- if (after (ack, sk->send_seq) || sk->state != TCP_ESTABLISHED)
+ if (after (ack, sk->send_seq) || (sk->state != TCP_ESTABLISHED &&
+ sk->state != TCP_CLOSE_WAIT))
{
return (0);
}
@@ -1473,8 +1894,90 @@ tcp_ack (volatile struct sock *sk, struct tcp_header *th, unsigned long saddr)
return (1);
}
- sk->window_seq = ack + net16(th->window);
+ /* see if our window has been shrunk. */
+ if (after (sk->window_seq, ack+net16(th->window)))
+ {
+ /* we may need to move packets from the send queue to the
+ write queue. if the window has been shrunk on us. */
+ /* the rfc says you are not allowed to shrink your window like
+ this, but if the other end does, you must be able to deal
+ with it. */
+
+ struct sk_buff *skb;
+ struct sk_buff *skb2=NULL;
+ struct sk_buff *wskb=NULL;
+
+ sk->window_seq = ack + net16(th->window);
+ cli();
+ for (skb = sk->send_head; skb != NULL; skb=skb->link3)
+ {
+ if (after( skb->h.seq, sk->window_seq))
+ {
+
+ /* remove it from the send queue. */
+ if (skb2 == NULL)
+ {
+ sk->send_head = skb->link3;
+ }
+ else
+ {
+ skb2->link3 = skb->link3;
+ }
+ if (sk->send_tail == skb)
+ sk->send_tail = skb2;
+
+ /* we may need to remove this from the dev send list. */
+ if (skb->next != NULL)
+ {
+ int i;
+ if (skb->next != skb)
+ {
+ skb->next->prev = skb->prev;
+ skb->prev->next = skb->next;
+ }
+ for (i = 0; i < DEV_NUMBUFFS; i++)
+ {
+ if (skb->dev->buffs[i] == skb)
+ {
+ if (skb->next == skb)
+ skb->dev->buffs[i] = NULL;
+ else
+ skb->dev->buffs[i] = skb->next;
+ break;
+ }
+ }
+ if (arp_q == skb)
+ {
+ if (skb->next == skb)
+ arp_q = NULL;
+ else
+ arp_q = skb->next;
+ }
+ }
+
+ /* now add it to the write_queue. */
+ skb->magic = TCP_WRITE_QUEUE_MAGIC;
+ if (wskb == NULL)
+ {
+ skb->next = sk->wfront;
+ sk->wfront = skb;
+ }
+ else
+ {
+ skb->next = wskb->next;
+ wskb->next = skb;
+ }
+ wskb = skb;
+ }
+ else
+ {
+ skb2 = skb;
+ }
+ }
+ sti();
+ }
+ sk->window_seq = ack + net16(th->window);
/* we don't want too many packets out there. */
if (sk->cong_window < 2048 && ack != sk->rcv_ack_seq)
@@ -1485,6 +1988,7 @@ tcp_ack (volatile struct sock *sk, struct tcp_header *th, unsigned long saddr)
sk->cong_window++;
}
+ PRINTK ("tcp_ack: Updating rcv ack sequence. \n");
sk->rcv_ack_seq = ack;
/* see if we can take anything off of the retransmit queue. */
@@ -1495,7 +1999,14 @@ tcp_ack (volatile struct sock *sk, struct tcp_header *th, unsigned long saddr)
struct sk_buff *oskb;
/* we have one less packet out there. */
sk->packets_out --;
+ PRINTK ("skb=%X acked\n", sk->send_head);
+ /* wake up the process, it can probably
+ write more. */
+ if (!sk->dead)
+ wake_up (sk->sleep);
+
cli();
+
oskb = sk->send_head;
/* estimate the rtt. */
sk->rtt += ((jiffies - oskb->when) - sk->rtt)/2;
@@ -1508,24 +2019,32 @@ tcp_ack (volatile struct sock *sk, struct tcp_header *th, unsigned long saddr)
/* we may need to remove this from the dev send list. */
if (oskb->next != NULL)
{
+ int i;
if (oskb->next != oskb)
{
oskb->next->prev = oskb->prev;
oskb->prev->next = oskb->next;
}
- else
+ for (i = 0; i < DEV_NUMBUFFS; i++)
{
- int i;
- for (i = 0; i < DEV_NUMBUFFS; i++)
- {
- if (oskb->dev->buffs[i] == oskb)
- {
- oskb->dev->buffs[i] = NULL;
- break;
- }
- }
+ if (oskb->dev->buffs[i] == oskb)
+ {
+ if (oskb== oskb->next)
+ oskb->dev->buffs[i]= NULL;
+ else
+ oskb->dev->buffs[i] = oskb->next;
+ break;
+ }
+ }
+ if (arp_q == oskb)
+ {
+ if (oskb == oskb->next)
+ arp_q = NULL;
+ else
+ arp_q = oskb->next;
}
}
+ oskb->magic = 0;
kfree_skb (oskb, FREE_WRITE); /* write. */
sti();
if (!sk->dead)
@@ -1546,6 +2065,7 @@ tcp_ack (volatile struct sock *sk, struct tcp_header *th, unsigned long saddr)
if (sk->retransmits && sk->send_head != NULL)
{
+ PRINTK ("retransmitting\n");
sk->prot->retransmit (sk,1);
}
sk->retransmits = 0;
@@ -1562,9 +2082,16 @@ tcp_ack (volatile struct sock *sk, struct tcp_header *th, unsigned long saddr)
else
{
if (sk->send_head == NULL && sk->ack_backlog == 0 &&
- sk->state != TCP_TIME_WAIT)
+ sk->state != TCP_TIME_WAIT && !sk->keepopen)
{
- delete_timer((struct timer *)&sk->time_wait);
+ PRINTK ("Nothing to do, going to sleep.\n");
+ if (!sk->dead)
+ wake_up (sk->sleep);
+
+ /* Lets send a probe once in a while. */
+ sk->time_wait.len = TCP_PROBEWAIT_LEN;
+ sk->timeout = TIME_KEEPOPEN;
+ reset_timer((struct timer *)&sk->time_wait);
sk->timeout = 0;
}
else
@@ -1574,10 +2101,19 @@ tcp_ack (volatile struct sock *sk, struct tcp_header *th, unsigned long saddr)
sk->time_wait.len = TCP_TIMEWAIT_LEN;
sk->timeout = TIME_CLOSE;
}
+ sk->timeout = TIME_WRITE;
+ sk->time_wait.len = sk->rtt*2;
reset_timer ((struct timer *)&sk->time_wait);
}
}
+
+ if (sk->packets_out == 0 && sk->send_tmp != NULL &&
+ sk->wfront == NULL && sk->send_head == NULL)
+ {
+ tcp_send_partial (sk);
+ }
+
/* see if we are done. */
if ( sk->state == TCP_TIME_WAIT)
{
@@ -1587,13 +2123,7 @@ tcp_ack (volatile struct sock *sk, struct tcp_header *th, unsigned long saddr)
sk->state = TCP_CLOSE;
}
- if (sk->state == TCP_FIN_WAIT1)
- {
- if (sk->rcv_ack_seq == sk->send_seq)
- sk->state = TCP_FIN_WAIT2;
- }
-
- if (sk->state == TCP_LAST_ACK)
+ if (sk->state == TCP_LAST_ACK || sk->state == TCP_FIN_WAIT2)
{
if (sk->rcv_ack_seq == sk->send_seq)
{
@@ -1603,12 +2133,15 @@ tcp_ack (volatile struct sock *sk, struct tcp_header *th, unsigned long saddr)
}
else
{
+ tcp_send_ack (sk->send_seq, sk->acked_seq, sk, th, sk->daddr);
sk->state = TCP_CLOSE;
}
}
if (!sk->dead) wake_up (sk->sleep);
}
+ PRINTK ("leaving tcp_ack\n");
+
return (1);
}
@@ -1647,10 +2180,12 @@ tcp_data (struct sk_buff *skb, volatile struct sock *sk,
sk->acked_seq = th->seq + skb->len + th->syn + th->fin;
tcp_send_ack (sk->send_seq, sk->acked_seq, sk, skb->h.th, saddr);
kfree_skb (skb, FREE_READ);
- if (sk->state == TCP_TIME_WAIT && sk->acked_seq == sk->fin_seq)
+ if (sk->acked_seq == sk->fin_seq)
{
if (!sk->dead) wake_up (sk->sleep);
- sk->state = TCP_CLOSE;
+ if (sk->state == TCP_TIME_WAIT || sk->state == TCP_LAST_ACK
+ || sk->state == TCP_FIN_WAIT2)
+ sk->state = TCP_CLOSE;
}
return (0);
}
@@ -1715,7 +2250,7 @@ tcp_data (struct sk_buff *skb, volatile struct sock *sk,
if (before (sk->acked_seq, sk->copied_seq))
{
- printk ("*** tcp.c:tcp_data bug acked < copied\n");
+ PRINTK ("*** tcp.c:tcp_data bug acked < copied\n");
sk->acked_seq = sk->copied_seq;
}
@@ -1724,20 +2259,37 @@ tcp_data (struct sk_buff *skb, volatile struct sock *sk,
{
if (before (th->seq, sk->acked_seq+1))
{
- sk->acked_seq = th->ack_seq;
+ if (after (th->ack_seq, sk->acked_seq))
+ sk->acked_seq = th->ack_seq;
skb->acked = 1;
+
+ /* when we ack the fin, we turn on the RCV_SHUTDOWN flag. */
+ if (skb->h.th->fin)
+ {
+ sk->shutdown |= RCV_SHUTDOWN;
+ }
for (skb2=skb->next; skb2 != sk->rqueue->next; skb2=skb2->next)
{
if (before(skb2->h.th->seq, sk->acked_seq+1))
{
- sk->acked_seq = skb2->h.th->ack_seq;
+ if (after (skb2->h.th->ack_seq, sk->acked_seq))
+ sk->acked_seq = skb2->h.th->ack_seq;
skb2->acked = 1;
+
+ /* when we ack the fin, we turn on the RCV_SHUTDOWN flag. */
+ if (skb2->h.th->fin)
+ {
+ sk->shutdown |= RCV_SHUTDOWN;
+ }
+
/* force an immediate ack. */
sk->ack_backlog = sk->max_ack_backlog;
}
else
- break;
+ {
+ break;
+ }
}
/* this also takes care of updating the window. */
@@ -1745,7 +2297,6 @@ tcp_data (struct sk_buff *skb, volatile struct sock *sk,
if (!sk->delay_acks ||
sk->ack_backlog >= sk->max_ack_backlog ||
- sk->window < 2*sk->mtu + sk->bytes_rcv ||
sk->bytes_rcv > sk->max_unacked ||
th->fin)
{
@@ -1776,9 +2327,10 @@ tcp_data (struct sk_buff *skb, volatile struct sock *sk,
PRINTK ("data received on dead socket. \n");
}
- if (sk->state > TCP_CLOSING && sk->acked_seq == sk->fin_seq)
+ if (sk->state == TCP_FIN_WAIT2 && sk->acked_seq == sk->fin_seq)
{
- sk->state = TCP_CLOSE;
+ tcp_send_ack (sk->send_seq, sk->acked_seq, sk, th, saddr);
+ sk->state = TCP_LAST_ACK;
}
return (0);
@@ -1824,9 +2376,6 @@ static int
tcp_fin (volatile struct sock *sk, struct tcp_header *th,
unsigned long saddr, struct device *dev)
{
- struct sk_buff *buff;
- struct tcp_header *t1;
- int tmp;
PRINTK ("tcp_fin (sk=%X, th=%X, saddr=%X, dev=%X)\n",
sk, th, saddr, dev);
@@ -1835,20 +2384,23 @@ tcp_fin (volatile struct sock *sk, struct tcp_header *th,
wake_up (sk->sleep);
}
- /* after sending the fin, we aren't allowed to write anymore. */
- sk->shutdown |= SEND_SHUTDOWN;
-
sk->err = 0;
switch (sk->state)
{
case TCP_SYN_RECV:
case TCP_SYN_SENT:
case TCP_ESTABLISHED:
- sk->state = TCP_LAST_ACK;
+ sk->state = TCP_CLOSE_WAIT;
break;
- default:
+ case TCP_CLOSE_WAIT:
+ break; /* we got a retransmit of the fin. */
+
case TCP_FIN_WAIT1:
+ sk->state = TCP_FIN_WAIT2;
+ break;
+
+ default:
case TCP_TIME_WAIT:
sk->state = TCP_LAST_ACK;
/* start the timers. */
@@ -1861,8 +2413,12 @@ tcp_fin (volatile struct sock *sk, struct tcp_header *th,
sk->state = TCP_CLOSE;
return (0);
}
+ /* there is no longer any reason to do this. Just let tcp_data
+ deal with it. */
+ sk->ack_backlog ++;
- /* send an ack and our own fin. */
+#if 0
+ /* send an ack */
buff=sk->prot->wmalloc(sk,MAX_ACK_SIZE,1, GFP_ATOMIC);
if (buff == NULL)
{
@@ -1895,10 +2451,10 @@ tcp_fin (volatile struct sock *sk, struct tcp_header *th,
t1->source = th->dest;
- t1->seq = net32(sk->send_seq++);
+ t1->seq = net32(sk->send_seq);
/* contains the one that needs to be acked. */
- sk->fin_seq = th->seq+1;
+ /* sk->fin_seq = th->seq+1;*/
buff->h.seq = sk->send_seq;
t1->window = net16(sk->prot->rspace(sk));
@@ -1910,7 +2466,7 @@ tcp_fin (volatile struct sock *sk, struct tcp_header *th,
t1->syn = 0;
t1->psh = 0;
t1->ack = 1;
- t1->fin = 1;
+ t1->fin = 0;
t1->ack_seq = net32(sk->acked_seq);
t1->doff = sizeof (*t1)/4;
@@ -1923,12 +2479,13 @@ tcp_fin (volatile struct sock *sk, struct tcp_header *th,
buff->next = NULL;
sk->wback->next = buff;
sk->wback = buff;
+ buff->magic = TCP_WRITE_QUEUE_MAGIC;
}
else
{
sk->prot->queue_xmit (sk, dev, buff,0);
}
-
+#endif
return (0);
}
@@ -1982,6 +2539,7 @@ tcp_accept (volatile struct sock *sk, int flags)
newsk = skb->sk;
kfree_skb (skb, FREE_READ);
+ sk->ack_backlog--;
release_sock (sk);
return (newsk);
}
@@ -2018,6 +2576,7 @@ tcp_connect (volatile struct sock *sk, struct sockaddr_in *usin, int addr_len)
return (-ENOMEM);
}
sk->inuse = 1;
+ buff->lock = 0;
buff->mem_addr = buff;
buff->mem_len = MAX_SYN_SIZE;
buff->len=24;
@@ -2085,13 +2644,20 @@ tcp_sequence (volatile struct sock *sk, struct tcp_header *th, short len,
slightly more packets than we should, but it should not cause
problems unless someone is trying to forge packets. */
+ PRINTK ("tcp_sequence (sk=%X, th=%X, len = %d, opt=%d, saddr=%X)\n",
+ sk, th, len, opt, saddr);
+
if (between(th->seq, sk->acked_seq, sk->acked_seq + sk->window)||
- between(th->seq + len-sizeof (*th), sk->acked_seq+1,
- sk->acked_seq + sk->window))
+ between(th->seq + len-sizeof (*th), sk->acked_seq,
+ sk->acked_seq + sk->window) ||
+ (before (th->seq, sk->acked_seq) &&
+ after (th->seq + len - sizeof (*th), sk->acked_seq + sk->window)))
{
return (1);
}
+ PRINTK ("tcp_sequence: rejecting packet. \n");
+
/* if it's too far ahead, send an ack to let the other end
know what we expect. */
if (after (th->seq, sk->acked_seq + sk->window))
@@ -2100,20 +2666,16 @@ tcp_sequence (volatile struct sock *sk, struct tcp_header *th, short len,
return (0);
}
+ /* in case it's just a late ack, let it through */
+ if (th->ack && len == th->doff*4 && after (th->seq, sk->acked_seq - 32767) &&
+ !th->fin && !th->syn) return (1);
+
if (!th->rst)
{
- if (len != th->doff*4 || th->fin || th->syn)
- {
- sk->delay_acks = 0;
- }
-
/* try to resync things. */
tcp_send_ack (net32(th->ack_seq), sk->acked_seq, sk, th, saddr);
}
- /* in case it's just a late ack, let it through */
- if (th->ack && len == th->doff*4 && after (th->seq, sk->acked_seq - 4096) &&
- !th->fin && !th->syn) return (1);
return (0);
}
@@ -2142,24 +2704,24 @@ tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
if (!skb)
{
- printk ("tcp.c: tcp_rcv skb = NULL\n");
+ PRINTK ("tcp.c: tcp_rcv skb = NULL\n");
return (0);
}
#if 0 /* it's ok for protocol to be NULL */
if (!protocol)
{
- printk ("tcp.c: tcp_rcv protocol = NULL\n");
+ PRINTK ("tcp.c: tcp_rcv protocol = NULL\n");
return (0);
}
if (!opt) /* it's ok for opt to be NULL */
{
- printk ("tcp.c: tcp_rcv opt = NULL\n");
+ PRINTK ("tcp.c: tcp_rcv opt = NULL\n");
}
#endif
if (!dev)
{
- printk ("tcp.c: tcp_rcv dev = NULL\n");
+ PRINTK ("tcp.c: tcp_rcv dev = NULL\n");
return (0);
}
@@ -2237,14 +2799,14 @@ tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
{
if (!sk)
{
- printk ("tcp.c: tcp_rcv bug sk=NULL redo = 1\n");
+ PRINTK ("tcp.c: tcp_rcv bug sk=NULL redo = 1\n");
return (0);
}
}
if (!sk->prot)
{
- printk ("tcp.c: tcp_rcv sk->prot = NULL \n");
+ PRINTK ("tcp.c: tcp_rcv sk->prot = NULL \n");
return (0);
}
@@ -2283,6 +2845,7 @@ tcp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
}
case TCP_ESTABLISHED:
+ case TCP_CLOSE_WAIT:
case TCP_FIN_WAIT1:
case TCP_FIN_WAIT2:
case TCP_TIME_WAIT:
@@ -2569,12 +3132,13 @@ tcp_write_wakeup(volatile struct sock *sk)
struct tcp_header *t1;
struct device *dev=NULL;
int tmp;
- if (sk -> state != TCP_ESTABLISHED) return;
+ if (sk -> state != TCP_ESTABLISHED && sk->state != TCP_CLOSE_WAIT) return;
buff=sk->prot->wmalloc(sk,MAX_ACK_SIZE,1, GFP_ATOMIC);
/* no big loss. */
if (buff == NULL) return;
+ buff->lock = 0;
buff->mem_addr = buff;
buff->mem_len = MAX_ACK_SIZE;
buff->len=sizeof (struct tcp_header);
@@ -2629,8 +3193,8 @@ struct proto tcp_prot =
tcp_close,
tcp_read,
tcp_write,
- NULL,
- NULL,
+ tcp_sendto,
+ tcp_recvfrom,
ip_build_header,
tcp_connect,
tcp_accept,
@@ -2642,6 +3206,7 @@ struct proto tcp_prot =
tcp_select,
tcp_ioctl,
NULL,
+ tcp_shutdown,
128,
0,
{NULL,}
diff --git a/net/tcp/tcp.h b/net/tcp/tcp.h
index e6609af..8401aea 100644
--- a/net/tcp/tcp.h
+++ b/net/tcp/tcp.h
@@ -19,17 +19,31 @@
The Author may be reached as bir7@leland.stanford.edu or
C/O Department of Mathematics; Stanford University; Stanford, CA 94305
*/
-/* $Id: tcp.h,v 0.8.4.1 1992/11/10 00:17:18 bir7 Exp $ */
+/* $Id: tcp.h,v 0.8.4.6 1992/12/12 19:25:04 bir7 Exp $ */
/* $Log: tcp.h,v $
+ * Revision 0.8.4.6 1992/12/12 19:25:04 bir7
+ * Fixed anti-memory Leak in shutdown.
+ *
+ * Revision 0.8.4.5 1992/12/12 01:50:49 bir7
+ * Fixed several bugs including half-duplex connections.
+ *
+ * Revision 0.8.4.4 1992/12/08 20:49:15 bir7
+ * Fixed minor bugs and checked out MSS.
+ *
+ * Revision 0.8.4.3 1992/12/06 23:29:59 bir7
+ * Added support for mss and half completed packets. Also added
+ * support for shrinking windows.
+ *
+ * Revision 0.8.4.2 1992/12/03 19:54:12 bir7
+ * Added paranoid queue checking.
+ *
* Revision 0.8.4.1 1992/11/10 00:17:18 bir7
* version change only.
*
* Revision 0.8.3.2 1992/11/10 00:14:47 bir7
- * Changed malloc to kmalloc and added $iId$ and $Log: tcp.h,v $
- * Revision 0.8.4.1 1992/11/10 00:17:18 bir7
- * version change only.
- *.
- * */
+ * Changed malloc to kmalloc and added Id and Log
+ *
+ */
#ifndef _TCP_TCP_H
#define _TCP_TCP_H
@@ -51,12 +65,15 @@ enum {
TCP_ESTABLISHED=1,
TCP_SYN_SENT,
TCP_SYN_RECV,
+#if 0
TCP_CLOSING, /* not a valid state, just a seperator so we can use
< tcp_closing or > tcp_closing for checks. */
+#endif
TCP_FIN_WAIT1,
TCP_FIN_WAIT2,
TCP_TIME_WAIT,
TCP_CLOSE,
+ TCP_CLOSE_WAIT,
TCP_LAST_ACK,
TCP_LISTEN
};
@@ -67,7 +84,7 @@ enum {
#define MAX_RESET_SIZE 40 + sizeof (struct sk_buff) + MAX_HEADER
#define MAX_WINDOW 12000
#define MIN_WINDOW 2048
-#define MAX_ACK_BACKLOG 2
+#define MAX_ACK_BACKLOG 8
#define MIN_WRITE_SPACE 2048
#define TCP_WINDOW_DIFF 2048
@@ -90,13 +107,16 @@ enum {
#define TCP_CONNECT_TIME 200 /* time to retransmit first syn. */
#define TCP_SYN_RETRIES 30 /* number of times to retry openning a connection.
*/
+#define TCP_PROBEWAIT_LEN 250 /* time to wait between probes when I've got
+ something to write and there is no window. */
#define TCP_NO_CHECK 0 /* turn to one if you want the default to be no
checksum . */
void print_th (struct tcp_header *);
-#define HEADER_SIZE 100
+#define HEADER_SIZE 64 /* Maximum header size we need to deal with. */
+#define TCP_WRITE_QUEUE_MAGIC 0xa5f23477
/* this next routines deal with comparing 32 bit unsigned ints and
worry about wrap around. The general strategy is to do a normal
@@ -142,4 +162,11 @@ void print_th (struct tcp_header *);
return (after (seq1+1, seq2) && before (seq1, seq3+1));
}
+static inline const int
+tcp_connected (const int state)
+{
+ return (state == TCP_ESTABLISHED || state == TCP_CLOSE_WAIT ||
+ state == TCP_FIN_WAIT1 || state == TCP_FIN_WAIT2);
+}
+
#endif
diff --git a/net/tcp/timer.c b/net/tcp/timer.c
index 377d30d..37a829f 100644
--- a/net/tcp/timer.c
+++ b/net/tcp/timer.c
@@ -20,8 +20,17 @@
C/O Department of Mathematics; Stanford University; Stanford, CA 94305
*/
-/* $Id: timer.c,v 0.8.4.2 1992/11/10 10:38:48 bir7 Exp $ */
+/* $Id: timer.c,v 0.8.4.5 1992/12/12 19:25:04 bir7 Exp $ */
/* $Log: timer.c,v $
+ * Revision 0.8.4.5 1992/12/12 19:25:04 bir7
+ * cleaned up Log messages.
+ *
+ * Revision 0.8.4.4 1992/12/12 01:50:49 bir7
+ * Fixed timeouts.
+ *
+ * Revision 0.8.4.3 1992/12/06 23:29:59 bir7
+ * Fixed bugs in timeout.
+ *
* Revision 0.8.4.2 1992/11/10 10:38:48 bir7
* Change free_s to kfree_s and accidently changed free_skb to kfree_skb.
*
@@ -29,7 +38,7 @@
* version change only.
*
* Revision 0.8.3.2 1992/11/10 00:14:47 bir7
- * Changed malloc to kmalloc and added $iId$ and
+ * Changed malloc to kmalloc and added Id and Log
* */
#include <linux/types.h>
@@ -45,7 +54,19 @@
#include "tcp.h"
#include "sock.h"
#include "arp.h"
-#include "../kern_sock.h"
+
+#undef TIMER_DEBUG
+
+#ifdef PRINTK
+#undef PRINTK
+#endif
+
+
+#ifdef TIMER_DEBUG
+#define PRINTK printk
+#else
+#define PRINTK dummy_routine
+#endif
static struct timer *timer_base=NULL;
unsigned long seq_offset;
@@ -55,7 +76,7 @@ delete_timer (struct timer *t)
{
struct timer *tm;
PRINTK ("delete_timer (t=%X)\n",t);
- if (timer_base == NULL) return;
+ if (timer_base == NULL || t == NULL) return;
cli();
if (t == timer_base)
{
@@ -150,9 +171,10 @@ net_timer (void)
}
sk->inuse = 1;
sti();
- PRINTK ("net_timer: found sk=%X\n",sk);
why = sk->timeout;
+ PRINTK ("net_timer: found sk=%X why = %d\n",sk, why);
+
if (sk->keepopen)
{
sk->time_wait.len = TCP_TIMEOUT_LEN;
@@ -212,17 +234,20 @@ net_timer (void)
case TIME_WRITE: /* try to retransmit. */
if (sk->send_head != NULL)
{
- sk->retransmits ++;
+ PRINTK ("retransmitting.\n");
+ sk->prot->retransmit (sk, 0);
+
if (sk->retransmits > TCP_RETR1)
{
- arp_destroy (sk->daddr);
- ip_route_check (sk->daddr);
+ PRINTK ("timer.c TIME_WRITE time-out 1\n");
+ arp_destroy (sk->daddr);
+ ip_route_check (sk->daddr);
}
if (sk->retransmits > TCP_RETR2)
{
+ PRINTK ("timer.c TIME_WRITE time-out 2\n");
sk->err = ETIMEDOUT;
- arp_destroy (sk->daddr);
if (sk->state == TCP_FIN_WAIT1 ||
sk->state == TCP_FIN_WAIT2 ||
sk->state == TCP_LAST_ACK)
@@ -240,16 +265,13 @@ net_timer (void)
break;
}
}
- else /* sk->retransmites .. */
- {
- sk->prot->retransmit (sk, 1);
- release_sock (sk);
- }
+ release_sock (sk);
break;
}
+
/* if we have stuff which hasn't been written because the
window is too small, fall throught to TIME_KEEPOPEN */
- if (sk->wfront == NULL)
+ if (sk->wfront == NULL && sk->send_tmp == NULL)
{
release_sock (sk);
break;
@@ -257,22 +279,36 @@ net_timer (void)
/* this basically assumes tcp here. */
/* exponential fall back. */
+ /* The rtt should quickly get back to normal once
+ we start sending packets again. */
+
sk->rtt *= 2;
- sk->time_wait.len = sk->rtt*2;
+ sk->time_wait.len = sk->rtt;
sk->timeout = TIME_WRITE;
+ if (sk->prot->write_wakeup != NULL)
+ sk->prot->write_wakeup(sk);
+
reset_timer ((struct timer *)&sk->time_wait);
+ release_sock (sk);
+ break;
case TIME_KEEPOPEN: /* send something to keep the
connection open. */
+
+ if (sk->prot->write_wakeup != NULL)
+ sk->prot->write_wakeup(sk);
sk->retransmits ++;
if (sk->retransmits > TCP_RETR1)
{
- arp_destroy (sk->daddr);
- ip_route_check (sk->daddr);
-
+ PRINTK ("timer.c TIME_KEEPOPEN time-out 1\n");
+ arp_destroy (sk->daddr);
+ ip_route_check (sk->daddr);
+ release_sock (sk);
+ break;
}
if (sk->retransmits > TCP_RETR2)
{
+ PRINTK ("timer.c TIME_KEEPOPEN time-out 2\n");
arp_destroy (sk->daddr);
sk->err = ETIMEDOUT;
if (sk->state == TCP_FIN_WAIT1 ||
@@ -289,13 +325,8 @@ net_timer (void)
}
break;
}
- else /* sk->retransmits. */
- {
- if (sk->prot->write_wakeup != NULL)
- sk->prot->write_wakeup(sk);
- release_sock (sk);
- break;
- }
+ release_sock (sk);
+ break;
default:
release_sock(sk);
diff --git a/net/tcp/udp.c b/net/tcp/udp.c
index d5c0fb0..0451a07 100644
--- a/net/tcp/udp.c
+++ b/net/tcp/udp.c
@@ -19,14 +19,23 @@
The Author may be reached as bir7@leland.stanford.edu or
C/O Department of Mathematics; Stanford University; Stanford, CA 94305
*/
-/* $Id: udp.c,v 0.8.4.5 1992/11/18 15:38:03 bir7 Exp $ */
+/* $Id: udp.c,v 0.8.4.9 1992/12/12 19:25:04 bir7 Exp $ */
/* $Log: udp.c,v $
+ * Revision 0.8.4.9 1992/12/12 19:25:04 bir7
+ * cleaned up Log messages.
+ *
+ * Revision 0.8.4.8 1992/12/12 01:50:49 bir7
+ * Changed connect.
+ *
+ * Revision 0.8.4.7 1992/12/05 21:35:53 bir7
+ * Added more debuggin code.
+ *
+ * Revision 0.8.4.6 1992/12/03 19:52:20 bir7
+ * fixed problems in udp_error.
+ *
* Revision 0.8.4.5 1992/11/18 15:38:03 bir7
* fixed minor problem in waiting for memory.
*
- * Revision 0.8.4.4 1992/11/17 14:19:47 bir7
- * *** empty log message ***
- *
* Revision 0.8.4.3 1992/11/15 14:55:30 bir7
* Fixed ctrl-h and added NULL checking to print_uh
*
@@ -37,7 +46,7 @@
* version change only.
*
* Revision 0.8.3.5 1992/11/10 00:14:47 bir7
- * Changed malloc to kmalloc and added $iId$ and
+ * Changed malloc to kmalloc and added Id and Log
* */
#include <linux/types.h>
@@ -59,8 +68,22 @@
#include "udp.h"
#include "icmp.h"
+#undef UDP_DEBUG
+
+#ifdef PRINTK
+#undef PRINTK
+#endif
+
+#ifdef UDP_DEBUG
+#define PRINTK printk
+#else
+#define PRINTK dummy_routine
+#endif
+
#define min(a,b) ((a)<(b)?(a):(b))
+
+
static void
print_uh(struct udp_header *uh)
{
@@ -112,10 +135,12 @@ void
udp_err (int err, unsigned char *header, unsigned long daddr,
unsigned long saddr, struct ip_protocol *protocol)
{
- struct tcp_header *th;
+ struct udp_header *th;
volatile struct sock *sk;
- th = (struct tcp_header *)header;
+ PRINTK ("udp_err (err=%d, header=%X, daddr=%X, saddr=%X, ip_protocl=%X)\n");
+
+ th = (struct udp_header *)header;
sk = get_sock (&udp_prot, net16(th->dest), saddr, th->source, daddr);
if (sk == NULL) return;
@@ -127,7 +152,8 @@ udp_err (int err, unsigned char *header, unsigned long daddr,
}
sk->err = icmp_err_convert[err & 0xff].errno;
- if (icmp_err_convert[err & 0xff].fatal)
+ /* it's only fatal if we have connected to them. */
+ if (icmp_err_convert[err & 0xff].fatal && sk->state == TCP_ESTABLISHED)
{
sk->prot->close(sk, 0);
}
@@ -237,7 +263,7 @@ udp_loopback (volatile struct sock *sk, unsigned short port,
/* if we didn't get the memory, just drop the packet. */
if (skb == NULL) return (len);
-
+ skb->lock = 0;
skb->mem_addr = skb;
skb->mem_len = sizeof (*skb) + len + sizeof (*uh) + 4;
@@ -369,6 +395,7 @@ udp_sendto (volatile struct sock *sk, unsigned char *from, int len,
continue;
}
+ skb->lock = 0;
skb->mem_addr = skb;
skb->mem_len = len + sizeof (*skb) + sk->prot->max_header;
skb->sk = sk;
@@ -405,6 +432,12 @@ udp_sendto (volatile struct sock *sk, unsigned char *from, int len,
amt -= sizeof (*uh);
buff += sizeof (*uh);
+ if (amt < 0)
+ {
+ printk ("udp.c: amt = %d < 0\n",amt);
+ release_sock (sk);
+ return (copied);
+ }
/* verify_area (from, amt);*/
memcpy_fromfs( buff, from, amt);
@@ -502,7 +535,12 @@ udp_recvfrom (volatile struct sock *sk, unsigned char *to, int len,
sk->inuse = 1;
while (sk->rqueue == NULL)
{
- if (noblock)
+ if (sk->shutdown & RCV_SHUTDOWN)
+ {
+ return (0);
+ }
+
+ if (noblock)
{
release_sock (sk);
return (-EAGAIN);
@@ -610,7 +648,8 @@ udp_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
/* if we don't know about the socket, forget about it. */
if (sk == NULL)
{
- if ((daddr & 0xff000000 != 0) && (daddr & 0xff000000 != 0xff000000))
+ if ((daddr & 0xff000000 != 0) &&
+ (daddr & 0xff000000 != 0xff000000))
{
icmp_reply (skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, dev);
}
@@ -727,6 +766,7 @@ struct proto udp_prot =
udp_select,
udp_ioctl,
NULL,
+ NULL,
128,
0,
{NULL,}
diff --git a/net/tcp/we.c b/net/tcp/we.c
index e5fe880..28b30ef 100644
--- a/net/tcp/we.c
+++ b/net/tcp/we.c
@@ -44,8 +44,23 @@
/* Note: My driver was full of bugs. Basically if it works, credit
Bob Harris. If it's broken blame me. -RAB */
-/* $Id: we.c,v 0.8.4.3 1992/11/15 14:55:30 bir7 Exp $ */
+/* $Id: we.c,v 0.8.4.8 1992/12/12 19:25:04 bir7 Exp $ */
/* $Log: we.c,v $
+ * Revision 0.8.4.8 1992/12/12 19:25:04 bir7
+ * cleaned up Log messages.
+ *
+ * Revision 0.8.4.7 1992/12/12 01:50:49 bir7
+ * made ring buffer volatile.
+ *
+ * Revision 0.8.4.6 1992/12/06 11:31:47 bir7
+ * Added missing braces in if statement.
+ *
+ * Revision 0.8.4.5 1992/12/05 21:35:53 bir7
+ * Added check for bad hardware returning runt packets.
+ *
+ * Revision 0.8.4.4 1992/12/03 19:52:20 bir7
+ * Added better queue checking.
+ *
* Revision 0.8.4.3 1992/11/15 14:55:30 bir7
* Put more checking in start_xmit to make sure packet doesn't disapear
* out from under us.
@@ -57,7 +72,7 @@
* version change only.
*
* Revision 0.8.3.4 1992/11/10 00:14:47 bir7
- * Changed malloc to kmalloc and added $iId$ and Log
+ * Changed malloc to kmalloc and added Id and Log
* */
#include <linux/config.h>
@@ -190,12 +205,18 @@ wd8003_open(struct device *dev)
/* This routine just calls the ether rcv_int. */
static int
-wdget(struct wd_ring *ring, struct device *dev)
+wdget(volatile struct wd_ring *ring, struct device *dev)
{
unsigned char *fptr;
- unsigned long len;
+ long len;
fptr = (unsigned char *)(ring +1);
+ /* some people have bugs in their hardware which let
+ ring->count be 0. It shouldn't happen, but we
+ should check for it. */
len = ring->count-4;
+ if (len < 56)
+ printk ("we.c: Hardware problem, runt packet. ring->count = %d\n",
+ ring->count);
return (dev_rint(fptr, len, 0, dev));
}
@@ -242,6 +263,7 @@ wd8003_start_xmit(struct sk_buff *skb, struct device *dev)
{
arp_queue (skb);
}
+ cli (); /* arp_queue turns them back on. */
status &= ~TRS_BUSY;
sti();
return (0);
@@ -347,7 +369,7 @@ wd_rcv( struct device *dev )
unsigned char bnd; /* Last packet page end */
unsigned char cur; /* Future packet page start */
unsigned char cmd; /* Command register save */
- struct wd_ring *ring;
+ volatile struct wd_ring *ring;
int done=0;
/* Calculate next packet location */
@@ -362,7 +384,7 @@ wd_rcv( struct device *dev )
{
/* Position pointer to packet in card ring buffer */
- ring = (struct wd_ring *) (dev->mem_start + (pkt << 8));
+ ring = (volatile struct wd_ring *) (dev->mem_start + (pkt << 8));
/* Ensure a valid packet */
if( ring->status & 1 )
@@ -578,8 +600,10 @@ wd8003_interrupt(int reg_ptr)
printk("\nwd8013 - network cable open!");
}
if (errors & FU )
- stats.tx_fifo_errors++;
- printk("\nwd8013 - TX FIFO underrun!");
+ {
+ stats.tx_fifo_errors++;
+ printk("\nwd8013 - TX FIFO underrun!");
+ }
/* Cannot do anymore - empty the bit bucket */
tx_aborted = 1;
@@ -620,7 +644,7 @@ static struct sigaction wd8003_sigaction =
NULL
};
-void
+int
wd8003_init(struct device *dev)
{
unsigned char csum;
@@ -636,7 +660,7 @@ wd8003_init(struct device *dev)
/* make sure no one can attempt to open the device. */
status = OPEN;
- return;
+ return (1);
}
printk("wd8013");
/* initialize the rest of the device structure. */
@@ -715,5 +739,7 @@ wd8003_init(struct device *dev)
if (irqaction (dev->irq, &wd8003_sigaction))
{
printk ("Unable to get IRQ%d for wd8013 board\n", dev->irq);
+ return (1);
}
+ return (0);
}
diff --git a/net/unix.c b/net/unix.c
index 2489423..1257542 100644
--- a/net/unix.c
+++ b/net/unix.c
@@ -112,7 +112,7 @@ sockaddr_un_printk(struct sockaddr_un *sockun, int sockaddr_len)
sockaddr_len -= UN_PATH_OFFSET;
if (sockun->sun_family != AF_UNIX)
printk("sockaddr_un: <BAD FAMILY: %d>\n", sockun->sun_family);
- else if (sockaddr_len <= 0 || sockaddr_len >= sizeof(buf)-1)
+ else if (sockaddr_len <= 0 || sockaddr_len >= sizeof(buf))
printk("sockaddr_un: <BAD LENGTH: %d>\n", sockaddr_len);
else {
memcpy(buf, sockun->sun_path, sockaddr_len);
@@ -192,6 +192,7 @@ unix_data_lookup(struct sockaddr_un *sockun, int sockaddr_len)
for (upd = unix_datas; upd <= last_unix_data; ++upd) {
if (upd->refcnt && upd->socket &&
+ upd->socket->state == SS_UNCONNECTED &&
upd->sockaddr_len == sockaddr_len &&
memcmp(&upd->sockaddr_un, sockun, sockaddr_len) == 0)
return upd;
@@ -380,11 +381,19 @@ unix_proto_connect(struct socket *sock, struct sockaddr *uservaddr,
PRINTK("unix_proto_connect: socket 0x%x, servlen=%d\n", sock,
sockaddr_len);
+
if (sockaddr_len <= UN_PATH_OFFSET ||
sockaddr_len > sizeof(struct sockaddr_un)) {
PRINTK("unix_proto_connect: bad length %d\n", sockaddr_len);
return -EINVAL;
}
+
+ if (sock->state == SS_CONNECTING)
+ return (-EINPROGRESS);
+
+ if (sock->state == SS_CONNECTED)
+ return (-EISCONN);
+
verify_area(uservaddr, sockaddr_len);
memcpy_fromfs(&sockun, uservaddr, sockaddr_len);
if (sockun.sun_family != AF_UNIX) {
@@ -461,6 +470,10 @@ unix_proto_accept(struct socket *sock, struct socket *newsock, int flags)
wake_up(clientsock->wait);
unix_data_ref (UN_DATA(newsock->conn));
UN_DATA(newsock)->peerupd = UN_DATA(newsock->conn);
+ UN_DATA(newsock)->sockaddr_un = UN_DATA(sock)->sockaddr_un;
+ UN_DATA(newsock)->sockaddr_len = UN_DATA(sock)->sockaddr_len;
+ UN_DATA(newsock->conn)->sockaddr_un = UN_DATA(sock)->sockaddr_un;
+ UN_DATA(newsock->conn)->sockaddr_len = UN_DATA(sock)->sockaddr_len;
return 0;
}
diff --git a/tools/version.h b/tools/version.h
index 6ff3194..15e45b1 100644
--- a/tools/version.h
+++ b/tools/version.h
@@ -1,5 +1,5 @@
-#define UTS_RELEASE "0.98.pl6-40"
-#define UTS_VERSION "12/02/92"
-#define LINUX_COMPILE_TIME "18:49:15"
+#define UTS_RELEASE "0.99-44"
+#define UTS_VERSION "12/11/92"
+#define LINUX_COMPILE_TIME "23:05:18"
#define LINUX_COMPILE_BY "root"
#define LINUX_COMPILE_HOST "home"