diff -u --recursive --new-file v1.3.28/linux/Documentation/devices.tex linux/Documentation/devices.tex
--- v1.3.28/linux/Documentation/devices.tex	Wed Sep 13 12:45:28 1995
+++ linux/Documentation/devices.tex	Fri Sep 22 08:04:12 1995
@@ -42,7 +42,7 @@
 %
 \title{{\bf Linux Allocated Devices}}
 \author{Maintained by H. Peter Anvin $<$Peter.Anvin@linux.org$>$}
-\date{Last revised: September 6, 1995}
+\date{Last revised: September 20, 1995}
 \maketitle
 %
 \noindent
@@ -138,8 +138,10 @@
 \major{  }{}{block}{Third IDE hard disk/CD-ROM interface}
 \major{34}{}{char }{Z8530 HDLC driver}
 \major{  }{}{block}{Fourth IDE hard disk/CD-ROM interface}
-\major{35}{}{block}{Modular RAM disk}
-\major{36--223}{}{}{Unallocated}
+\major{35}{}{char }{tclmidi MIDI driver}
+\major{  }{}{block}{Modular RAM disk}
+\major{36}{}{block}{MCA ESDI hard disk}
+\major{37--223}{}{}{Unallocated}
 \major{224--254}{}{}{Local use}
 \major{255}{}{}{Reserved}
 \end{devicelist}
@@ -318,9 +320,9 @@
 \end{devicelist}
 
 \noindent
-Partitions are handled in the same way as for IDE
-disks (see major number 3) except that the limit on
-logical partitions is 11 rather than 59 per disk.
+Partitions are handled in the same way as for IDE disks (see major
+number 3) except that the limit on logical partitions is 11 rather
+than 59 per disk.
 
 \begin{devicelist}
 \major{ 9}{}{char }{SCSI tape devices}
@@ -401,8 +403,8 @@
 \end{devicelist}
 
 \noindent
-Partitions are handled in the same way as IDE disks
-(see major number 3).
+Partitions are handled in the same way as for IDE disks (see major
+number 3).
 
 \begin{devicelist}
 \major{14}{}{char }{Sound card}
@@ -430,8 +432,8 @@
 \end{devicelist}
 
 \noindent
-Partitions are handled in the same way as IDE disks
-(see major number 3).
+Partitions are handled in the same way as for IDE disks (see major
+number 3).
 
 \begin{devicelist}
 \major{15}{}{char }{Joystick}
@@ -517,8 +519,8 @@
 \end{devicelist}
 
 \noindent
-Partitions are handled the same way as for the first
-interface (see major number 3).
+Partitions are handled the same way as for the first interface (see
+major number 3).
 
 \begin{devicelist}
 \major{23}{}{char }{Digiboard serial card -- alternate devices}
@@ -621,9 +623,9 @@
 \end{devicelist}
 
 \noindent
-Partitions are handled in the same way as for IDE
-disks (see major number 3) except that the limit on
-logical partitions is 11 rather than 59 per disk.
+Partitions are handled in the same way as for IDE disks (see major
+number 3) except that the limit on logical partitions is 11 rather
+than 59 per disk.
 
 \begin{devicelist}
 \major{29}{}{char }{Universal frame buffer}
@@ -702,6 +704,7 @@
 	\minor{0}{/dev/ttyX0}{First Specialix port}
 	\minor{1}{/dev/ttyX1}{Second Specialix port}
 	\minordots
+\\
 \major{  }{}{block}{Philips LMS CM-206 CD-ROM}
 	\minor{0}{/dev/cm206cd}{Philips LMS CM-206 CD-ROM}
 \end{devicelist}
@@ -711,6 +714,7 @@
 	\minor{0}{/dev/cux0}{Callout device corresponding to {\file ttyX0}}
 	\minor{1}{/dev/cux1}{Callout device corresponding to {\file ttyX1}}
 	\minordots
+\\
 \major{  }{}{block}{Third IDE hard disk/CD-ROM interface}
 	\minor{0}{/dev/hde}{Master: whole disk (or CD-ROM)}
 	\minor{64}{/dev/hdf}{Slave: whole disk (or CD-ROM)}
@@ -727,6 +731,13 @@
 	\minor{2}{/dev/sc3}{Second Z8530, first port}
 	\minor{3}{/dev/sc4}{Second Z8530, second port}
 	\minordots
+\end{devicelist}
+
+\noindent
+The author has indicated that the device names will change in a
+subsequent version; {\file /dev/sc1} will become {\file /dev/scc0} etc.
+
+\begin{devicelist}
 \major{  }{}{block}{Fourth IDE hard disk/CD-ROM interface}
 	\minor{0}{/dev/hdg}{Master: whole disk (or CD-ROM)}
 	\minor{64}{/dev/hdh}{Slave: whole disk (or CD-ROM)}
@@ -737,7 +748,21 @@
 major number 3).
 
 \begin{devicelist}
-\major{35}{}{block}{Modular RAM disk}
+\major{35}{}{char }{tclmidi MIDI driver}
+	\minor{0}{/dev/midi0}{First MIDI port, kernel timed}
+	\minor{1}{/dev/midi1}{Second MIDI port, kernel timed}
+	\minor{2}{/dev/midi2}{Third MIDI port, kernel timed}
+	\minor{3}{/dev/midi3}{Fourth MIDI port, kernel timed}
+	\minor{64}{/dev/rmidi0}{First MIDI port, untimed}
+	\minor{65}{/dev/rmidi1}{Second MIDI port, untimed}
+	\minor{66}{/dev/rmidi2}{Third MIDI port, untimed}
+	\minor{67}{/dev/rmidi3}{Fourth MIDI port, untimed}
+	\minor{128}{/dev/smpte0}{First MIDI port, SMPTE timed}
+	\minor{129}{/dev/smpte1}{Second MIDI port, SMPTE timed}
+	\minor{130}{/dev/smpte2}{Third MIDI port, SMPTE timed}
+	\minor{131}{/dev/smpte3}{Fourth MIDI port, SMPTE timed}
+\\
+\major{  }{}{block}{Modular RAM disk}
 	\minor{0}{/dev/ram0}{First modular RAM disk}
 	\minor{1}{/dev/ram1}{Second modular RAM disk}
 	\minordots
@@ -745,7 +770,18 @@
 \end{devicelist}
 
 \begin{devicelist}
-\major{36}{--223}{}{Unallocated}
+\major{36}{}{block}{MCA ESDI hard disk}
+	\minor{0}{/dev/eda}{First ESDI disk whole disk}
+	\minor{64}{/dev/edb}{Second ESDI disk whole disk}
+	\minordots
+\end{devicelist}
+
+\noindent
+Partitions are handled the same way as for IDE disks (see major number
+3).
+
+\begin{devicelist}
+\major{37}{--223}{}{Unallocated}
 \end{devicelist}
 
 \begin{devicelist}
diff -u --recursive --new-file v1.3.28/linux/Documentation/devices.txt linux/Documentation/devices.txt
--- v1.3.28/linux/Documentation/devices.txt	Wed Sep 13 12:45:28 1995
+++ linux/Documentation/devices.txt	Thu Sep 21 08:53:40 1995
@@ -2,7 +2,7 @@
 
 	 Maintained by H. Peter Anvin <Peter.Anvin@linux.org>
 
-		   Last revised: September 6, 1995
+		   Last revised: September 20, 1995
 
 This list is the successor to Rick Miller's Linux Device List, which
 he stopped maintaining when he lost network access in 1993.  It is a
@@ -503,13 +503,34 @@
 		Partitions are handled the same way as for the first
 		interface (see major number 3).
 
- 35 block	Modular RAM disk device
+ 35 char	tclmidi MIDI driver
+		  0 = /dev/midi0	First MIDI port, kernel timed
+		  1 = /dev/midi1	Second MIDI port, kernel timed
+		  2 = /dev/midi2	Third MIDI port, kernel timed
+		  3 = /dev/midi3	Fourth MIDI port, kernel timed
+	         64 = /dev/rmidi0	First MIDI port, untimed
+	         65 = /dev/rmidi1	Second MIDI port, untimed
+	         66 = /dev/rmidi2	Third MIDI port, untimed
+	         67 = /dev/rmidi3	Fourth MIDI port, untimed
+		128 = /dev/smpte0	First MIDI port, SMPTE timed
+		129 = /dev/smpte1	Second MIDI port, SMPTE timed
+		130 = /dev/smpte2	Third MIDI port, SMPTE timed
+		131 = /dev/smpte3	Fourth MIDI port, SMPTE timed
+    block	Modular RAM disk device
 		  0 = /dev/ram0		First modular RAM disk
 		  1 = /dev/ram1		Second modular RAM disk
 		      ...
 		255 = /dev/ram255	256th modular RAM disk
 
- 36-223		UNALLOCATED
+ 36 block	MCA ESDI hard disk
+		  0 = /dev/eda		First ESDI disk whole disk
+		 64 = /dev/edb		Second ESDI disk whole disk
+		      ...
+
+		Partitions are handled in the same way as IDE disks
+		(see major number 3).
+
+ 37-223		UNALLOCATED
 
 224-254		LOCAL USE
 		Allocated for local/experimental use
diff -u --recursive --new-file v1.3.28/linux/Documentation/modules.txt linux/Documentation/modules.txt
--- v1.3.28/linux/Documentation/modules.txt	Sun Sep  3 12:26:47 1995
+++ linux/Documentation/modules.txt	Fri Sep 22 08:04:12 1995
@@ -34,7 +34,9 @@
 	Most filesystems: minix, xiafs, msdos, umsdos, sysv, isofs, hpfs,
 			  smbfs, nfs
 
-	Some SCSI drivers: aha1542, in2000
+	Mid-level SCSI support (required by top and low level scsi drivers).
+	Most low-level SCSI drivers: (i.e. aha1542, in2000)
+	All SCSI high-level drivers: disk, tape, cdrom, generic.
 
 	Some ethernet drivers:
 		plip, slip, dummy,
diff -u --recursive --new-file v1.3.28/linux/Documentation/scsi.txt linux/Documentation/scsi.txt
--- v1.3.28/linux/Documentation/scsi.txt	Thu Jan  1 02:00:00 1970
+++ linux/Documentation/scsi.txt	Fri Sep 22 08:04:12 1995
@@ -0,0 +1,30 @@
+
+	The scsi support in the linux kernel can be modularized in a
+number of different ways depending upon the needs of the end user.  To
+understand  your options, we should first define a few terms.
+
+	The scsi-core contains the core of scsi support.  Without it
+you can do nothing with any of the other scsi drivers.  The scsi core
+support can be a module (scsi_mod.o), or it can be build into the kernel.
+If the core is a module, it must be the first scsi module loaded, and
+if you unload the modules, it will have to be the last one unloaded.
+
+	The individual upper and lower level drivers can be loaded in any
+order once the scsi core is present in the kernel (either compiled in
+or loaded as a module).  The disk driver (sd_mod.o), cdrom driver (sr_mod.o),
+tape driver (st.o) and scsi generics driver (sg.o) represent the upper level
+drivers to support the various assorted devices which can be controlled.
+You can for example load the tape driver to use the tape drive, and then
+unload it once you have no further need for the driver (and release the
+associated memory).
+
+	The lower level drivers are the ones that support the
+individual cards that are supported for the hardware platform that you
+are running under.  Examples are aha1542.o to drive Adaptec 1542
+cards.  Rather than list the drivers which *can* be modularized, it is
+easier to list the ones which cannot, since the list only contains a
+few entries.  The drivers which have NOT been modularized are:
+
+	NCR5380 boards of one kind or another including PAS16,
+		Trantor T128/128F/228, 
+
diff -u --recursive --new-file v1.3.28/linux/Makefile linux/Makefile
--- v1.3.28/linux/Makefile	Mon Sep 18 14:53:47 1995
+++ linux/Makefile	Mon Sep 18 14:54:52 1995
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 3
-SUBLEVEL = 28
+SUBLEVEL = 29
 
 ARCH = i386
 
diff -u --recursive --new-file v1.3.28/linux/Rules.make linux/Rules.make
--- v1.3.28/linux/Rules.make	Wed Sep 13 12:45:28 1995
+++ linux/Rules.make	Thu Sep 21 08:53:39 1995
@@ -92,12 +92,13 @@
 	set -e; for i in $(MOD_SUB_DIRS); do $(MAKE) -C $$i modules; done
 endif
 ifneq "$(strip $(MOD_LIST_NAME))" ""
-ifndef M_OBJS # Hack for fs subdirectories
 	rm -f $$TOPDIR/modules/$(MOD_LIST_NAME)
+ifdef MOD_SUB_DIRS
 	for i in $(MOD_SUB_DIRS); do \
 	    echo `basename $$i`.o >> $$TOPDIR/modules/$(MOD_LIST_NAME); done
-else
-	echo $(M_OBJS) > $$TOPDIR/modules/$(MOD_LIST_NAME)
+endif
+ifdef M_OBJS
+	echo $(M_OBJS) >> $$TOPDIR/modules/$(MOD_LIST_NAME)
 endif
 endif
 ifdef M_OBJS
diff -u --recursive --new-file v1.3.28/linux/arch/alpha/Makefile linux/arch/alpha/Makefile
--- v1.3.28/linux/arch/alpha/Makefile	Sun Sep  3 12:26:48 1995
+++ linux/arch/alpha/Makefile	Sat Sep 23 18:39:44 1995
@@ -11,9 +11,9 @@
 NM := nm -B
 
 # enable this for linking under OSF/1:
