aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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"