-LINKFLAGS = -non_shared -T 0xfffffc0000310000 -N
+#LINKFLAGS = -non_shared -T 0xfffffc0000310000 -N
 # enable this for linking under Linux:
-#LINKFLAGS = -static -T arch/alpha/vmlinux.lds -N
+LINKFLAGS = -static -T arch/alpha/vmlinux.lds -N
 
 CFLAGS := $(CFLAGS) -mno-fp-regs
 
diff -u --recursive --new-file v1.3.28/linux/arch/alpha/boot/Makefile linux/arch/alpha/boot/Makefile
--- v1.3.28/linux/arch/alpha/boot/Makefile	Sat Sep  9 15:26:51 1995
+++ linux/arch/alpha/boot/Makefile	Sat Sep 23 18:39:44 1995
@@ -9,9 +9,9 @@
 #
 
 # enable this for linking under OSF/1:
-LINKFLAGS = -non_shared -T 0x20000000 -N
+#LINKFLAGS = -non_shared -T 0x20000000 -N
 # enable this for linking under Linux:
-#LINKFLAGS = -static -T bootloader.lds -N 
+LINKFLAGS = -static -T bootloader.lds -N 
 
 .S.s:
 	$(CC) -D__ASSEMBLY__ -traditional -E -o $*.o $<
@@ -32,9 +32,9 @@
 	gzip -fv vmlinux
 
 vmlinux: tools/build $(TOPDIR)/vmlinux
-	tools/build -v $(TOPDIR)/vmlinux > vmlinux
-#	cp $(TOPDIR)/vmlinux vmlinux
-#	quickstrip vmlinux
+#	tools/build -v $(TOPDIR)/vmlinux > vmlinux
+	cp $(TOPDIR)/vmlinux vmlinux
+	quickstrip vmlinux
 
 tools/lxboot: tools/build
 	tools/build > tools/lxboot
diff -u --recursive --new-file v1.3.28/linux/arch/alpha/config.in linux/arch/alpha/config.in
--- v1.3.28/linux/arch/alpha/config.in	Mon Sep 18 14:53:47 1995
+++ linux/arch/alpha/config.in	Sat Sep 23 18:39:44 1995
@@ -6,7 +6,7 @@
 comment 'General setup'
 
 tristate 'Normal floppy disk support' CONFIG_BLK_DEV_FD y
-bool 'Normal (MFM/RLL) disk and IDE disk/cdrom support' CONFIG_ST506 n
+bool 'Normal (MFM/RLL) disk and IDE disk/cdrom support' CONFIG_ST506 y
 if [ "$CONFIG_ST506" = "y" ]; then
   comment 'Please see drivers/block/README.ide for help/info on IDE drives'
   bool '   Use old disk-only driver for primary i/f' CONFIG_BLK_DEV_HD n
@@ -29,7 +29,7 @@
 	 EB66		CONFIG_ALPHA_EB66		\
 	 EB66+		CONFIG_ALPHA_EB66P		\
 	 EB64		CONFIG_ALPHA_EB64		\
-	 EB64+		CONFIG_ALPHA_EB64P" Jensen
+	 EB64+		CONFIG_ALPHA_EB64P" Cabriolet
 if [ "$CONFIG_ALPHA_NONAME" = "y" ]; then
 	define_bool CONFIG_PCI y
 	define_bool CONFIG_ALPHA_LCA y
@@ -110,7 +110,7 @@
 
 dep_tristate 'Adaptec AHA152X support' CONFIG_SCSI_AHA152X n $CONFIG_SCSI
 dep_tristate 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 n $CONFIG_SCSI
-dep_tristate 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 y $CONFIG_SCSI
+dep_tristate 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 n $CONFIG_SCSI
 dep_tristate 'Adaptec AHA274X/284X/294X support' CONFIG_SCSI_AIC7XXX n $CONFIG_SCSI
 dep_tristate 'BusLogic SCSI support' CONFIG_SCSI_BUSLOGIC n $CONFIG_SCSI
 dep_tristate 'EATA-DMA (DPT, NEC, ATT, Olivetti) support' CONFIG_SCSI_EATA_DMA n $CONFIG_SCSI
@@ -119,7 +119,7 @@
 dep_tristate 'Future Domain 16xx SCSI support' CONFIG_SCSI_FUTURE_DOMAIN n $CONFIG_SCSI
 bool 'Generic NCR5380 SCSI support' CONFIG_SCSI_GENERIC_NCR5380 n
 if [ "$CONFIG_PCI" = "y" ]; then
-  dep_tristate 'NCR53c7,8xx SCSI support'  CONFIG_SCSI_NCR53C7xx n $CONFIG_SCSI
+  dep_tristate 'NCR53c7,8xx SCSI support'  CONFIG_SCSI_NCR53C7xx y $CONFIG_SCSI
 fi
 dep_tristate 'Always IN2000 SCSI support (test release)' CONFIG_SCSI_IN2000 n $CONFIG_SCSI
 bool 'PAS16 SCSI support' CONFIG_SCSI_PAS16 n
@@ -176,7 +176,7 @@
 	fi
 	tristate '3c509/3c579 support' CONFIG_EL3 y
 fi
-bool 'Other ISA cards' CONFIG_NET_ISA y
+bool 'Other ISA cards' CONFIG_NET_ISA n
 if [ "$CONFIG_NET_ISA" = "y" ]; then
 	tristate 'Cabletron E21xx support' CONFIG_E2100 n
 	tristate 'DEPCA support' CONFIG_DEPCA y
@@ -199,17 +199,17 @@
 	tristate 'NE2000/NE1000 support' CONFIG_NE2000 n
 	bool 'SK_G16 support' CONFIG_SK_G16 n
 fi
-bool 'EISA, VLB, PCI and on board controllers' CONFIG_NET_EISA n
+bool 'EISA, VLB, PCI and on board controllers' CONFIG_NET_EISA y
 if [ "$CONFIG_NET_EISA" = "y" ]; then
 	if [ "$CONFIG_NET_ALPHA" = "y" ]; then
 		tristate 'Ansel Communications EISA 3200 support' CONFIG_AC3200 n
 	fi
 	tristate 'Apricot Xen-II on board ethernet' CONFIG_APRICOT n
-	tristate 'DE425, DE434, DE435, DE500 support' CONFIG_DE4X5 n
+	tristate 'DE425, DE434, DE435, DE500 support' CONFIG_DE4X5 y
 #	tristate 'DEC 21040 PCI support' CONFIG_DEC_ELCP n
 #	bool 'LPL T100V 100Mbs support' CONFIG_LPL_T100 n
 #	bool 'PCnet32 (32 bit VLB and PCI LANCE) support' CONFIG_PCNET32 n
-	bool 'Zenith Z-Note support' CONFIG_ZNET y
+	bool 'Zenith Z-Note support' CONFIG_ZNET n
 fi
 bool 'Pocket and portable adaptors' CONFIG_NET_POCKET n
 if [ "$CONFIG_NET_POCKET" = "y" ]; then
diff -u --recursive --new-file v1.3.28/linux/arch/alpha/kernel/traps.c linux/arch/alpha/kernel/traps.c
--- v1.3.28/linux/arch/alpha/kernel/traps.c	Sun Sep  3 12:26:49 1995
+++ linux/arch/alpha/kernel/traps.c	Sat Sep 23 18:39:44 1995
@@ -42,9 +42,7 @@
 	for (i = -3; i < 6; i++)
 		printk("%c%08x%c",i?' ':'<',pc[i],i?' ':'>');
 	printk("\n");
-	for (i = 0 ; i < 5000000000 ; i++)
-		/* pause */;
-	halt();
+	do_exit(SIGSEGV);
 }
 
 asmlinkage void do_entArith(unsigned long summary, unsigned long write_mask,
diff -u --recursive --new-file v1.3.28/linux/arch/alpha/mm/init.c linux/arch/alpha/mm/init.c
--- v1.3.28/linux/arch/alpha/mm/init.c	Thu Jun  1 13:22:06 1995
+++ linux/arch/alpha/mm/init.c	Tue Sep 19 12:15:27 1995
@@ -68,12 +68,12 @@
 	i = MAP_NR(high_memory);
 	while (i-- > 0) {
 		total++;
-		if (mem_map[i] & MAP_PAGE_RESERVED)
+		if (mem_map[i].reserved)
 			reserved++;
-		else if (!mem_map[i])
+		else if (!mem_map[i].count)
 			free++;
 		else
-			shared += mem_map[i]-1;
+			shared += mem_map[i].count-1;
 	}
 	printk("%d pages of RAM\n",total);
 	printk("%d free pages\n",free);
@@ -127,7 +127,7 @@
 			continue;
 
 		while (nr--)
-			mem_map[pfn++] = 0;
+			mem_map[pfn++].reserved = 0;
 	}
 
 	/* unmap the console stuff: we don't need it, and we don't want it */
@@ -158,7 +158,7 @@
 	 */
 	tmp = KERNEL_START;
 	while (tmp < start_mem) {
-		mem_map[MAP_NR(tmp)] = MAP_PAGE_RESERVED;
+		mem_map[MAP_NR(tmp)].reserved = 1;
 		tmp += PAGE_SIZE;
 	}
 
@@ -171,9 +171,9 @@
 #endif
 
 	for (tmp = PAGE_OFFSET ; tmp < high_memory ; tmp += PAGE_SIZE) {
-		if (mem_map[MAP_NR(tmp)])
+		if (mem_map[MAP_NR(tmp)].reserved)
 			continue;
-		mem_map[MAP_NR(tmp)] = 1;
+		mem_map[MAP_NR(tmp)].count = 1;
 		free_page(tmp);
 	}
 	tmp = nr_free_pages << PAGE_SHIFT;
@@ -191,12 +191,12 @@
 	val->freeram = nr_free_pages << PAGE_SHIFT;
 	val->bufferram = buffermem;
 	while (i-- > 0)  {
-		if (mem_map[i] & MAP_PAGE_RESERVED)
+		if (mem_map[i].reserved)
 			continue;
 		val->totalram++;
-		if (!mem_map[i])
+		if (!mem_map[i].count)
 			continue;
-		val->sharedram += mem_map[i]-1;
+		val->sharedram += mem_map[i].count-1;
 	}
 	val->totalram <<= PAGE_SHIFT;
 	val->sharedram <<= PAGE_SHIFT;
diff -u --recursive --new-file v1.3.28/linux/arch/i386/config.in linux/arch/i386/config.in
--- v1.3.28/linux/arch/i386/config.in	Mon Sep 18 14:53:48 1995
+++ linux/arch/i386/config.in	Tue Sep 19 12:51:23 1995
@@ -34,7 +34,7 @@
 bool 'System V IPC' CONFIG_SYSVIPC y
 tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF y
 if [ "$CONFIG_BINFMT_ELF" = "y" ]; then
-bool 'Compile kernel as ELF - if your GCC is ELF-GCC' CONFIG_KERNEL_ELF n
+bool 'Compile kernel as ELF - if your GCC is ELF-GCC' CONFIG_KERNEL_ELF y
 fi
 #bool 'Use -mpentium flag for Pentium-specific optimizations' CONFIG_M586 n
 #if [ "$CONFIG_M586" = "n" ]; then
diff -u --recursive --new-file v1.3.28/linux/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c
--- v1.3.28/linux/arch/i386/kernel/setup.c	Mon Sep 18 14:53:48 1995
+++ linux/arch/i386/kernel/setup.c	Wed Sep 20 08:59:13 1995
@@ -22,6 +22,7 @@
 #include <linux/tty.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
+#include <linux/config.h>
 
 #include <asm/segment.h>
 #include <asm/system.h>
diff -u --recursive --new-file v1.3.28/linux/arch/i386/mm/init.c linux/arch/i386/mm/init.c
--- v1.3.28/linux/arch/i386/mm/init.c	Sun Sep  3 12:26:49 1995
+++ linux/arch/i386/mm/init.c	Tue Sep 19 12:16:55 1995
@@ -73,12 +73,12 @@
 	i = high_memory >> PAGE_SHIFT;
 	while (i-- > 0) {
 		total++;
-		if (mem_map[i] & MAP_PAGE_RESERVED)
+		if (mem_map[i].reserved)
 			reserved++;
-		else if (!mem_map[i])
+		else if (!mem_map[i].count)
 			free++;
 		else
-			shared += mem_map[i]-1;
+			shared += mem_map[i].count-1;
 	}
 	printk("%d pages of RAM\n",total);
 	printk("%d free pages\n",free);
@@ -192,12 +192,12 @@
 	 * controller as well..
 	 */
 	while (start_low_mem < 0x9f000) {
-		mem_map[MAP_NR(start_low_mem)] = 0;
+		mem_map[MAP_NR(start_low_mem)].reserved = 0;
 		start_low_mem += PAGE_SIZE;
 	}
 
 	while (start_mem < high_memory) {
-		mem_map[MAP_NR(start_mem)] = 0;
+		mem_map[MAP_NR(start_mem)].reserved = 0;
 		start_mem += PAGE_SIZE;
 	}
 #ifdef CONFIG_SCSI
@@ -207,7 +207,7 @@
 	sound_mem_init();
 #endif
 	for (tmp = 0 ; tmp < high_memory ; tmp += PAGE_SIZE) {
-		if (mem_map[MAP_NR(tmp)]) {
+		if (mem_map[MAP_NR(tmp)].reserved) {
 			if (tmp >= 0xA0000 && tmp < 0x100000)
 				reservedpages++;
 			else if (tmp < (unsigned long) &_etext)
@@ -216,7 +216,7 @@
 				datapages++;
 			continue;
 		}
-		mem_map[MAP_NR(tmp)] = 1;
+		mem_map[MAP_NR(tmp)].count = 1;
 		free_page(tmp);
 	}
 	tmp = nr_free_pages << PAGE_SHIFT;
@@ -249,12 +249,12 @@
 	val->freeram = nr_free_pages << PAGE_SHIFT;
 	val->bufferram = buffermem;
 	while (i-- > 0)  {
-		if (mem_map[i] & MAP_PAGE_RESERVED)
+		if (mem_map[i].reserved)
 			continue;
 		val->totalram++;
-		if (!mem_map[i])
+		if (!mem_map[i].count)
 			continue;
-		val->sharedram += mem_map[i]-1;
+		val->sharedram += mem_map[i].count-1;
 	}
 	val->totalram <<= PAGE_SHIFT;
 	val->sharedram <<= PAGE_SHIFT;
diff -u --recursive --new-file v1.3.28/linux/drivers/block/genhd.c linux/drivers/block/genhd.c
--- v1.3.28/linux/drivers/block/genhd.c	Mon Sep 18 14:53:49 1995
+++ linux/drivers/block/genhd.c	Thu Sep 21 08:53:39 1995
@@ -79,11 +79,12 @@
 {
 	struct buffer_head *bh;
 	struct partition *p;
-	unsigned long first_sector, this_sector, this_size;
+	unsigned long first_sector, first_size, this_sector, this_size;
 	int mask = (1 << hd->minor_shift) - 1;
 	int i;
 
 	first_sector = hd->part[MINOR(dev)].start_sect;
+	first_size = hd->part[MINOR(dev)].nr_sects;
 	this_sector = first_sector;
 
 	while (1) {
@@ -122,7 +123,13 @@
 		    if (!p->nr_sects || p->sys_ind == EXTENDED_PARTITION)
 		      continue;
 
-		    if (p->start_sect + p->nr_sects > this_size)
+		    /* Check the 3rd and 4th entries -
+		       these sometimes contain random garbage */
+		    if (i >= 2
+			&& p->start_sect + p->nr_sects > this_size
+			&& (this_sector + p->start_sect < first_sector ||
+			    this_sector + p->start_sect + p->nr_sects >
+			     first_sector + first_size))
 		      continue;
 
 		    add_partition(hd, current_minor, this_sector+p->start_sect, p->nr_sects);
diff -u --recursive --new-file v1.3.28/linux/drivers/net/slip.c linux/drivers/net/slip.c
--- v1.3.28/linux/drivers/net/slip.c	Fri Aug 18 08:44:57 1995
+++ linux/drivers/net/slip.c	Thu Sep 21 08:53:40 1995
@@ -1163,15 +1163,14 @@
 	}
 
 
-	/* If not loadable module, a bootstrap Space.c slip_proto dev
-	 *  now needs to be unregistered.
+#ifdef MODULE
+	return status;
+#else
+	/* Return "not found", so that dev_init() will unlink
+	 * the placeholder device entry for us.
 	 */
-#ifndef MODULE
-/*	printk("SLIP: Unregistering bootstrap device "
-	       "'slip_proto' - slip OK\n");*/
-	unregister_netdev(dummy);
+	return ENODEV;
 #endif
-	return status;
       }
 
 
diff -u --recursive --new-file v1.3.28/linux/drivers/pci/pci.c linux/drivers/pci/pci.c
--- v1.3.28/linux/drivers/pci/pci.c	Mon Sep 18 14:53:54 1995
+++ linux/drivers/pci/pci.c	Thu Sep 21 15:41:23 1995
@@ -83,6 +83,8 @@
 	DEVICE( SI,		SI_501,		"85C501"),
 	DEVICE( SI,		SI_496,		"85C496"),
 	DEVICE( SI,		SI_601,		"85C601"),
+	DEVICE( SI,		SI_5511,		"85C5511"),
+	DEVICE( SI,		SI_5513,		"85C5513"),
 	DEVICE( HP,		HP_J2585A,	"J2585A"),
 #if 0
 	DEVICE( SMC,		SMC_37C665,	"FDC 37C665"),  /* 1042 ? */
@@ -110,6 +112,7 @@
 	DEVICE( LEADTEK,	LEADTEK_805,	"S3 805"),
 	DEVICE( CONTAQ,		CONTAQ_82C599,	"82C599"),
 	DEVICE( CMD,		CMD_640,	"640 (buggy)"),
+	DEVICE( CMD,		CMD_646,	"646"),
 	DEVICE( VISION,		VISION_QD8500,	"QD-8500"),
 	DEVICE( VISION,		VISION_QD8580,	"QD-8580"),
 	DEVICE( WINBOND,	WINBOND_83769,	"W83769F"),
@@ -123,6 +126,7 @@
 	DEVICE( AL,		AL_M1461,	"M1461"),
 	DEVICE( AL,		AL_M4803,	"M4803"),
 	DEVICE( IMS,		IMS_8849,	"8849"),
+	DEVICE( REALTEK,	REALTEK_8300,	"ENW-8300C"),
 	DEVICE( VIA,		VIA_82C505,	"VT 82C505"),
 	DEVICE( VIA,		VIA_82C561,	"VT 82C561"),
 	DEVICE( VIA,		VIA_82C576,	"VT 82C576 3V"),
diff -u --recursive --new-file v1.3.28/linux/drivers/scsi/53c7,8xx.c linux/drivers/scsi/53c7,8xx.c
--- v1.3.28/linux/drivers/scsi/53c7,8xx.c	Mon Sep 18 14:53:55 1995
+++ linux/drivers/scsi/53c7,8xx.c	Tue Sep 19 09:34:23 1995
@@ -994,6 +994,8 @@
     unsigned char pci_bus, pci_device_fn;
     static short pci_index=0;	/* Device index to PCI BIOS calls */
 
+    tpnt->proc_dir = &proc_scsi_ncr53c7xx;
+
     for (current_override = count = 0; current_override < OVERRIDE_LIMIT; 
 	 ++current_override) {
 	 if (overrides[current_override].pci ? 
@@ -1120,7 +1122,6 @@
      * SCRIPTS.
      */
     
-    tpnt->proc_dir = &proc_scsi_ncr53c7xx;
 
     patch_abs_rwri_data (hostdata->script, 0, dmode_memory_to_memory, tmp);
     patch_abs_rwri_data (hostdata->script, 0, dmode_memory_to_ncr, memory_to_ncr);
diff -u --recursive --new-file v1.3.28/linux/drivers/scsi/Makefile linux/drivers/scsi/Makefile
--- v1.3.28/linux/drivers/scsi/Makefile	Mon Sep 18 14:53:55 1995
+++ linux/drivers/scsi/Makefile	Fri Sep 22 08:04:12 1995
@@ -38,7 +38,6 @@
       # Create this before we build anything else.
       SCSI_MODULE_VER := scsi_syms.ver
       SYMTAB_OBJS := scsi_syms.o
-      include ../../versions.mk
       endif
     M_OBJS += scsi_mod.o
   endif
@@ -234,6 +233,12 @@
 endif
 
 include $(TOPDIR)/Rules.make
+
+ifeq ($(CONFIG_SCSI),m)
+  ifdef CONFIG_MODVERSIONS
+      include ../../versions.mk
+  endif
+endif
 
 aha152x.o: aha152x.c
 	$(CC) $(CFLAGS) $(AHA152X) -c aha152x.c 
diff -u --recursive --new-file v1.3.28/linux/drivers/scsi/eata_dma.c linux/drivers/scsi/eata_dma.c
--- v1.3.28/linux/drivers/scsi/eata_dma.c	Mon Sep 18 14:53:56 1995
+++ linux/drivers/scsi/eata_dma.c	Thu Sep 21 15:41:29 1995
@@ -48,7 +48,7 @@
  * Thanks also to Greg Hosler who did a lot of testing and  *
  * found quite a number of bugs during the development.	    *
  ************************************************************
- *  last change: 95/07/18                 OS: Linux 1.3.10  *
+ *  last change: 95/09/17                 OS: Linux 1.3.28  *
  ************************************************************/
 
 /* Look in eata_dma.h for configuration and revision information */
@@ -504,10 +504,11 @@
     cmd->host_scribble = (char *)&hd->ccb[y];	
     
     if(eata_send_command((u32) cp, (u32) sh->base, EATA_CMD_DMA_SEND_CP) == FALSE) {
-	cmd->result = DID_ERROR << 16;
-	printk("eata_queue target %d, pid %ld, HBA busy, returning DID_ERROR,"
-	       " done.\n", cmd->target, cmd->pid);
+	cmd->result = DID_BUS_BUSY << 16;
+	printk("eata_queue target %d, pid %ld, HBA busy, returning DID_BUS_BUSY\n", 
+	       cmd->target, cmd->pid);
 	done(cmd);
+	cp->status = FREE;     /* Hmmm..... */
 	restore_flags(flags);
 	return(0);
     }
@@ -857,7 +858,6 @@
 	       "Please use the EATA-PIO driver.\n", base);
 	return (FALSE);
     }
-
     if(gc->HAA_valid == FALSE || ntohl(gc->len) < 0x22) 
 	gc->MAX_CHAN = 0;
     
@@ -1124,8 +1124,8 @@
 				      (int)pal1, (int)pal2, (int)pal3));
 #endif
 		if (get_conf_PIO(base, buf) == TRUE) {
-		    DBG(DBG_PROBE && DBG_EISA, print_config(buf));
 		    if (buf->IRQ) {  
+			DBG(DBG_EISA, printk("Registering EISA HBA\n"));
 			register_HBA(base, buf, tpnt, IS_EISA);
 		    } else
 			printk("eata_dma: No valid IRQ. HBA removed from list\n");
@@ -1151,6 +1151,7 @@
     for (i = 0; i < MAXISA; i++) {  
 	if (ISAbases[i]) {  
 	    if (get_conf_PIO(ISAbases[i],buf) == TRUE){
+		DBG(DBG_ISA, printk("Registering ISA HBA\n"));
 		register_HBA(ISAbases[i], buf, tpnt, IS_ISA);
 	    } else {
 		if (check_blink_state(ISAbases[i])) 
@@ -1176,6 +1177,7 @@
     u16 com_adr;
     u16 rev_device;
     u32 error, i, x;
+    u8 pal1, pal2, pal3;
 
     if (pcibios_present()) {
 	for (i = 0; i <= MAXPCI; ++i, ++pci_index) {
@@ -1217,21 +1219,26 @@
 		/* Check if the address is valid */
 		if (base & 0x01) {
 		    base &= 0xfffffffe;
-		    /* EISA tag there ? */
-		    if ((inb(base) == 0x12) && (inb(base + 1) == 0x14))
-			continue;   /* Jep, it's forced, so move on  */
-		    base += 0x10;   /* Now, THIS is the real address */
+                    /* EISA tag there ? */
+		    pal1 = inb(base);
+		    pal2 = inb(base + 1);
+		    pal3 = inb(base + 2);
+		    if (((pal1 == 0x12) && (pal2 == 0x14)) ||
+			((pal1 == 0x38) && (pal2 == 0xa3) && (pal3 == 0x82)) ||
+			((pal1 == 0x06) && (pal2 == 0x94) && (pal3 == 0x24)))
+			base += 0x08;
+		    else
+			base += 0x10;   /* Now, THIS is the real address */
+
 		    if (base != 0x1f8) {
 			/* We didn't find it in the primary search */
 			if (get_conf_PIO(base, buf) == TRUE) {
-			    if (buf->FORCADR)	/* If the address is forced */
-				continue;	/* we'll find it later	    */
-			    
+
 			    /* OK. We made it till here, so we can go now  
 			     * and register it. We  only have to check and 
 			     * eventually remove it from the EISA and ISA list 
 			     */
-			    
+			    DBG(DBG_PCI, printk("Registering PCI HBA\n"));
 			    register_HBA(base, buf, tpnt, IS_PCI);
 			    
 			    if (base < 0x1000) {
diff -u --recursive --new-file v1.3.28/linux/drivers/scsi/eata_dma.h linux/drivers/scsi/eata_dma.h
--- v1.3.28/linux/drivers/scsi/eata_dma.h	Mon Sep 18 14:53:56 1995
+++ linux/drivers/scsi/eata_dma.h	Thu Sep 21 15:41:29 1995
@@ -16,7 +16,7 @@
 
 #define VER_MAJOR 2
 #define VER_MINOR 5
-#define VER_SUB   "7b"
+#define VER_SUB   "8"
 
 
 /************************************************************************
@@ -72,6 +72,8 @@
 #else
 #define eata_release NULL  
 #endif
+
+#include <linux/scsicam.h>
 
 #define EATA_DMA {                   \
         NULL, NULL,                  \
diff -u --recursive --new-file v1.3.28/linux/drivers/scsi/eata_dma_proc.c linux/drivers/scsi/eata_dma_proc.c
--- v1.3.28/linux/drivers/scsi/eata_dma_proc.c	Mon Sep 18 14:53:56 1995
+++ linux/drivers/scsi/eata_dma_proc.c	Thu Sep 21 15:41:29 1995
@@ -369,7 +369,7 @@
 		       SD(HBA_ptr)->writes[11]);
 	len += size; 
 	pos = begin + len;
-	size = sprintf(buffer+len,"Sum   : %12u %12u\n",
+	size = sprintf(buffer+len,"Sum   :%12u %12u\n",
 		       SD(HBA_ptr)->reads[12], 
 		       SD(HBA_ptr)->writes[12]);
 	len += size; 
diff -u --recursive --new-file v1.3.28/linux/drivers/scsi/eata_pio.c linux/drivers/scsi/eata_pio.c
--- v1.3.28/linux/drivers/scsi/eata_pio.c	Mon Sep 18 14:53:56 1995
+++ linux/drivers/scsi/eata_pio.c	Thu Sep 21 15:41:29 1995
@@ -378,11 +378,12 @@
     
     if (eata_pio_send_command(base, EATA_CMD_PIO_SEND_CP)) 
     {
-	cmd->result = DID_ERROR << 16;
+	cmd->result = DID_BUS_BUSY << 16;
 	printk("eata_pio_queue target %d, pid %ld, HBA busy, returning "
-               "DID_ERROR, done.\n", cmd->target, cmd->pid);
-	restore_flags(flags);
+               "DID_BUS_BUSY, done.\n", cmd->target, cmd->pid);
         done(cmd);
+        cp->status = FREE;      
+        restore_flags(flags);
 	return (0);
     }
     while (!(inb(base + HA_RSTATUS) & HA_SDRQ));
diff -u --recursive --new-file v1.3.28/linux/drivers/scsi/hosts.c linux/drivers/scsi/hosts.c
--- v1.3.28/linux/drivers/scsi/hosts.c	Mon Sep 18 14:53:57 1995
+++ linux/drivers/scsi/hosts.c	Tue Sep 19 12:12:38 1995
@@ -416,7 +416,7 @@
 		     Low24 += PAGE_SIZE) {
 		    unsigned long ForbiddenAddress = High8 + Low24;
 		    if (ForbiddenAddress >= memory_end) goto next_host;
-		    mem_map[MAP_NR(ForbiddenAddress)] = MAP_PAGE_RESERVED;
+		    mem_map[MAP_NR(ForbiddenAddress)].reserved = 1;
 		}
 	    }
 	}
diff -u --recursive --new-file v1.3.28/linux/drivers/scsi/qlogic.c linux/drivers/scsi/qlogic.c
--- v1.3.28/linux/drivers/scsi/qlogic.c	Mon Sep 18 14:54:02 1995
+++ linux/drivers/scsi/qlogic.c	Wed Sep 20 16:06:19 1995
@@ -543,7 +543,7 @@
 struct	Scsi_Host	*hreg;	/* registered host structure */
 unsigned long	flags;
 
-tpnt->proc_dir =  &proc_scsi_qlogic;
+host->proc_dir =  &proc_scsi_qlogic;
 
 /* Qlogic Cards only exist at 0x230 or 0x330 (the chip itself decodes the
    address - I check 230 first since MIDI cards are typically at 330
diff -u --recursive --new-file v1.3.28/linux/drivers/scsi/scsi.h linux/drivers/scsi/scsi.h
--- v1.3.28/linux/drivers/scsi/scsi.h	Mon Sep 18 14:54:02 1995
+++ linux/drivers/scsi/scsi.h	Fri Sep 22 08:30:32 1995
@@ -510,37 +510,37 @@
  * that an interrupt may start another request, so we run this with interrupts
  * turned off 
  */
-#define INIT_SCSI_REQUEST \
-    if (!CURRENT) {\
-	CLEAR_INTR; \
+#define INIT_SCSI_REQUEST       \
+    if (!CURRENT) {             \
+	CLEAR_INTR;             \
 	restore_flags(flags);	\
-	return; \
-    } \
-    if (MAJOR(CURRENT->rq_dev) != MAJOR_NR) \
-	panic(DEVICE_NAME ": request list destroyed"); \
-    if (CURRENT->bh) { \
-	if (!CURRENT->bh->b_lock) \
-	    panic(DEVICE_NAME ": block not locked"); \
+	return;                 \
+    }                           \
+    if (MAJOR(CURRENT->rq_dev) != MAJOR_NR)           \
+	panic(DEVICE_NAME ": request list destroyed");\
+    if (CURRENT->bh) {                                \
+	if (!CURRENT->bh->b_lock)                     \
+	    panic(DEVICE_NAME ": block not locked");  \
     }
 #endif
 
 #define SCSI_SLEEP(QUEUE, CONDITION) {		    \
-    if (CONDITION) {			\
+    if (CONDITION) {			            \
 	struct wait_queue wait = { current, NULL};  \
-	add_wait_queue(QUEUE, &wait);		\
-	for(;;) {			    \
+	add_wait_queue(QUEUE, &wait);		    \
+	for(;;) {			            \
 	current->state = TASK_UNINTERRUPTIBLE;	    \
-	if (CONDITION) {		\
-		   if (intr_count)				\
-		      panic("scsi: trying to call schedule() in interrupt" \
-			    ", file %s, line %d.\n", __FILE__, __LINE__);  \
-	   schedule();			\
-	   }				\
-	    else			\
-		   break;					\
-	}			\
-	remove_wait_queue(QUEUE, &wait);	\
-	current->state = TASK_RUNNING;		\
+	if (CONDITION) {		            \
+            if (intr_count)	                    \
+	        panic("scsi: trying to call schedule() in interrupt" \
+		      ", file %s, line %d.\n", __FILE__, __LINE__);  \
+	    schedule();			\
+        }				\
+	else			        \
+	    break;      		\
+	}			        \
+	remove_wait_queue(QUEUE, &wait);\
+	current->state = TASK_RUNNING;	\
     }; }
 
 #endif
diff -u --recursive --new-file v1.3.28/linux/drivers/scsi/st.c linux/drivers/scsi/st.c
--- v1.3.28/linux/drivers/scsi/st.c	Mon Sep 18 14:54:03 1995
+++ linux/drivers/scsi/st.c	Wed Sep 20 08:18:05 1995
@@ -11,7 +11,7 @@
   Copyright 1992, 1993, 1994, 1995 Kai Makisara
 		 email Kai.Makisara@metla.fi
 
-  Last modified: Sun Sep 10 20:33:24 1995 by makisara@kai.makisara.fi
+  Last modified: Tue Sep 19 21:51:41 1995 by root@kai.makisara.fi
   Some small formal changes - aeb, 950809
 */
 #ifdef MODULE
@@ -74,14 +74,16 @@
 #define TAPE_NR(x) (MINOR(x) & 127)
 
 static int st_nbr_buffers;
-static int st_req_nbr_buffers;
 static ST_buffer **st_buffers;
 static int st_buffer_size = ST_BUFFER_SIZE;
 static int st_write_threshold = ST_WRITE_THRESHOLD;
 static int st_max_buffers = ST_MAX_BUFFERS;
 
+#define MAX_SCSI_TAPES 8
 Scsi_Tape * scsi_tapes = NULL;
 
+static ST_buffer *new_tape_buffer(int);
+
 static int st_init(void);
 static int st_attach(Scsi_Device *);
 static int st_detect(Scsi_Device *);
@@ -189,7 +191,7 @@
     if ((STp->buffer)->writing)
       SCpnt->request.rq_status = RQ_INACTIVE;
     else
-      SCpnt->request.rq_status = RQ_SCSI_BUSY;
+      SCpnt->request.rq_status = RQ_SCSI_DONE;
     if (!(STp->buffer)->writing || STp->write_pending)
       wake_up( &(STp->waiting) );
     STp->write_pending = 0;
@@ -257,13 +259,13 @@
   unsigned int flags;
 
   SCpnt = allocate_device(NULL, STp->device, 1);
+  SCpnt->request.rq_dev = devt;
   cmd[0] = SPACE;
   cmd[1] = ((SCpnt->lun << 5) & 0xe0) | 0x01; /* Space FileMarks */
   cmd[2] = cmd[3] = cmd[4] = 0xff;  /* -1 filemarks */
   cmd[5] = 0;
 
-  SCpnt->request.rq_status = RQ_ACTIVE;
-  SCpnt->request.rq_dev = devt;
+  SCpnt->request.rq_status = RQ_SCSI_BUSY;
   scsi_do_cmd(SCpnt,
 	      (void *) cmd, (void *) (STp->buffer)->b_data, 0,
 	      st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
@@ -271,7 +273,7 @@
   /* need to do the check with interrupts off. -RAB */
   save_flags(flags);
   cli();
-  if (TAPE_NR(SCpnt->request.rq_dev) == dev)
+  if (SCpnt->request.rq_status != RQ_SCSI_DONE)
     sleep_on( &(STp->waiting) );
   restore_flags(flags);
   
@@ -336,7 +338,7 @@
     cmd[2] = blks >> 16;
     cmd[3] = blks >> 8;
     cmd[4] = blks;
-    SCpnt->request.rq_status = RQ_ACTIVE;
+    SCpnt->request.rq_status = RQ_SCSI_BUSY;
     SCpnt->request.rq_dev = devt;
     scsi_do_cmd (SCpnt,
 		 (void *) cmd, (STp->buffer)->b_data, transfer,
@@ -345,7 +347,7 @@
     /* this must be done with interrupts off */
     save_flags (flags);
     cli();
-    if (TAPE_NR(SCpnt->request.rq_dev) == dev)
+    if (SCpnt->request.rq_status != RQ_SCSI_DONE)
       sleep_on( &(STp->waiting) );
     restore_flags(flags);
  
@@ -388,7 +390,6 @@
   STp = &(scsi_tapes[dev]);
   STbuffer = STp->buffer;
 
-
   /*
    * If there was a bus reset, block further access
    * to this device.
@@ -455,10 +456,14 @@
       if (!st_buffers[i]->in_use)
 	break;
     if (i >= st_nbr_buffers) {
-      printk("st%d: No free buffers.\n", dev);
-      return (-EBUSY);
+      STp->buffer = new_tape_buffer(FALSE);
+      if (STp->buffer == NULL) {
+	printk("st%d: No free buffers.\n", dev);
+	return (-EBUSY);
+      }
     }
-    STp->buffer = st_buffers[i];
+    else
+      STp->buffer = st_buffers[i];
     (STp->buffer)->in_use = 1;
     (STp->buffer)->writing = 0;
     STp->in_use = 1;
@@ -479,6 +484,7 @@
 #endif
 
     SCpnt = allocate_device(NULL, STp->device, 1);
+    SCpnt->request.rq_dev = devt;
     if (!SCpnt) {
       printk("st%d: Tape request not allocated", dev);
       return (-EBUSY);
@@ -487,8 +493,7 @@
     memset ((void *) &cmd[0], 0, 10);
     cmd[0] = TEST_UNIT_READY;
     cmd[1] = (SCpnt->lun << 5) & 0xe0;
-    SCpnt->request.rq_status = RQ_ACTIVE;
-    SCpnt->request.rq_dev = devt;
+    SCpnt->request.rq_status = RQ_SCSI_BUSY;
     scsi_do_cmd(SCpnt,
 		(void *) cmd, (void *) (STp->buffer)->b_data,
 		0, st_sleep_done, ST_LONG_TIMEOUT,
@@ -497,7 +502,7 @@
     /* this must be done with interrupts off */
     save_flags (processor_flags);
     cli();
-    if (TAPE_NR(SCpnt->request.rq_dev) == dev)
+    if (SCpnt->request.rq_status != RQ_SCSI_DONE)
       sleep_on( &(STp->waiting) );
     restore_flags(processor_flags);
 
@@ -507,8 +512,7 @@
       memset ((void *) &cmd[0], 0, 10);
       cmd[0] = TEST_UNIT_READY;
       cmd[1] = (SCpnt->lun << 5) & 0xe0;
-      SCpnt->request.rq_status = RQ_ACTIVE;
-      SCpnt->request.rq_dev = devt;
+      SCpnt->request.rq_status = RQ_SCSI_BUSY;
       scsi_do_cmd(SCpnt,
 		  (void *) cmd, (void *) (STp->buffer)->b_data,
 		  0, st_sleep_done, ST_LONG_TIMEOUT,
@@ -517,7 +521,7 @@
       /* this must be done with interrupts off */
       save_flags (processor_flags);
       cli();
-      if (TAPE_NR(SCpnt->request.rq_dev) == dev)
+      if (SCpnt->request.rq_status != RQ_SCSI_DONE)
 	sleep_on( &(STp->waiting) );
       restore_flags(processor_flags);
 
@@ -551,8 +555,7 @@
     memset ((void *) &cmd[0], 0, 10);
     cmd[0] = READ_BLOCK_LIMITS;
     cmd[1] = (SCpnt->lun << 5) & 0xe0;
-    SCpnt->request.rq_status = RQ_ACTIVE;
-    SCpnt->request.rq_dev = devt;
+    SCpnt->request.rq_status = RQ_SCSI_BUSY;
     scsi_do_cmd(SCpnt,
 		(void *) cmd, (void *) (STp->buffer)->b_data,
 		6, st_sleep_done, ST_TIMEOUT, MAX_READY_RETRIES);
@@ -560,7 +563,7 @@
     /* this must be done with interrupts off */
     save_flags (processor_flags);
     cli();
-    if (TAPE_NR(SCpnt->request.rq_dev) == dev)
+    if (SCpnt->request.rq_status != RQ_SCSI_DONE)
       sleep_on( &(STp->waiting) );
     restore_flags(processor_flags);
 
@@ -587,8 +590,7 @@
     cmd[0] = MODE_SENSE;
     cmd[1] = (SCpnt->lun << 5) & 0xe0;
     cmd[4] = 12;
-    SCpnt->request.rq_status = RQ_ACTIVE;
-    SCpnt->request.rq_dev = devt;
+    SCpnt->request.rq_status = RQ_SCSI_BUSY;
     scsi_do_cmd(SCpnt,
 		(void *) cmd, (void *) (STp->buffer)->b_data,
 		12, st_sleep_done, ST_TIMEOUT, MAX_READY_RETRIES);
@@ -596,7 +598,7 @@
     /* this must be done with interrupts off */
     save_flags (processor_flags);
     cli();
-    if (TAPE_NR(SCpnt->request.rq_dev) == dev)
+    if (SCpnt->request.rq_status != RQ_SCSI_DONE)
       sleep_on( &(STp->waiting) );
     restore_flags(processor_flags);
 
@@ -714,13 +716,13 @@
 
       if (result == 0 || result == (-ENOSPC)) {
 	SCpnt = allocate_device(NULL, STp->device, 1);
+	SCpnt->request.rq_dev = devt;
 
 	memset(cmd, 0, 10);
 	cmd[0] = WRITE_FILEMARKS;
 	cmd[1] = (SCpnt->lun << 5) & 0xe0;
 	cmd[4] = 1 + STp->two_fm;
-	SCpnt->request.rq_status = RQ_ACTIVE;
-	SCpnt->request.rq_dev = devt;
+	SCpnt->request.rq_status = RQ_SCSI_BUSY;
 	scsi_do_cmd( SCpnt,
 		    (void *) cmd, (void *) (STp->buffer)->b_data,
 		    0, st_sleep_done, ST_TIMEOUT, MAX_WRITE_RETRIES);
@@ -728,7 +730,7 @@
 	/* this must be done with interrupts off */
 	save_flags (flags);
 	cli();
-	if (TAPE_NR(SCpnt->request.rq_dev) == dev)
+	if (SCpnt->request.rq_status != RQ_SCSI_DONE)
 	  sleep_on( &(STp->waiting) );
 	restore_flags(flags);
 
@@ -867,6 +869,7 @@
       write_threshold--;
 
     SCpnt = allocate_device(NULL, STp->device, 1);
+    SCpnt->request.rq_dev = devt;
 
     total = count;
 
@@ -902,8 +905,7 @@
       cmd[2] = blks >> 16;
       cmd[3] = blks >> 8;
       cmd[4] = blks;
-      SCpnt->request.rq_status = RQ_ACTIVE;
-      SCpnt->request.rq_dev = devt;
+      SCpnt->request.rq_status = RQ_SCSI_BUSY;
       scsi_do_cmd (SCpnt,
 		   (void *) cmd, (STp->buffer)->b_data, transfer,
 		   st_sleep_done, ST_TIMEOUT, MAX_WRITE_RETRIES);
@@ -911,7 +913,7 @@
       /* this must be done with interrupts off */
       save_flags (flags);
       cli();
-      if (TAPE_NR(SCpnt->request.rq_dev) == dev)
+      if (SCpnt->request.rq_status != RQ_SCSI_DONE)
 	sleep_on( &(STp->waiting) );
       restore_flags(flags);
 
@@ -1018,8 +1020,7 @@
       cmd[2] = blks >> 16;
       cmd[3] = blks >> 8;
       cmd[4] = blks;
-      SCpnt->request.rq_status = RQ_ACTIVE;
-      SCpnt->request.rq_dev = devt;
+      SCpnt->request.rq_status = RQ_SCSI_BUSY;
       STp->write_pending = 1;
       scsi_do_cmd (SCpnt,
 		   (void *) cmd, (STp->buffer)->b_data,
@@ -1090,6 +1091,7 @@
     STp->rw = ST_READING;
 
     SCpnt = allocate_device(NULL, STp->device, 1);
+    SCpnt->request.rq_dev = devt;
 
     for (total = 0; total < count; ) {
 
@@ -1118,8 +1120,7 @@
 	cmd[3] = blks >> 8;
 	cmd[4] = blks;
 
-	SCpnt->request.rq_status = RQ_ACTIVE;
-	SCpnt->request.rq_dev = devt;
+	SCpnt->request.rq_status = RQ_SCSI_BUSY;
 	scsi_do_cmd (SCpnt,
 		     (void *) cmd, (STp->buffer)->b_data,
 		     bytes, st_sleep_done, ST_TIMEOUT, MAX_RETRIES);
@@ -1127,7 +1128,7 @@
 	/* this must be done with interrupts off */
 	save_flags (flags);
 	cli();
-	if (TAPE_NR(SCpnt->request.rq_dev) == dev)
+	if (SCpnt->request.rq_status != RQ_SCSI_DONE)
 	  sleep_on( &(STp->waiting) );
 	restore_flags(flags);
 
@@ -1687,9 +1688,9 @@
      }
 
    SCpnt = allocate_device(NULL, STp->device, 1);
-   cmd[1] |= (SCpnt->lun << 5) & 0xe0;
-   SCpnt->request.rq_status = RQ_ACTIVE;
    SCpnt->request.rq_dev = devt;
+   cmd[1] |= (SCpnt->lun << 5) & 0xe0;
+   SCpnt->request.rq_status = RQ_SCSI_BUSY;
    scsi_do_cmd(SCpnt,
 	       (void *) cmd, (void *) (STp->buffer)->b_data, datalen,
 	       st_sleep_done, timeout, MAX_RETRIES);
@@ -1697,7 +1698,7 @@
    /* this must be done with interrupts off */
    save_flags (flags);
    cli();
-   if (TAPE_NR(SCpnt->request.rq_dev) == dev)
+   if (SCpnt->request.rq_status != RQ_SCSI_DONE)
      sleep_on( &(STp->waiting) );
    restore_flags(flags);
 
@@ -1860,30 +1861,38 @@
      if (i)
 	return i;
 
-     /*
-      * If there was a bus reset, block further access
-      * to this device.  If the user wants to rewind the tape,
-      * then reset the flag and allow access again.
-      */
-     if( STp->device->was_reset) 
-       {
-	 if(mtc.mt_op != MTREW && 
-	    mtc.mt_op != MTOFFL &&
-	    mtc.mt_op != MTRESET && 
-	    mtc.mt_op != MTRETEN && 
-	    mtc.mt_op != MTEOM)
-	   return (-EIO);
-	 STp->device->was_reset = 0;
-       }
-
      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 ||
-		      mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD);
-     if (i < 0)
-       return i;
+     if (!(STp->device)->was_reset) {
+       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 ||
+			mtc.mt_op == MTLOCK || mtc.mt_op == MTLOAD);
+       if (i < 0)
+	 return i;
+     }
+     else {
+       /*
+	* If there was a bus reset, block further access
+	* to this device.  If the user wants to rewind the tape,
+	* then reset the flag and allow access again.
+	*/
+       if(mtc.mt_op != MTREW && 
+	  mtc.mt_op != MTOFFL &&
+	  mtc.mt_op != MTRETEN && 
+	  mtc.mt_op != MTERASE &&
+	  mtc.mt_op != MTSEEK &&
+	  mtc.mt_op != MTEOM)
+	 return (-EIO);
+       STp->device->was_reset = 0;
+       if (STp->door_locked != ST_UNLOCKED) {
+	 if (st_int_ioctl(inode, file, MTLOCK, 0)) {
+	   printk("st%d: Could not relock door after bus reset.\n", dev);
+	   STp->door_locked = ST_UNLOCKED;
+	 }
+       }
+     }
+
      if (mtc.mt_op != MTNOP && mtc.mt_op != MTSETBLK &&
 	 mtc.mt_op != MTSETDENSITY && mtc.mt_op != MTWSM &&
 	 mtc.mt_op != MTSETDRVBUFFER)
@@ -1970,6 +1979,7 @@
        return i;
 
      SCpnt = allocate_device(NULL, STp->device, 1);
+     SCpnt->request.rq_dev = devt;
 
      memset (scmd, 0, 10);
      if ((STp->device)->scsi_level < SCSI_2) {
@@ -1980,8 +1990,7 @@
        scmd[0] = READ_POSITION;
        scmd[1] = 1;
      }
-     SCpnt->request.rq_status = RQ_ACTIVE;
-     SCpnt->request.rq_dev = devt;
+     SCpnt->request.rq_status = RQ_SCSI_BUSY;
      scmd[1] |= (SCpnt->lun << 5) & 0xe0;
      scsi_do_cmd(SCpnt,
 		 (void *) scmd, (void *) (STp->buffer)->b_data,
@@ -1990,7 +1999,7 @@
      /* this must be done with interrupts off */
      save_flags (flags);
      cli();
-     if (TAPE_NR(SCpnt->request.rq_dev) == dev)
+     if (SCpnt->request.rq_status != RQ_SCSI_DONE)
        sleep_on( &(STp->waiting) );
      restore_flags(flags);
 
@@ -2026,6 +2035,44 @@
 }
 
 
+/* Try to allocate a new tape buffer */
+	static ST_buffer *
+new_tape_buffer( int from_initialization )
+{
+  int priority;
+  ST_buffer *tb;
+
+  if (st_nbr_buffers >= st_template.dev_max)
+    return NULL;  /* Should never happen */
+
+  if (from_initialization)
+    priority = GFP_ATOMIC;
+  else
+    priority = GFP_KERNEL;
+  tb = (ST_buffer *)scsi_init_malloc(sizeof(ST_buffer), priority);
+  if (tb) {
+    tb->b_data = (unsigned char *)scsi_init_malloc(st_buffer_size,
+						   priority | GFP_DMA);
+    if (!tb->b_data) {
+      scsi_init_free((char *)tb, sizeof(ST_buffer));
+      tb = NULL;
+    }
+  }
+  if (!tb) {
+    printk("st: Can't allocate new tape buffer (nbr %d).\n", st_nbr_buffers);
+    return NULL;
+  }
+
+#if DEBUG
+  printk("st: Allocated tape buffer %d.\n", st_nbr_buffers);
+#endif
+  tb->in_use = 0;
+  tb->writing = 0;
+  st_buffers[st_nbr_buffers++] = tb;
+  return tb;
+}
+
+
 /* Set the boot options. Syntax: st=xxx,yyy
    where xxx is buffer size in 512 byte blocks and yyy is write threshold
    in 512 byte blocks. */
@@ -2120,6 +2167,9 @@
 {
   int i;
   Scsi_Tape * STp;
+#if !ST_RUNTIME_BUFFERS
+  int target_nbr;
+#endif
 
   if (st_template.dev_noticed == 0) return 0;
 
@@ -2132,15 +2182,17 @@
   }
 
   if (scsi_tapes) return 0;
-  scsi_tapes = (Scsi_Tape *) scsi_init_malloc(
-  		(st_template.dev_noticed + ST_EXTRA_DEVS) * 
-					      sizeof(Scsi_Tape), GFP_ATOMIC);
+  st_template.dev_max = st_template.dev_noticed + ST_EXTRA_DEVS;
+  if (st_template.dev_max < MAX_SCSI_TAPES)
+    st_template.dev_max = MAX_SCSI_TAPES;
+  scsi_tapes =
+    (Scsi_Tape *) scsi_init_malloc(st_template.dev_max * sizeof(Scsi_Tape),
+				   GFP_ATOMIC);
   if (scsi_tapes == NULL) {
     printk("Unable to allocate descriptors for SCSI tapes.\n");
     unregister_chrdev(SCSI_TAPE_MAJOR, "st");
     return 1;
   }
-  st_template.dev_max = st_template.dev_noticed + ST_EXTRA_DEVS;
 
 #if DEBUG
   printk("st: Buffer size %d bytes, write threshold %d bytes.\n",
@@ -2168,62 +2220,49 @@
     STp->drv_block = 0;
     STp->moves_after_eof = 1;
     STp->at_sm = 0;
-    STp->mt_status = (struct mtget *) scsi_init_malloc(sizeof(struct mtget), GFP_ATOMIC);
+    STp->mt_status = (struct mtget *) scsi_init_malloc(sizeof(struct mtget),
+						       GFP_ATOMIC);
     /* Initialize status */
     memset((void *) scsi_tapes[i].mt_status, 0, sizeof(struct mtget));
   }
 
   /* Allocate the buffers */
-  st_nbr_buffers = st_template.dev_noticed;
-  if (st_nbr_buffers < ST_EXTRA_DEVS)
-    st_nbr_buffers = ST_EXTRA_DEVS;
-  if (st_nbr_buffers > st_max_buffers)
-    st_nbr_buffers = st_max_buffers;
-  st_req_nbr_buffers = st_nbr_buffers;
-  st_buffers = (ST_buffer **) scsi_init_malloc(st_nbr_buffers * 
-					       sizeof(ST_buffer *),
-					       GFP_ATOMIC);
+  st_buffers =
+    (ST_buffer **) scsi_init_malloc(st_template.dev_max * sizeof(ST_buffer *),
+				    GFP_ATOMIC);
   if (st_buffers == NULL) {
     printk("Unable to allocate tape buffer pointers.\n");
     unregister_chrdev(SCSI_TAPE_MAJOR, "st");
     scsi_init_free((char *) scsi_tapes,
-		   (st_template.dev_noticed + ST_EXTRA_DEVS) 
-		   * sizeof(Scsi_Tape));
+		   st_template.dev_max * sizeof(Scsi_Tape));
     return 1;
   }
 
-  /* FIXME - if we are hitting this because we are loading a tape module
-  as a loadable driver, we should not use kmalloc - it will allocate
-  a 64Kb region in order to buffer about 32Kb.  Try using 31 blocks
-  instead. */
-  
-  for (i=0; i < st_nbr_buffers; i++) {
-    st_buffers[i] = (ST_buffer *) scsi_init_malloc(sizeof(ST_buffer) - 
-						   1 + st_buffer_size,
-						   GFP_ATOMIC | GFP_DMA);
-    if (st_buffers[i] == NULL) {
-      printk("Not enough memory for buffer %d.\n", i);
+#if ST_RUNTIME_BUFFERS
+  st_nbr_buffers = 0;
+#else
+  target_nbr = st_template.dev_noticed;
+  if (target_nbr < ST_EXTRA_DEVS)
+    target_nbr = ST_EXTRA_DEVS;
+  if (target_nbr > st_max_buffers)
+    target_nbr = st_max_buffers;
+
+  for (i=st_nbr_buffers=0; i < target_nbr; i++) {
+    if (!new_tape_buffer(TRUE)) {
       if (i == 0) {
+	printk("Can't continue without at least one tape buffer.\n");
 	unregister_chrdev(SCSI_TAPE_MAJOR, "st");
-	scsi_init_free((char *) scsi_tapes,
-		       (st_template.dev_noticed + ST_EXTRA_DEVS) 
-		       * sizeof(Scsi_Tape));
 	scsi_init_free((char *) st_buffers,
-		       st_nbr_buffers * sizeof(ST_buffer *));
+		       st_template.dev_max * sizeof(ST_buffer *));
+	scsi_init_free((char *) scsi_tapes,
+		       st_template.dev_max * sizeof(Scsi_Tape));
 	return 1;
       }
-      st_nbr_buffers = i;
       printk("Number of tape buffers adjusted.\n");
       break;
     }
-    else {
-#if DEBUG
-/*    printk("st: Buffer address: %p\n", st_buffers[i]); */
-#endif
-      st_buffers[i]->in_use = 0;
-      st_buffers[i]->writing = 0;
-    }
   }
+#endif
   return 0;
 }
 
@@ -2265,18 +2304,17 @@
   st_registered--;
   if(scsi_tapes != NULL) {
     scsi_init_free((char *) scsi_tapes,
-		   (st_template.dev_noticed + ST_EXTRA_DEVS) 
-		   * sizeof(Scsi_Tape));
+		   st_template.dev_max * sizeof(Scsi_Tape));
 
     if (st_buffers != NULL) {
       for (i=0; i < st_nbr_buffers; i++)
 	if (st_buffers[i] != NULL) {
-	  scsi_init_free((char *) st_buffers[i],
-			 sizeof(ST_buffer) - 1 + st_buffer_size);
+	  scsi_init_free((char *) st_buffers[i]->b_data, st_buffer_size);
+	  scsi_init_free((char *) st_buffers[i], sizeof(ST_buffer));
 	}
       
       scsi_init_free((char *) st_buffers,
-		     st_req_nbr_buffers * sizeof(ST_buffer *));
+		     st_template.dev_max * sizeof(ST_buffer *));
     }
   }
   st_template.dev_max = 0;
diff -u --recursive --new-file v1.3.28/linux/drivers/scsi/st.h linux/drivers/scsi/st.h
--- v1.3.28/linux/drivers/scsi/st.h	Sun Sep  3 12:27:00 1995
+++ linux/drivers/scsi/st.h	Wed Sep 20 08:18:05 1995
@@ -18,7 +18,7 @@
   int writing;
   int last_result;
   int last_result_fatal;
-  unsigned char b_data[1];
+  unsigned char *b_data;
 } ST_buffer;
 
 typedef struct {
diff -u --recursive --new-file v1.3.28/linux/drivers/scsi/st_options.h linux/drivers/scsi/st_options.h
--- v1.3.28/linux/drivers/scsi/st_options.h	Wed Sep 13 12:45:31 1995
+++ linux/drivers/scsi/st_options.h	Wed Sep 20 08:18:05 1995
@@ -3,12 +3,18 @@
 
    Copyright 1995 Kai Makisara.
 
-   Last modified: Sun Sep 10 13:26:02 1995 by root@kai.makisara.fi
+   Last modified: Mon Sep 18 21:00:49 1995 by root@kai.makisara.fi
 */
 
 #ifndef _ST_OPTIONS_H
 #define _ST_OPTIONS_H
 
+/* The driver allocates the tape buffers when needed if ST_RUNTIME_BUFFERS
+   is nonzero. Otherwise a number of buffers are allocated at initialization.
+   The drawback of runtime allocation is that allocation may fail. In any
+   case the driver tries to allocate a new tape buffer when none is free. */
+#define ST_RUNTIME_BUFFERS 0
+
 /* The driver does not wait for some operations to finish before returning
    to the user program if ST_NOWAIT is non-zero. This helps if the SCSI
    adapter does not support multiple outstanding commands. However, the user
@@ -30,15 +36,8 @@
    SENSE. */
 #define ST_DEFAULT_BLOCK 0
 
-/* The tape driver buffer size in kilobytes. When loading as module, the
-   memory block being used is slightly less than a power of two, i.e.,
-   a 64 kB block is used for a 32 kB buffer => we may as well use what is
-   being allocated! */
-#ifdef MODULE
-#define ST_BUFFER_BLOCKS 63
-#else
+/* The tape driver buffer size in kilobytes. */
 #define ST_BUFFER_BLOCKS 32
-#endif
 
 /* The number of kilobytes of data in the buffer that triggers an
    asynchronous write in fixed block mode. See also ST_ASYNC_WRITES
diff -u --recursive --new-file v1.3.28/linux/drivers/sound/soundcard.c linux/drivers/sound/soundcard.c
--- v1.3.28/linux/drivers/sound/soundcard.c	Mon Sep 18 14:54:04 1995
+++ linux/drivers/sound/soundcard.c	Tue Sep 19 12:13:46 1995
@@ -618,10 +618,10 @@
 
 	    for (i = MAP_NR (start_addr); i <= MAP_NR (end_addr); i++)
 	      {
-		if (mem_map[i])
+		if (mem_map[i].reserved || mem_map[i].count)
 		  panic ("sound_mem_init: Page not free (driver incompatible with kernel).\n");
 
-		mem_map[i] = MAP_PAGE_RESERVED;
+		mem_map[i].reserved = 1;
 	      }
 	  }
       }				/* for dev */
diff -u --recursive --new-file v1.3.28/linux/fs/binfmt_elf.c linux/fs/binfmt_elf.c
--- v1.3.28/linux/fs/binfmt_elf.c	Mon Sep 18 14:54:05 1995
+++ linux/fs/binfmt_elf.c	Thu Sep 21 08:53:39 1995
@@ -590,7 +590,7 @@
 					elf_ppnt->p_offset & 0xfffff000);
 			
 #ifdef LOW_ELF_STACK
-			if(elf_ppnt->p_vaddr & 0xfffff000 < elf_stack) 
+			if((elf_ppnt->p_vaddr & 0xfffff000) < elf_stack) 
 				elf_stack = elf_ppnt->p_vaddr & 0xfffff000;
 #endif
 			
diff -u --recursive --new-file v1.3.28/linux/fs/buffer.c linux/fs/buffer.c
--- v1.3.28/linux/fs/buffer.c	Mon Sep 18 14:54:05 1995
+++ linux/fs/buffer.c	Tue Sep 19 13:27:48 1995
@@ -566,7 +566,7 @@
 			 tmp = bh->b_next_free;
 			 if (!bh) break;
 			 
-			 if (mem_map[MAP_NR((unsigned long) bh->b_data)] != 1 ||
+			 if (mem_map[MAP_NR((unsigned long) bh->b_data)].count != 1 ||
 			     bh->b_dirt) {
 				 refile_buffer(bh);
 				 continue;
@@ -614,7 +614,7 @@
 		if(candidate[i] == bh) candidate[i] = NULL;  /* Got last one */
 		if (bh->b_count || bh->b_size != size)
 			 panic("Busy buffer in candidate list\n");
-		if (mem_map[MAP_NR((unsigned long) bh->b_data)] != 1)
+		if (mem_map[MAP_NR((unsigned long) bh->b_data)].count != 1)
 			 panic("Shared buffer in candidate list\n");
 		if (BADNESS(bh)) panic("Buffer in candidate list with BADNESS != 0\n");
 		
@@ -638,7 +638,7 @@
 				tmp = bh->b_next_free;
 				if (!bh) break;
 				
-				if (mem_map[MAP_NR((unsigned long) bh->b_data)] != 1 ||
+				if (mem_map[MAP_NR((unsigned long) bh->b_data)].count != 1 ||
 				    bh->b_dirt) {
 					refile_buffer(bh);
 					continue;
@@ -761,7 +761,7 @@
 		panic("Attempt to refile free buffer\n");
 	if (buf->b_dirt)
 		dispose = BUF_DIRTY;
-	else if (mem_map[MAP_NR((unsigned long) buf->b_data)] > 1)
+	else if (mem_map[MAP_NR((unsigned long) buf->b_data)].count > 1)
 		dispose = BUF_SHARED;
 	else if (buf->b_lock)
 		dispose = BUF_LOCKED;
@@ -1048,7 +1048,7 @@
 	}
 	if (!aligned)
 		return try_to_align(bh, nrbuf, address);
-	mem_map[MAP_NR(page)]++;
+	mem_map[MAP_NR(page)].count++;
 	read_buffers(bh,nrbuf);		/* make sure they are actually read correctly */
 	while (nrbuf-- > 0)
 		brelse(bh[nrbuf]);
@@ -1106,7 +1106,7 @@
 	}
 	buffermem += PAGE_SIZE;
 	bh->b_this_page = tmp;
-	mem_map[MAP_NR(address)]++;
+	mem_map[MAP_NR(address)].count++;
 	buffer_pages[MAP_NR(address)] = bh;
 	read_buffers(arr,block);
 	while (block-- > 0)
@@ -1308,7 +1308,7 @@
 	buffermem -= PAGE_SIZE;
 	buffer_pages[MAP_NR(page)] = NULL;
 	free_page(page);
-	return !mem_map[MAP_NR(page)];
+	return !mem_map[MAP_NR(page)].count;
 }
 
 
@@ -1471,7 +1471,7 @@
 			locked++;
 		if (bh->b_dirt)
 			dirty++;
-		if(mem_map[MAP_NR(((unsigned long) bh->b_data))] !=1) shared++;
+		if(mem_map[MAP_NR(((unsigned long) bh->b_data))].count !=1) shared++;
 		if (bh->b_count)
 			used++, lastused = found;
 		bh = bh->b_next_free;
@@ -1505,7 +1505,7 @@
 	*bhp = bh;
 	page = (unsigned long) bh->b_data;
 	page &= PAGE_MASK;
-	if(mem_map[MAP_NR(page)] != 1) return 0;
+	if(mem_map[MAP_NR(page)].count != 1) return 0;
 	tmp = bh;
 	do {
 		if (!tmp)
diff -u --recursive --new-file v1.3.28/linux/fs/proc/array.c linux/fs/proc/array.c
--- v1.3.28/linux/fs/proc/array.c	Mon Sep 18 14:54:07 1995
+++ linux/fs/proc/array.c	Tue Sep 19 12:32:48 1995
@@ -512,7 +512,7 @@
 			++*dirty;
 		if (pte_page(page) >= high_memory)
 			continue;
-		if (mem_map[MAP_NR(pte_page(page))] > 1)
+		if (mem_map[MAP_NR(pte_page(page))].count > 1)
 			++*shared;
 	} while (address < end);
 }
diff -u --recursive --new-file v1.3.28/linux/fs/proc/link.c linux/fs/proc/link.c
--- v1.3.28/linux/fs/proc/link.c	Mon Sep 18 14:54:07 1995
+++ linux/fs/proc/link.c	Thu Sep 21 08:53:39 1995
@@ -61,7 +61,7 @@
  * looking up the file structure of the newly opened proc fd file, and
  * replacing it with the actual file structure of the process's file
  * descriptor.  This allows plan 9 semantics, so that the returned
- * file descriptor is an dup of the target file descriptor.
+ * file descriptor is a dup of the target file descriptor.
  */
 static int proc_fd_dupf(struct inode * inode, struct file * f)
 {
diff -u --recursive --new-file v1.3.28/linux/fs/proc/mem.c linux/fs/proc/mem.c
--- v1.3.28/linux/fs/proc/mem.c	Thu Sep  7 17:17:18 1995
+++ linux/fs/proc/mem.c	Tue Sep 19 12:31:10 1995
@@ -291,7 +291,7 @@
 
 		set_pte(src_table, pte_mkdirty(*src_table));
 		set_pte(dest_table, *src_table);
-		mem_map[MAP_NR(pte_page(*src_table))]++;
+		mem_map[MAP_NR(pte_page(*src_table))].count++;
 
 		stmp += PAGE_SIZE;
 		dtmp += PAGE_SIZE;
diff -u --recursive --new-file v1.3.28/linux/fs/proc/root.c linux/fs/proc/root.c
--- v1.3.28/linux/fs/proc/root.c	Mon Sep 18 14:54:08 1995
+++ linux/fs/proc/root.c	Fri Sep 22 08:04:12 1995
@@ -328,8 +328,10 @@
 	}
 
 	de = (struct proc_dir_entry *) dir->u.generic_ip;
-	if (!de)
+	if (!de) {
+		iput(dir);
 		return -EINVAL;
+	}
 
 	/* Special case "." and "..": they aren't on the directory list */
 	*result = dir;
@@ -354,8 +356,10 @@
 		if (proc_match(len, name, de))
 			break;
 	}
-	if (!de)
+	if (!de) {
+		iput(dir);
 		return -ENOENT;
+	}
 
 	ino = de->low_ino | (dir->i_ino & ~(0xffff));
 
@@ -371,11 +375,14 @@
 	struct inode ** result)
 {
 	unsigned int pid, c;
-	int i, ino;
+	int i, ino, retval;
 
-	int retval = proc_lookup(dir, name, len, result);
-	if (retval != -ENOENT)
+	dir->i_count++;
+	retval = proc_lookup(dir, name, len, result);
+	if (retval != -ENOENT) {
+		iput(dir);
 		return retval;
+	}
 	
 	pid = 0;
 	while (len-- > 0) {
diff -u --recursive --new-file v1.3.28/linux/include/asm-alpha/page.h linux/include/asm-alpha/page.h
--- v1.3.28/linux/include/asm-alpha/page.h	Sun Sep  3 12:27:01 1995
+++ linux/include/asm-alpha/page.h	Tue Sep 19 12:17:30 1995
@@ -71,9 +71,13 @@
 
 #define PAGE_OFFSET		0xFFFFFC0000000000
 #define MAP_NR(addr)		((((unsigned long) (addr)) - PAGE_OFFSET) >> PAGE_SHIFT)
-#define MAP_PAGE_RESERVED	(1<<31)
 
-typedef unsigned int mem_map_t;
+typedef struct {
+	unsigned count:30,
+		 dirty:1,
+		 reserved:1;
+} mem_map_t;
+
 
 #endif /* __KERNEL__ */
 
diff -u --recursive --new-file v1.3.28/linux/include/asm-alpha/pgtable.h linux/include/asm-alpha/pgtable.h
--- v1.3.28/linux/include/asm-alpha/pgtable.h	Sat Sep  9 15:26:53 1995
+++ linux/include/asm-alpha/pgtable.h	Tue Sep 19 13:37:35 1995
@@ -171,35 +171,30 @@
 
 extern inline int pte_none(pte_t pte)		{ return !pte_val(pte); }
 extern inline int pte_present(pte_t pte)	{ return pte_val(pte) & _PAGE_VALID; }
-extern inline int pte_inuse(pte_t *ptep)	{ return mem_map[MAP_NR(ptep)] != 1; }
+extern inline int pte_inuse(pte_t *ptep)	{ return mem_map[MAP_NR(ptep)].reserved || mem_map[MAP_NR(ptep)].count != 1; }
 extern inline void pte_clear(pte_t *ptep)	{ pte_val(*ptep) = 0; }
 extern inline void pte_reuse(pte_t * ptep)
 {
-	if (!(mem_map[MAP_NR(ptep)] & MAP_PAGE_RESERVED))
-		mem_map[MAP_NR(ptep)]++;
+	if (!mem_map[MAP_NR(ptep)].reserved)
+		mem_map[MAP_NR(ptep)].count++;
 }
 
 extern inline int pmd_none(pmd_t pmd)		{ return !pmd_val(pmd); }
 extern inline int pmd_bad(pmd_t pmd)		{ return (pmd_val(pmd) & ~_PFN_MASK) != _PAGE_TABLE || pmd_page(pmd) > high_memory; }
 extern inline int pmd_present(pmd_t pmd)	{ return pmd_val(pmd) & _PAGE_VALID; }
-extern inline int pmd_inuse(pmd_t *pmdp)	{ return mem_map[MAP_NR(pmdp)] != 1; }
+extern inline int pmd_inuse(pmd_t *pmdp)	{ return mem_map[MAP_NR(pmdp)].reserved || mem_map[MAP_NR(pmdp)].count != 1; }
 extern inline void pmd_clear(pmd_t * pmdp)	{ pmd_val(*pmdp) = 0; }
 extern inline void pmd_reuse(pmd_t * pmdp)
 {
-	if (!(mem_map[MAP_NR(pmdp)] & MAP_PAGE_RESERVED))
-		mem_map[MAP_NR(pmdp)]++;
+	if (!mem_map[MAP_NR(pmdp)].reserved)
+		mem_map[MAP_NR(pmdp)].count++;
 }
 
 extern inline int pgd_none(pgd_t pgd)		{ return !pgd_val(pgd); }
 extern inline int pgd_bad(pgd_t pgd)		{ return (pgd_val(pgd) & ~_PFN_MASK) != _PAGE_TABLE || pgd_page(pgd) > high_memory; }
 extern inline int pgd_present(pgd_t pgd)	{ return pgd_val(pgd) & _PAGE_VALID; }
-extern inline int pgd_inuse(pgd_t *pgdp)	{ return mem_map[MAP_NR(pgdp)] != 1; }
+extern inline int pgd_inuse(pgd_t *pgdp)	{ return mem_map[MAP_NR(pgdp)].reserved; }
 extern inline void pgd_clear(pgd_t * pgdp)	{ pgd_val(*pgdp) = 0; }
-extern inline void pgd_reuse(pgd_t * pgdp)
-{
-	if (!(mem_map[MAP_NR(pgdp)] & MAP_PAGE_RESERVED))
-		mem_map[MAP_NR(pgdp)]++;
-}
 
 /*
  * The following only work if pte_present() is true.
@@ -273,7 +268,7 @@
  */
 extern inline void pte_free_kernel(pte_t * pte)
 {
-	mem_map[MAP_NR(pte)] = 1;
+	mem_map[MAP_NR(pte)].reserved = 0;
 	free_page((unsigned long) pte);
 }
 
@@ -285,7 +280,7 @@
 		if (pmd_none(*pmd)) {
 			if (page) {
 				pmd_set(pmd, page);
-				mem_map[MAP_NR(page)] = MAP_PAGE_RESERVED;
+				mem_map[MAP_NR(page)].reserved = 1;
 				return page + address;
 			}
 			pmd_set(pmd, (pte_t *) BAD_PAGETABLE);
@@ -303,7 +298,7 @@
 
 extern inline void pmd_free_kernel(pmd_t * pmd)
 {
-	mem_map[MAP_NR(pmd)] = 1;
+	mem_map[MAP_NR(pmd)].reserved = 0;
 	free_page((unsigned long) pmd);
 }
 
@@ -315,7 +310,7 @@
 		if (pgd_none(*pgd)) {
 			if (page) {
 				pgd_set(pgd, page);
-				mem_map[MAP_NR(page)] = MAP_PAGE_RESERVED;
+				mem_map[MAP_NR(page)].reserved = 1;
 				return page + address;
 			}
 			pgd_set(pgd, BAD_PAGETABLE);
diff -u --recursive --new-file v1.3.28/linux/include/asm-i386/page.h linux/include/asm-i386/page.h
--- v1.3.28/linux/include/asm-i386/page.h	Sun Sep  3 12:27:02 1995
+++ linux/include/asm-i386/page.h	Tue Sep 19 12:17:30 1995
@@ -81,9 +81,12 @@
 /* This handles the memory map.. */
 #define PAGE_OFFSET		0
 #define MAP_NR(addr)		(((unsigned long)(addr)) >> PAGE_SHIFT)
-#define MAP_PAGE_RESERVED	(1<<15)
 
-typedef unsigned short mem_map_t;
+typedef struct {
+	unsigned count:30,
+		 dirty:1,
+		 reserved:1;
+} mem_map_t;
 
 #endif /* __KERNEL__ */
 
diff -u --recursive --new-file v1.3.28/linux/include/asm-i386/pgtable.h linux/include/asm-i386/pgtable.h
--- v1.3.28/linux/include/asm-i386/pgtable.h	Thu Sep  7 17:17:19 1995
+++ linux/include/asm-i386/pgtable.h	Tue Sep 19 13:33:34 1995
@@ -143,12 +143,12 @@
 
 extern inline int pte_none(pte_t pte)		{ return !pte_val(pte); }
 extern inline int pte_present(pte_t pte)	{ return pte_val(pte) & _PAGE_PRESENT; }
-extern inline int pte_inuse(pte_t *ptep)	{ return mem_map[MAP_NR(ptep)] != 1; }
+extern inline int pte_inuse(pte_t *ptep)	{ return mem_map[MAP_NR(ptep)].reserved || mem_map[MAP_NR(ptep)].count != 1; }
 extern inline void pte_clear(pte_t *ptep)	{ pte_val(*ptep) = 0; }
 extern inline void pte_reuse(pte_t * ptep)
 {
-	if (!(mem_map[MAP_NR(ptep)] & MAP_PAGE_RESERVED))
-		mem_map[MAP_NR(ptep)]++;
+	if (!mem_map[MAP_NR(ptep)].reserved)
+		mem_map[MAP_NR(ptep)].count++;
 }
 
 extern inline int pmd_none(pmd_t pmd)		{ return !pmd_val(pmd); }
@@ -170,13 +170,8 @@
 extern inline int pgd_none(pgd_t pgd)		{ return 0; }
 extern inline int pgd_bad(pgd_t pgd)		{ return 0; }
 extern inline int pgd_present(pgd_t pgd)	{ return 1; }
-extern inline int pgd_inuse(pgd_t * pgdp)	{ return mem_map[MAP_NR(pgdp)] != 1; }
+extern inline int pgd_inuse(pgd_t * pgdp)	{ return mem_map[MAP_NR(pgdp)].reserved; }
 extern inline void pgd_clear(pgd_t * pgdp)	{ }
-extern inline void pgd_reuse(pgd_t * pgdp)
-{
-	if (!(mem_map[MAP_NR(pgdp)] & MAP_PAGE_RESERVED))
-		mem_map[MAP_NR(pgdp)]++;
-}
 
 /*
  * The following only work if pte_present() is true.
@@ -243,7 +238,7 @@
  */
 extern inline void pte_free_kernel(pte_t * pte)
 {
-	mem_map[MAP_NR(pte)] = 1;
+	mem_map[MAP_NR(pte)].reserved = 0;
 	free_page((unsigned long) pte);
 }
 
@@ -255,7 +250,7 @@
 		if (pmd_none(*pmd)) {
 			if (page) {
 				pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) page;
-				mem_map[MAP_NR(page)] = MAP_PAGE_RESERVED;
+				mem_map[MAP_NR(page)].reserved = 1;
 				return page + address;
 			}
 			pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
diff -u --recursive --new-file v1.3.28/linux/include/linux/kdev_t.h linux/include/linux/kdev_t.h
--- v1.3.28/linux/include/linux/kdev_t.h	Mon Sep 18 14:54:09 1995
+++ linux/include/linux/kdev_t.h	Thu Sep 21 08:53:39 1995
@@ -104,11 +104,11 @@
 #else /* __KERNEL__ */
 
 /*
-Some unfortunate programs want their definitions of MAJOR and MINOR
-from the kernel sources.
+Some programs want their definitions of MAJOR and MINOR and MKDEV
+from the kernel sources. These must be the externally visible ones.
 */
 #define MAJOR(dev)	((dev)>>8)
 #define MINOR(dev)	((dev) & 0xff)
-
+#define MKDEV(ma,mi)	((ma)<<8 | (mi))
 #endif /* __KERNEL__ */
 #endif
diff -u --recursive --new-file v1.3.28/linux/include/linux/pci.h linux/include/linux/pci.h
--- v1.3.28/linux/include/linux/pci.h	Mon Sep 18 14:54:09 1995
+++ linux/include/linux/pci.h	Thu Sep 21 15:41:23 1995
@@ -29,8 +29,11 @@
  *	- your exact hardware description. Try to find out
  *	  which device is unknown. It may be you mainboard chipset.
  *	  PCI-CPU bridge or PCI-ISA bridge.
- *	- Send all that to frederic@cao-vlsi.ibp.fr, and I'll add
- *	  your device to the list as soon as possible
+ *	- If you can't find the actual information in your hardware
+ *	  booklet, try to read the references of the chip on the board.
+ *	- Send all that, with the word PCIPROBE in the subject,
+ *	  to frederic@cao-vlsi.ibp.fr, and I'll add your device to 
+ *	  the list as soon as possible
  *		fred.
  */
 
@@ -285,6 +288,8 @@
 #define PCI_DEVICE_ID_SI_501		0x0406
 #define PCI_DEVICE_ID_SI_496		0x0496
 #define PCI_DEVICE_ID_SI_601		0x0601
+#define PCI_DEVICE_ID_SI_5511		0x5511
+#define PCI_DEVICE_ID_SI_5513		0x5513
 
 #define PCI_VENDOR_ID_HP		0x103c
 #define PCI_DEVICE_ID_HP_J2585A		0x1030
@@ -345,6 +350,7 @@
 
 #define PCI_VENDOR_ID_CMD		0x1095
 #define PCI_DEVICE_ID_CMD_640		0x0640
+#define PCI_DEVICE_ID_CMD_646		0x0646
 
 #define PCI_VENDOR_ID_VISION		0x1098
 #define PCI_DEVICE_ID_VISION_QD8500	0x0001
@@ -370,6 +376,9 @@
 
 #define PCI_VENDOR_ID_IMS		0x10e0
 #define PCI_DEVICE_ID_IMS_8849		0x8849
+
+#define PCI_VENDOR_ID_REALTEK		0x10ec
+#define PCI_DEVICE_ID_REALTEK_8300	0x8029
 
 #define PCI_VENDOR_ID_VIA		0x1106
 #define PCI_DEVICE_ID_VIA_82C505	0x0505
diff -u --recursive --new-file v1.3.28/linux/include/linux/proc_fs.h linux/include/linux/proc_fs.h
--- v1.3.28/linux/include/linux/proc_fs.h	Mon Sep 18 14:54:09 1995
+++ linux/include/linux/proc_fs.h	Fri Sep 22 08:30:32 1995
@@ -221,7 +221,6 @@
 extern int proc_readdir(struct inode *, struct file *, void *, filldir_t);
 extern int proc_lookup(struct inode *, const char *, int, struct inode **);
 
-extern struct inode_operations proc_base_inode_operations;
 extern struct inode_operations proc_net_inode_operations;
 extern struct inode_operations proc_netdir_inode_operations;
 extern struct inode_operations proc_scsi_inode_operations;
diff -u --recursive --new-file v1.3.28/linux/ipc/shm.c linux/ipc/shm.c
--- v1.3.28/linux/ipc/shm.c	Fri Sep 15 11:13:03 1995
+++ linux/ipc/shm.c	Tue Sep 19 12:48:34 1995
@@ -664,7 +664,7 @@
 
 done:	/* pte_val(pte) == shp->shm_pages[idx] */
 	current->min_flt++;
-	mem_map[MAP_NR(pte_page(pte))]++;
+	mem_map[MAP_NR(pte_page(pte))].count++;
 	return pte_modify(pte, shmd->vm_page_prot);
 }
 
@@ -764,7 +764,7 @@
 			printk("shm_swap_out: page and pte mismatch\n");
 		set_pte(page_table,
 		  __pte(shmd->vm_pte + SWP_ENTRY(0, idx << SHM_IDX_SHIFT)));
-		mem_map[MAP_NR(pte_page(pte))]--;
+		mem_map[MAP_NR(pte_page(pte))].count--;
 		if (shmd->vm_mm->rss > 0)
 			shmd->vm_mm->rss--;
 		invalid++;
@@ -774,7 +774,7 @@
 		break;
 	}
 
-	if (mem_map[MAP_NR(pte_page(page))] != 1)
+	if (mem_map[MAP_NR(pte_page(page))].count != 1)
 		goto check_table;
 	shp->shm_pages[idx] = swap_nr;
 	if (invalid)
diff -u --recursive --new-file v1.3.28/linux/kernel/ksyms.c linux/kernel/ksyms.c
--- v1.3.28/linux/kernel/ksyms.c	Wed Sep 13 12:45:33 1995
+++ linux/kernel/ksyms.c	Thu Sep 21 15:41:29 1995
@@ -92,11 +92,6 @@
 				off_t offset, int length, 
 				int inode, int func) = 0; /* Dirty hack */
 
-#if defined(CONFIG_PROC_FS)
-extern struct proc_dir_entry scsi_dir[]; 
-extern struct proc_dir_entry scsi_hba_dir[];
-#endif
-
 extern int sys_tz;
 extern int request_dma(unsigned int dmanr, char * deviceID);
 extern void free_dma(unsigned int dmanr);
@@ -290,6 +285,7 @@
 	X(printk),
 	X(sprintf),
 	X(vsprintf),
+	X(kdevname),
 	X(simple_strtoul),
 	X(system_utsname),
 	X(sys_call_table),
@@ -416,11 +412,6 @@
 	 */
 	X(gendisk_head),
 	X(resetup_one_dev),
-
-#if defined(CONFIG_PROC_FS)
-	X(scsi_dir),
-	X(scsi_hba_dir),
-#endif
 	X(dispatch_scsi_info_ptr),
 #endif
 	/* Added to make file system as module */
diff -u --recursive --new-file v1.3.28/linux/mm/filemap.c linux/mm/filemap.c
--- v1.3.28/linux/mm/filemap.c	Sat Sep  9 15:26:53 1995
+++ linux/mm/filemap.c	Tue Sep 19 12:10:56 1995
@@ -153,7 +153,7 @@
 {
 	unsigned long page = SWP_OFFSET(entry);
 
-	mem_map[page]++;
+	mem_map[page].count++;
 	page = (page << PAGE_SHIFT) + PAGE_OFFSET;
 	return mk_pte(page,vma->vm_page_prot);
 }
@@ -173,7 +173,7 @@
 			return 0;
 		set_pte(ptep, pte_mkclean(pte));
 		page = pte_page(pte);
-		mem_map[MAP_NR(page)]++;
+		mem_map[MAP_NR(page)].count++;
 	} else {
 		if (pte_none(pte))
 			return 0;
diff -u --recursive --new-file v1.3.28/linux/mm/memory.c linux/mm/memory.c
--- v1.3.28/linux/mm/memory.c	Fri Sep 15 11:13:03 1995
+++ linux/mm/memory.c	Tue Sep 19 11:54:56 1995
@@ -207,7 +207,7 @@
 		set_pte(new_pte, pte);
 		return;
 	}
-	if (pte_page(pte) > high_memory || (mem_map[MAP_NR(pte_page(pte))] & MAP_PAGE_RESERVED)) {
+	if (pte_page(pte) > high_memory || mem_map[MAP_NR(pte_page(pte))].reserved) {
 		set_pte(new_pte, pte);
 		return;
 	}
@@ -217,7 +217,7 @@
 		pte = pte_mkdirty(pte);
 	set_pte(new_pte, pte_mkold(pte));
 	set_pte(old_pte, pte);
-	mem_map[MAP_NR(pte_page(pte))]++;
+	mem_map[MAP_NR(pte_page(pte))].count++;
 }
 
 static inline int copy_pte_range(pmd_t *dst_pmd, pmd_t *src_pmd, unsigned long address, unsigned long size)
@@ -315,7 +315,7 @@
 		return;
 	if (pte_present(page)) {
 		free_page(pte_page(page));
-		if (mem_map[MAP_NR(pte_page(page))] & MAP_PAGE_RESERVED)
+		if (mem_map[MAP_NR(pte_page(page))].reserved)
 			return;
 		if (current->mm->rss <= 0)
 			return;
@@ -479,7 +479,7 @@
 	do {
 		pte_t oldpage = *pte;
 		pte_clear(pte);
-		if (offset >= high_memory || (mem_map[MAP_NR(offset)] & MAP_PAGE_RESERVED))
+		if (offset >= high_memory || mem_map[MAP_NR(offset)].reserved)
 			set_pte(pte, mk_pte(offset, prot));
 		forget_pte(oldpage);
 		address += PAGE_SIZE;
@@ -558,7 +558,7 @@
 
 	if (page >= high_memory)
 		printk("put_dirty_page: trying to put page %08lx at %08lx\n",page,address);
-	if (mem_map[MAP_NR(page)] != 1)
+	if (mem_map[MAP_NR(page)].count != 1)
 		printk("mem_map disagrees with %08lx at %08lx\n",page,address);
 	pgd = pgd_offset(tsk->mm,address);
 	pmd = pmd_alloc(pgd, address);
@@ -632,9 +632,9 @@
 	/*
 	 * Do we need to copy?
 	 */
-	if (mem_map[MAP_NR(old_page)] != 1) {
+	if (mem_map[MAP_NR(old_page)].count != 1) {
 		if (new_page) {
-			if (mem_map[MAP_NR(old_page)] & MAP_PAGE_RESERVED)
+			if (mem_map[MAP_NR(old_page)].reserved)
 				++vma->vm_mm->rss;
 			copy_page(old_page,new_page);
 			set_pte(page_table, pte_mkwrite(pte_mkdirty(mk_pte(new_page, vma->vm_page_prot))));
@@ -812,7 +812,7 @@
 /* is the page reasonable at all? */
 	if (pte_page(from) >= high_memory)
 		return 0;
-	if (mem_map[MAP_NR(pte_page(from))] & MAP_PAGE_RESERVED)
+	if (mem_map[MAP_NR(pte_page(from))].reserved)
 		return 0;
 /* is the destination ok? */
 	to_dir = pgd_offset(to_area->vm_mm,to_address);
@@ -862,7 +862,7 @@
 		set_pte(from_table, pte_mkdirty(from));
 		delete_from_swap_cache(pte_page(from));
 	}
-	mem_map[MAP_NR(pte_page(from))]++;
+	mem_map[MAP_NR(pte_page(from))].count++;
 	set_pte(to_table, mk_pte(pte_page(from), to_area->vm_page_prot));
 /* Check if we need to do anything at all to the 'from' field */
 	if (!pte_write(from))
@@ -966,7 +966,7 @@
 		free_page(pte_page(page));
 		return;
 	}
-	if (mem_map[MAP_NR(pte_page(page))] > 1 && !(vma->vm_flags & VM_SHARED))
+	if (mem_map[MAP_NR(pte_page(page))].count > 1 && !(vma->vm_flags & VM_SHARED))
 		page = pte_wrprotect(page);
 	++vma->vm_mm->rss;
 	++tsk->maj_flt;
@@ -1041,7 +1041,7 @@
 	entry = mk_pte(page, vma->vm_page_prot);
 	if (write_access) {
 		entry = pte_mkwrite(pte_mkdirty(entry));
-	} else if (mem_map[MAP_NR(page)] > 1 && !(vma->vm_flags & VM_SHARED))
+	} else if (mem_map[MAP_NR(page)].count > 1 && !(vma->vm_flags & VM_SHARED))
 		entry = pte_wrprotect(entry);
 	put_page(page_table, entry);
 }
diff -u --recursive --new-file v1.3.28/linux/mm/swap.c linux/mm/swap.c
--- v1.3.28/linux/mm/swap.c	Mon Sep 18 14:54:11 1995
+++ linux/mm/swap.c	Sat Sep 23 18:39:44 1995
@@ -367,7 +367,7 @@
 		return 0;
 	if (page >= limit)
 		return 0;
-	if (mem_map[MAP_NR(page)] & MAP_PAGE_RESERVED)
+	if (mem_map[MAP_NR(page)].reserved)
 		return 0;
 	if ((pte_dirty(pte) && delete_from_swap_cache(page)) || pte_young(pte))  {
 		set_pte(page_table, pte_mkold(pte));
@@ -380,7 +380,7 @@
 			if (vma->vm_ops->swapout(vma, address - vma->vm_start + vma->vm_offset, page_table))
 				kill_proc(pid, SIGBUS, 1);
 		} else {
-			if (mem_map[MAP_NR(page)] != 1)
+			if (mem_map[MAP_NR(page)].count != 1)
 				return 0;
 			if (!(entry = get_swap_page()))
 				return 0;
@@ -393,7 +393,7 @@
 		return 1;	/* we slept: the process may not exist any more */
 	}
         if ((entry = find_in_swap_cache(page)))  {
-		if (mem_map[MAP_NR(page)] != 1) {
+		if (mem_map[MAP_NR(page)].count != 1) {
 			set_pte(page_table, pte_mkdirty(pte));
 			printk("Aiee.. duplicated cached swap-cache entry\n");
 			return 0;
@@ -407,7 +407,7 @@
 	vma->vm_mm->rss--;
 	pte_clear(page_table);
 	invalidate();
-	entry = mem_map[MAP_NR(page)];
+	entry = mem_map[MAP_NR(page)].count;
 	free_page(page);
 	return entry;
 }
@@ -717,21 +717,21 @@
 
 void free_pages(unsigned long addr, unsigned long order)
 {
-	if (addr < high_memory) {
+	if (MAP_NR(addr) < MAP_NR(high_memory)) {
 		unsigned long flag;
 		mem_map_t * map = mem_map + MAP_NR(addr);
-		if (*map) {
-			if (!(*map & MAP_PAGE_RESERVED)) {
-				save_flags(flag);
-				cli();
-				if (!--*map)  {
-					free_pages_ok(addr, order);
-					delete_from_swap_cache(addr);
-				}
-				restore_flags(flag);
-				if (*map == 1)
-					check_free_buffers(addr);
+		if (map->reserved)
+			return;
+		if (map->count) {
+			save_flags(flag);
+			cli();
+			if (!--map->count) {
+				free_pages_ok(addr, order);
+				delete_from_swap_cache(addr);
 			}
+			restore_flags(flag);
+			if (map->count == 1)
+				check_free_buffers(addr);
 			return;
 		}
 		printk("Trying to free free memory (%08lx): memory probably corrupted\n",addr);
@@ -775,7 +775,7 @@
 		mark_used((unsigned long) addr, high); \
 		restore_flags(flags); \
 		addr = (struct mem_list *) (size + (unsigned long) addr); \
-	} mem_map[MAP_NR((unsigned long) addr)] = 1; \
+	} mem_map[MAP_NR((unsigned long) addr)].count = 1; \
 } while (0)
 
 unsigned long __get_free_pages(int priority, unsigned long order, unsigned long limit)
@@ -956,6 +956,8 @@
 	/*
 	 * Go through process' page directory.
 	 */
+	if (!p->mm || pgd_inuse(p->mm->pgd))
+		return 0;
 	vma = p->mm->mmap;
 	while (vma) {
 		pgd_t * pgd = pgd_offset(p->mm, vma->vm_start);
@@ -1244,7 +1246,7 @@
 
 /*
  * set up the free-area data structures:
- *   - mark all pages MAP_PAGE_RESERVED
+ *   - mark all pages reserved
  *   - mark all memory queues empty
  *   - clear the memory bitmaps
  */
@@ -1266,8 +1268,12 @@
 	mem_map = (mem_map_t *) start_mem;
 	p = mem_map + MAP_NR(end_mem);
 	start_mem = LONG_ALIGN((unsigned long) p);
-	while (p > mem_map)
-		*--p = MAP_PAGE_RESERVED;
+	while (p > mem_map) {
+		--p;
+		p->count = 0;
+		p->dirty = 0;
+		p->reserved = 1;
+	}
 
 	for (i = 0 ; i < NR_MEM_LISTS ; i++) {
 		unsigned long bitmap_size;
