diff -u --recursive --new-file pre2.0.14/linux/.name linux/.name
--- pre2.0.14/linux/.name	Sun May 12 10:16:05 1996
+++ linux/.name	Thu Jan  1 02:00:00 1970
@@ -1 +0,0 @@
-pre-2.0
diff -u --recursive --new-file pre2.0.14/linux/CREDITS linux/CREDITS
--- pre2.0.14/linux/CREDITS	Mon Jun  3 16:46:53 1996
+++ linux/CREDITS	Sat Jun  8 18:55:40 1996
@@ -1175,6 +1175,14 @@
 S: Beaverton, OR 97008
 S: USA
 
+N: John Shifflett
+E: john@geolog.com
+E: jshiffle@netcom.com
+D: Always IN2000 SCSI driver
+D: wd33c93 SCSI driver (linux-m68k)
+S: San Jose, CA
+S: USA
+
 N: Rick Sladkey
 E: jrs@world.std.com
 D: utility hacker: Emacs, NFS server, mount, kmem-ps, UPS debugger, strace, GDB
@@ -1262,6 +1270,8 @@
 
 N: Linus Torvalds
 E: Linus.Torvalds@Helsinki.FI
+W: http://www.cs.helsinki.fi/~torvalds/
+P: 1024/A86B35C5 96 54 50 29 EC 11 44 7A  BE 67 3C 24 03 13 62 C8
 D: General kernel hacker
 S: Kalevankatu 55 B 37
 S: 00180 Helsinki
diff -u --recursive --new-file pre2.0.14/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- pre2.0.14/linux/Documentation/Configure.help	Thu Jun  6 17:42:31 1996
+++ linux/Documentation/Configure.help	Fri Jun  7 16:28:46 1996
@@ -697,17 +697,17 @@
 Set version information on all symbols for modules
 CONFIG_MODVERSIONS
   Usually, modules have to be recompiled whenever you switch to a new
-  kernel. Enabling this option allows you to keep using the same
-  modules even after compiling a new kernel; this requires the program
-  modprobe. All the software needed for module support is in the
-  modules package in sunsite.unc.edu:/pub/Linux/kernel, available via
-  ftp (user: anonymous) and to be extracted with "tar xzvf
-  filename". NOTE1: if you say Y here but don't have the program
-  genksyms (which is also contained in the above mentioned modules
-  package), then the building of your kernel will fail. NOTE2: if you
-  say Y here, then you cannot say Y to the PPP driver, below; the only
-  option is to compile it as a module (PPP is a protocol for sending
-  internet traffic over telephone lines). Therefore, N is a safe bet.
+  kernel. Enabling this option makes it possible, and safe, to use the
+  same modules even after compiling a new kernel; this requires the
+  program modprobe. All the software needed for module support is in
+  the modules package in sunsite.unc.edu:/pub/Linux/kernel, available
+  via ftp (user: anonymous) to be extracted with "tar xzvf filename".
+  NOTE: if you say Y here but don't have the program genksyms (which
+  is also contained in the above mentioned modules package), then the
+  building of your kernel will fail.
+  If you are going to use modules that are generated from non-kernel
+  sources, you would benefit from this option. Otherwise it's not that
+  important. So, N ought to be a safe bet.
 
 Kernel daemon support
 CONFIG_KERNELD
diff -u --recursive --new-file pre2.0.14/linux/Documentation/isdn/README linux/Documentation/isdn/README
--- pre2.0.14/linux/Documentation/isdn/README	Tue May 21 19:52:31 1996
+++ linux/Documentation/isdn/README	Fri Jun  7 16:02:39 1996
@@ -106,6 +106,7 @@
                         driver may not be selected (see "Automatic
                         Assignment") however the size of outgoing packets
                         will be limited correctly.
+	       AT&D0    Ignore DTR
 	       AT&D2    DTR-low-edge: Hang up and return to 
                         command mode (default).
                AT&D3    Same as AT&D2 but also resets all registers.
@@ -157,10 +158,10 @@
                                       1 = DCD follows carrier.
                             Bit 4     0 = CTS follows RTS
                                       1 = Ignore RTS, CTS always on.
-                            Bit 5     0 = Low-edge on DTR: Hang up and
-                                          return to command mode.
+                            Bit 5     0 = return to command mode on DTR low.
                                       1 = Same as 0 but also resets all
                                           registers.
+                                      See also register 13, bit 2
                             Bit 6     0 = DSR always on.
                                       1 = DSR only on if channel is available.
                             Bit 7     0 = Cisco-PPP-flag-hack off (default).
@@ -170,6 +171,8 @@
                                       1 = Direct tty-send.
                             Bit 1:    0 = T.70 protocol (Only for BTX!) off
                                       1 = T.70 protocol (Only for BTX!) on
+                            Bit 2:    0 = Don't hangup on DTR low.
+                                      1 = Hangup on DTR low.
 	     14   0         Layer-2 protocol:
 				      0 = X75/LAPB with I-frames
 				      1 = X75/LAPB with UI-frames
diff -u --recursive --new-file pre2.0.14/linux/Documentation/isdn/README.audio linux/Documentation/isdn/README.audio
--- pre2.0.14/linux/Documentation/isdn/README.audio	Mon Jun  3 16:46:53 1996
+++ linux/Documentation/isdn/README.audio	Fri Jun  7 16:02:39 1996
@@ -1,4 +1,4 @@
-$Id: README.audio,v 1.1 1996/05/19 00:07:35 fritz Exp $
+$Id: README.audio,v 1.3 1996/06/05 02:19:36 fritz Exp $
 
 ISDN subsystem for Linux.
   Description of audio mode.
@@ -89,14 +89,18 @@
     <DLE><ETX>              End of audio data. Emulator stops
                             recording, responding with VCON.
     <DLE><DLE>              Escape sequence for DLE in data stream.
-
-    Currently unsupported DLE sequences:
-
     <DLE>0                  Touchtone "0" received.
          ...
     <DLE>9                  Touchtone "9" received.
     <DLE>#                  Touchtone "#" received.
     <DLE>*                  Touchtone "*" received.
+    <DLE>A                  Touchtone "A" received.
+    <DLE>B                  Touchtone "B" received.
+    <DLE>C                  Touchtone "C" received.
+    <DLE>D                  Touchtone "D" received.
+
+    Currently unsupported DLE sequences:
+
     <DLE>c                  FAX calling tone received.
     <DLE>b                  busy tone received.
     <DLE>q                  quiet. Silence detected after non-silence.
diff -u --recursive --new-file pre2.0.14/linux/Documentation/isdn/README.icn linux/Documentation/isdn/README.icn
--- pre2.0.14/linux/Documentation/isdn/README.icn	Sat Jun  1 20:11:29 1996
+++ linux/Documentation/isdn/README.icn	Fri Jun  7 16:02:39 1996
@@ -1,4 +1,4 @@
-$Id: README.icn,v 1.3 1996/05/19 00:10:37 fritz Exp $
+$Id: README.icn,v 1.4 1996/06/03 19:57:07 fritz Exp $
 
 You can get the ICN-ISDN-card from:
 
Binary files pre2.0.14/linux/Documentation/logo.gif and linux/Documentation/logo.gif differ
diff -u --recursive --new-file pre2.0.14/linux/Documentation/logo.txt linux/Documentation/logo.txt
--- pre2.0.14/linux/Documentation/logo.txt	Thu Jan  1 02:00:00 1970
+++ linux/Documentation/logo.txt	Sun Jun  9 08:51:02 1996
@@ -0,0 +1,13 @@
+This is the full-colour version of the currenly unofficial Linux logo
+("currently unofficial" just means that there has been no paperwork and
+that I haven't really announced it yet).  It was created by Larry Ewing,
+and is freely usable as long as you acknowledge Larry as the original
+artist. 
+
+Note that there are black-and-white versions of this available that
+scale down to smaller sizes and are better for letterheads or whatever
+you want to use it for: for the full range of logos take a look at
+Larry's web-page:
+
+	http://www.isc.tamu.edu/~lewing/linux/
+
diff -u --recursive --new-file pre2.0.14/linux/Documentation/modules.txt linux/Documentation/modules.txt
--- pre2.0.14/linux/Documentation/modules.txt	Thu Jun  6 17:42:32 1996
+++ linux/Documentation/modules.txt	Fri Jun  7 16:28:46 1996
@@ -3,10 +3,6 @@
 the internals of module, but mostly a sample of how to compile
 and use modules.
 
-In this kernel you also have a possibility to create modules that are
-less dependent on the kernel version.  This option can be selected
-during "make config", by enabling CONFIG_MODVERSIONS.
-
 Note: You should ensure that the modules-X.Y.Z.tar.gz you are using
 is the most up to date one for this kernel. The "X.Y.Z" will reflect
 the kernel version at the time of the release of the modules package.
@@ -16,16 +12,21 @@
 package is by looking up the URL listed for "Bjorn Ekwall" in the 
 file ./linux/CREDITS)
 
+
+In the beginning...
+-------------------
+
 Anyway, your first step is to compile the kernel, as explained in the
-file README.  It generally goes like:
+file linux/README.  It generally goes like:
 
 	make config
 	make dep
 	make clean
 	make zImage or make zlilo
 
-In "make config", you select what you want to include in the kernel.
-You will generally select the minimal set that is needed to boot:
+In "make config", you select what you want to include in the "resident"
+kernel and what features you want to have available as loadable modules.
+You will generally select the minimal resident set that is needed to boot:
 
 	The filesystem of your root partition
 	A scsi driver, but see below for a list of SCSI modules!
@@ -35,8 +36,18 @@
 
 	plus those things that you just can't live without...
 
-What has been left out is generally loadable as a modules.
-The set of modules is rapidly increasing, but so far these are known:
+The set of modules is constantly increasing, and you will be able to select
+the option "m" in "make config" for those features that the current kernel
+can offer as loadable modules.
+
+You also have a possibility to create modules that are less dependent on
+the kernel version.  This option can be selected during "make config", by
+enabling CONFIG_MODVERSIONS, and is most useful on "stable" kernel versions,
+such as the kernels from the 1.2 and 2.0 series.
+If you have modules that are based on sources that are not included in
+the official kernel sources, you will certainly like this option...
+
+Here is a sample of the available modules included in the kernel sources:
 
 	Most filesystems: minix, xiafs, msdos, umsdos, sysv, isofs, hpfs,
 			  smbfs, nfs
@@ -59,25 +70,21 @@
 		           Longshine LCS-7260, TEAC CD-55A
 		sonycd535: Sony CDU-531/535, CDU-510/515
 
-	Some misc modules:
+	And a lot of misc modules, such as:
 		lp: line printer
 		binfmt_elf: elf loader
 		binfmt_java: java loader
 		isp16: cdrom interface
+		serial: the serial (tty) interface
 
 When you have made the kernel, you create the modules by doing:
 
 	make modules
 
-This will compile all modules and update the modules directory.
+This will compile all modules and update the linux/modules directory.
 In this directory you will then find a bunch of symbolic links,
 pointing to the various object files in the kernel tree.
-
-As soon as you have rebooted the newly made kernel, you can install
-and remove modules at will with the utilities: "insmod" and "rmmod".
-
-
-Now, after you have made all modules, you can also do:
+Now, after you have created all your modules, you should also do:
 
 	make modules_install
 
@@ -85,17 +92,36 @@
 "/lib/modules/kernel_release/", where "kernel_release" is something
 like 2.0.1, or whatever the current kernel version is...
 
+As soon as you have rebooted the newly made kernel, you can install
+and remove modules at will with the utilities: "insmod" and "rmmod".
+After reading the man-page for insmod, you will also know how easy
+it is to configure a module when you do "insmod" (hint: symbol=value).
+
 
 Nifty features:
+---------------
+
+You also have access to two utilities: "modprobe" and "depmod", where
+modprobe is a "wrapper" for (or extension to) "insmod".
+These utilities use (and maintain) a set of files that describe all the
+modules that are available for the current kernel in the /lib/modules
+hierarchy as well as their interdependencies.
 
-You have access to two utilities: "modprobe" and "depmod".
 Using the modprobe utility, you can load any module like this:
 
 	/sbin/modprobe module
 
-without paying much attention to which kernel you are running.
+without paying much attention to which kernel you are running, or what
+other modules this module depends on.
+
+With the help of the modprobe configuration file: "/etc/conf.modules"
+you can tune the behaviour of modprobe in many ways, including an
+automatic setting of insmod options for each module.
+And, yes, there _are_ man-pages for all this...
+
 To use modprobe successfully, you generally place the following
-command in your /etc/rc.d/rc.S script.
+command in your /etc/rc.d/rc.S script.  (Read more about this in the
+"rc.hints" file in the module utilities package, "modules-x.y.z.tar.gz".)
 
 	/sbin/depmod -a
 
@@ -106,6 +132,82 @@
 
 you will automatically load _both_ the msdos and umsdos modules,
 since umsdos runs piggyback on msdos.
+
+
+The "ultimate" utility:
+-----------------------
+
+OK, you have read all of the above, and feel amply impressed...
+Now, we tell you to forget all about how to install and remove
+loadable modules...
+With the kerneld daemon, all of these chores will be taken care of
+automatically.  Just answer "Y" to CONFIG_KERNELD in "make config",
+and make sure that /sbin/kerneld is started as soon as possible
+after boot and that "/sbin/depmod -a" has been executed for the
+current kernel. (Read more about this in the module utilities package.)
+
+Whenever a program wants the kernel to use a feature that is only
+available as a loadable module, and if the kernel hasn't got the
+module installed yet, the kernel will ask the kerneld deamon to take
+care of the situation and make the best of it.
+
+This is what happens:
+
+	- The kernel notices that a feature is requested that is not
+	  resident in the kernel.
+	- The kernel sends a message to kerneld, with a symbolic
+	  description of the requested feature.
+	- The kerneld daemon asks e.g. modprobe to load a module that
+	  fits this symbolic description.
+	- modprobe looks into its internal "alias" translation table
+	  to see if there is a match.  This table can be reconfigured
+	  and expanded by having "alias" lines in "/etc/conf.modules".
+	- insmod is then asked to insert the module(s) that modprobe
+	  has decided that the kernel needs.  Every module will be
+	  configured according to the "options" lines in "/etc/conf.modules".
+	- modprobe exits and kerneld tells the kernel that the request
+	  succeded (or failed...)
+	- The kernel uses the freshly installed feature just as if it
+	  had been configured into the kernel as a "resident" part.
+
+The icing of the cake is that when an automatically installed module
+has been unused for a period of time (usually 1 minute), the module
+will be automatically removed from the kernel as well.
+
+This makes the kernel use the minimal amount of memory at any given time,
+making it available for more productive use than as just a placeholder for
+unused code.
+
+Actually, this is only a side-effect from the _real_ benefit of kerneld:
+You only have to create a minimal kernel, that is more or less independent
+of the actual hardware setup.  The setup of the "virtual" kernel is
+instead controlled by a configuration file as well as the actual usage
+pattern of the current machine and its kernel.
+This should be good news for maintainers of multiple machines as well as
+for maintainers of distributions.
+
+To use kerneld with the least amount of "hassle", you need modprobe from
+a release that can be considered "recent" w.r.t. your kernel, and also
+a configuration file for modprobe ("/etc/conf.modules").
+Since modprobe already knows about most modules, the minimal configuration
+file could look something like this:
+
+	alias scsi_hostadapter aha1542  # or whatever SCSI adapter you have
+	alias eth0 3c509	# or whatever net adapter you have
+	# you might need an "options" line for some net adapters:
+	options 3c509 io=0x300 irq=10
+	# you might also need an "options" line for some other module:
+	options cdu31a cdu31a_port=0x1f88 sony_pas_init=1
+
+You could add these lines as well, but they are only "cosmetic":
+
+	alias net-pf-3 off	# no ax25 module available (yet)
+	alias net-pf-4 off	# if you don't use the ipx module
+	alias net-pf-5 off	# if you don't use the appletalk module
+
+Finally, for the "purists":
+You can name the modprobe configuration either "/etc/conf.modules" or
+"/etc/modules.conf", since modprobe knows what to do in each case...
 
 
 Written by:
diff -u --recursive --new-file pre2.0.14/linux/MAINTAINERS linux/MAINTAINERS
--- pre2.0.14/linux/MAINTAINERS	Mon Jun  3 16:46:53 1996
+++ linux/MAINTAINERS	Sun Jun  9 12:47:01 1996
@@ -318,6 +318,12 @@
 W:	http://www.advansys.com/linux
 S:	Maintained
 
+AHA152X SCSI DRIVER
+P:	Juergen E. Fischer
+M:	Juergen Fischer <fischer@et-inf.fho-emden.de>
+L:	linux-scsi@vger.rutgers.edu
+S:	Maintained
+
 CREDITS FILE
 P:	John A. Martin
 M:	jam@acm.org
diff -u --recursive --new-file pre2.0.14/linux/Makefile linux/Makefile
--- pre2.0.14/linux/Makefile	Thu Jun  6 22:35:43 1996
+++ linux/Makefile	Fri Jun  7 11:55:00 1996
@@ -1,6 +1,6 @@
-VERSION = 1
-PATCHLEVEL = 99
-SUBLEVEL = 14
+VERSION = 2
+PATCHLEVEL = 0
+SUBLEVEL = 0
 
 ARCH = i386
 
diff -u --recursive --new-file pre2.0.14/linux/Rules.make linux/Rules.make
--- pre2.0.14/linux/Rules.make	Tue Apr  2 13:32:18 1996
+++ linux/Rules.make	Fri Jun  7 16:28:45 1996
@@ -146,9 +146,10 @@
 
 MODINCL = $(TOPDIR)/include/linux/modules
 
+# The -w option (enable warnings) for /bin/genksyms will return here in 2.1
 $(MODINCL)/%.ver: %.c
-	@if [ ! -x /sbin/genksyms ]; then echo "Please read: README.modules"; fi
-	$(CC) $(CFLAGS) -E -D__GENKSYMS__ $< | /sbin/genksyms -w $(MODINCL)
+	@if [ ! -x /sbin/genksyms ]; then echo "Please read: Documentation/modules.txt"; fi
+	$(CC) $(CFLAGS) -E -D__GENKSYMS__ $< | /sbin/genksyms $(MODINCL)
 
 $(addprefix $(MODINCL)/,$(SYMTAB_OBJS:.o=.ver)): $(TOPDIR)/include/linux/autoconf.h
 
diff -u --recursive --new-file pre2.0.14/linux/arch/alpha/defconfig linux/arch/alpha/defconfig
--- pre2.0.14/linux/arch/alpha/defconfig	Mon May 20 08:20:58 1996
+++ linux/arch/alpha/defconfig	Fri Jun  7 14:44:14 1996
@@ -19,6 +19,7 @@
 #
 CONFIG_NATIVE=y
 # CONFIG_ALPHA_AVANTI is not set
+# CONFIG_ALPHA_XL is not set
 # CONFIG_ALPHA_CABRIOLET is not set
 # CONFIG_ALPHA_EB66 is not set
 # CONFIG_ALPHA_EB66P is not set
@@ -27,10 +28,12 @@
 # CONFIG_ALPHA_PC164 is not set
 # CONFIG_ALPHA_JENSEN is not set
 # CONFIG_ALPHA_NONAME is not set
+# CONFIG_ALPHA_MIKASA is not set
+# CONFIG_ALPHA_ALCOR is not set
 # CONFIG_ALPHA_P2K is not set
 CONFIG_PCI=y
 CONFIG_ALPHA_EV5=y
-CONFIG_ALPHA_ALCOR=y
+CONFIG_ALPHA_CIA=y
 # CONFIG_SERIAL_ECHO is not set
 # CONFIG_TGA_CONSOLE is not set
 CONFIG_NET=y
@@ -45,7 +48,7 @@
 # CONFIG_BLK_DEV_IDE is not set
 
 #
-# Please see drivers/block/README.ide for help/info on IDE drives
+# Please see Documentation/ide.txt for help/info on IDE drives
 #
 # CONFIG_BLK_DEV_HD_ONLY is not set
 
@@ -91,7 +94,7 @@
 CONFIG_SCSI=y
 
 #
-# SCSI support type (disk, tape, CDrom)
+# SCSI support type (disk, tape, CD-ROM)
 #
 CONFIG_BLK_DEV_SD=y
 # CONFIG_CHR_DEV_ST is not set
@@ -107,33 +110,33 @@
 #
 # SCSI low-level drivers
 #
-# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_7000FASST is not set
 # CONFIG_SCSI_AHA152X is not set
 # CONFIG_SCSI_AHA1542 is not set
 # CONFIG_SCSI_AHA1740 is not set
 # CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_AM53C974 is not set
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
 # CONFIG_SCSI_EATA_DMA is not set
 # CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_U14_34F is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_NCR53C406A is not set
 CONFIG_SCSI_NCR53C7xx=y
 CONFIG_SCSI_NCR53C7xx_sync=y
 CONFIG_SCSI_NCR53C7xx_FAST=y
 # CONFIG_SCSI_NCR53C7xx_DISCONNECT is not set
-# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_PPA is not set
 # CONFIG_SCSI_PAS16 is not set
 # CONFIG_SCSI_QLOGIC_FAS is not set
 # CONFIG_SCSI_SEAGATE is not set
 # CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
 # CONFIG_SCSI_ULTRASTOR is not set
-# CONFIG_SCSI_7000FASST is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_PPA is not set
-# CONFIG_SCSI_AM53C974 is not set
 
 #
 # Network device support
@@ -184,7 +187,6 @@
 CONFIG_ISO9660_FS=y
 # CONFIG_HPFS_FS is not set
 # CONFIG_SYSV_FS is not set
-# CONFIG_AFFS_FS is not set
 # CONFIG_UFS_FS is not set
 
 #
@@ -196,11 +198,12 @@
 # CONFIG_STALDRV is not set
 # CONFIG_RISCOM8 is not set
 # CONFIG_PRINTER is not set
+CONFIG_MOUSE=y
+# CONFIG_ATIXL_BUSMOUSE is not set
 # CONFIG_BUSMOUSE is not set
+# CONFIG_MS_BUSMOUSE is not set
 CONFIG_PSMOUSE=y
 # CONFIG_82C710_MOUSE is not set
-# CONFIG_MS_BUSMOUSE is not set
-# CONFIG_ATIXL_BUSMOUSE is not set
 # CONFIG_UMISC is not set
 # CONFIG_QIC02_TAPE is not set
 # CONFIG_FTAPE is not set
diff -u --recursive --new-file pre2.0.14/linux/arch/alpha/kernel/bios32.c linux/arch/alpha/kernel/bios32.c
--- pre2.0.14/linux/arch/alpha/kernel/bios32.c	Wed Jun  5 10:41:27 1996
+++ linux/arch/alpha/kernel/bios32.c	Sat Jun  8 11:24:57 1996
@@ -87,7 +87,10 @@
 
 #if PCI_MODIFY
 
-#if defined(CONFIG_ALPHA_MIKASA) || defined(CONFIG_ALPHA_ALCOR)
+/* NOTE: we can't just blindly use 64K for machines with EISA busses; they
+   may also have PCI-PCI bridges present, and then we'd configure the bridge
+   incorrectly */
+#if 0
 static unsigned int	io_base	 = 64*KB;	/* <64KB are (E)ISA ports */
 #else
 static unsigned int	io_base	 = 0xb000;
@@ -122,7 +125,7 @@
 	 *       itself as a bridge... :-(
 	 */
         if (dev->vendor == 0x8086 && dev->device == 0x0482) {
-          DBG_DEVS(("disable_dev: ignoring...\n"));
+          DBG_DEVS(("disable_dev: ignoring PCEB...\n"));
           return;
         }
 #endif
@@ -148,6 +151,17 @@
 	unsigned int base, mask, size, reg;
 	unsigned int alignto;
 
+#if defined(CONFIG_ALPHA_MIKASA) || defined(CONFIG_ALPHA_ALCOR)
+	/*
+	 * HACK: the PCI-to-EISA bridge does not seem to identify
+	 *       itself as a bridge... :-(
+	 */
+        if (dev->vendor == 0x8086 && dev->device == 0x0482) {
+          DBG_DEVS(("layout_dev: ignoring PCEB...\n"));
+          return;
+        }
+#endif
+
 	bus = dev->bus;
 	pcibios_read_config_word(bus->number, dev->devfn, PCI_COMMAND, &cmd);
 
@@ -352,7 +366,7 @@
 		 */
 		pcibios_read_config_dword(bridge->bus->number, bridge->devfn,
 					  0x1c, &l);
-		l = (l & 0xffff0000) | (bio >> 8) | ((tio - 1) & 0xf000);
+		l = (l & 0xffff0000) | ((bio >> 8) & 0x00f0) | ((tio - 1) & 0xf000);
 		pcibios_write_config_dword(bridge->bus->number, bridge->devfn,
 					   0x1c, l);
 		/*
diff -u --recursive --new-file pre2.0.14/linux/arch/alpha/kernel/cia.c linux/arch/alpha/kernel/cia.c
--- pre2.0.14/linux/arch/alpha/kernel/cia.c	Wed Jun  5 10:41:27 1996
+++ linux/arch/alpha/kernel/cia.c	Sat Jun  8 11:24:57 1996
@@ -138,6 +138,7 @@
 		DBG(("conf_read: TYPE1 access\n"));
 	}
 
+	mb();
 	draina();
 	CIA_mcheck_expected = 1;
 	CIA_mcheck_taken = 0;
@@ -159,7 +160,7 @@
 	 * know).  When we build kernels for one particular platform
 	 * then we can make this conditional on the type.
 	 */
-#if 1
+#if 0
 	draina();
 
 	/* now look for any errors */
@@ -229,7 +230,7 @@
 	 * know).  When we build kernels for one particular platform
 	 * then we can make this conditional on the type.
 	 */
-#if 1
+#if 0
 	draina();
 
 	/* now look for any errors */
@@ -439,8 +440,8 @@
 void cia_machine_check(unsigned long vector, unsigned long la_ptr,
 			 struct pt_regs * regs)
 {
-#if 1
-        printk("CIA machine check\n") ;
+#if 0
+        printk("CIA machine check ignored\n") ;
 #else
 	struct el_common *mchk_header;
 	struct el_CIA_sysdata_mcheck *mchk_sysdata;
@@ -470,16 +471,23 @@
 	 * Check if machine check is due to a badaddr() and if so,
 	 * ignore the machine check.
 	 */
-	if (CIA_mcheck_expected && (mchk_sysdata->epic_dcsr && 0x0c00UL)) {
+	mb();
+	mb();
+	if (CIA_mcheck_expected/* && (mchk_sysdata->epic_dcsr && 0x0c00UL)*/) {
+		DBG(("CIA machine check expected\n"));
 		CIA_mcheck_expected = 0;
 		CIA_mcheck_taken = 1;
 		mb();
 		mb();
+		draina();
 		cia_pci_clr_err();
 		wrmces(0x7);
 		mb();
-		draina();
 	}
+#if 1
+	else
+	  printk("CIA machine check NOT expected\n") ;
+#endif
 #endif
 }
 
diff -u --recursive --new-file pre2.0.14/linux/arch/alpha/kernel/entry.S linux/arch/alpha/kernel/entry.S
--- pre2.0.14/linux/arch/alpha/kernel/entry.S	Sat Apr 27 15:19:44 1996
+++ linux/arch/alpha/kernel/entry.S	Sat Jun  8 11:09:03 1996
@@ -757,5 +757,5 @@
 	.quad sys_setfsuid, sys_setfsgid, sys_ustat, sys_statfs, sys_fstatfs
 	.quad sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler, sys_sched_yield
 	.quad sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, do_entSys /* sys_afs_syscall */, sys_newuname
-	.quad sys_nanosleep, do_entSys, do_entSys, do_entSys, do_entSys
+	.quad sys_nanosleep, sys_mremap, do_entSys, do_entSys, do_entSys
 	.quad do_entSys, do_entSys, do_entSys, do_entSys, do_entSys
diff -u --recursive --new-file pre2.0.14/linux/arch/alpha/kernel/irq.c linux/arch/alpha/kernel/irq.c
--- pre2.0.14/linux/arch/alpha/kernel/irq.c	Wed Jun  5 10:41:27 1996
+++ linux/arch/alpha/kernel/irq.c	Sat Jun  8 11:24:57 1996
@@ -193,6 +193,13 @@
 		/* .. then the master */
 		outb(0xE0 | irq, 0x20);
 	}
+#if defined(CONFIG_ALPHA_ALCOR)
+	/* on ALCOR, need to dismiss interrupt via GRU */
+	*(int *)GRU_INT_CLEAR = 0x80000000; 
+	mb();
+	*(int *)GRU_INT_CLEAR = 0x00000000;
+	mb();
+#endif /* CONFIG_ALPHA_ALCOR */
 }
 
 int request_irq(unsigned int irq, 
diff -u --recursive --new-file pre2.0.14/linux/arch/i386/kernel/bios32.c linux/arch/i386/kernel/bios32.c
--- pre2.0.14/linux/arch/i386/kernel/bios32.c	Tue Nov 14 07:35:31 1995
+++ linux/arch/i386/kernel/bios32.c	Sat Jun  8 11:10:49 1996
@@ -441,14 +441,6 @@
 				bios32_indirect.address = bios32_entry = check->fields.entry;
 				printk ("pcibios_init : BIOS32 Service Directory entry at 0x%lx\n", bios32_entry);
 			}
-		} else {
-			printk ("pcibios_init : multiple entries, mail drew@colorado.edu\n");
-			/*
-			 * Jeremy Fitzhardinge reports at least one PCI BIOS
-			 * with two different service directories, and as both
-			 * worked for him, we'll just mention the fact, and
-			 * not actually disallow it..
-			 */
 		}
 	}
 #ifdef CONFIG_PCI
diff -u --recursive --new-file pre2.0.14/linux/drivers/cdrom/sbpcd.c linux/drivers/cdrom/sbpcd.c
--- pre2.0.14/linux/drivers/cdrom/sbpcd.c	Thu Jun  6 17:42:34 1996
+++ linux/drivers/cdrom/sbpcd.c	Fri Jun  7 15:28:13 1996
@@ -4457,8 +4457,10 @@
 	INIT_REQUEST;
 	sti();
 	
-	if ((CURRENT == NULL) || CURRENT->rq_status == RQ_INACTIVE)
-		goto err_done;
+	if ((CURRENT == NULL) || CURRENT->rq_status == RQ_INACTIVE) {
+		CLEAR_INTR;
+		return;
+	}
 	if (CURRENT -> sector == -1)
 		goto err_done;
 	if (CURRENT->cmd != READ)
diff -u --recursive --new-file pre2.0.14/linux/drivers/char/Config.in linux/drivers/char/Config.in
--- pre2.0.14/linux/drivers/char/Config.in	Thu Jun  6 17:42:34 1996
+++ linux/drivers/char/Config.in	Sat Jun  8 11:21:15 1996
@@ -5,7 +5,7 @@
 comment 'Character devices'
 
 tristate 'Standard/generic serial support' CONFIG_SERIAL
-bool 'Digiboard PC/X Support' CONFIG_DIGI
+bool 'Digiboard PC/Xx Support' CONFIG_DIGI
 tristate 'Cyclades async mux support' CONFIG_CYCLADES
 bool 'Stallion multiport serial support' CONFIG_STALDRV
 if [ "$CONFIG_STALDRV" = "y" ]; then
diff -u --recursive --new-file pre2.0.14/linux/drivers/char/consolemap.c linux/drivers/char/consolemap.c
--- pre2.0.14/linux/drivers/char/consolemap.c	Sat Jun  1 20:11:30 1996
+++ linux/drivers/char/consolemap.c	Sat Jun  8 16:14:39 1996
@@ -58,14 +58,14 @@
     0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
     0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
     0x0028, 0x0029, 0x002a, 0x2192, 0x2190, 0x2191, 0x2193, 0x002f,
-    0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
+    0x2588, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
     0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
     0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
     0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
     0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
     0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x00a0,
     0x25c6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1,
-    0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0xf800,
+    0x2591, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0xf800,
     0xf801, 0x2500, 0xf803, 0xf804, 0x251c, 0x2524, 0x2534, 0x252c,
     0x2502, 0x2264, 0x2265, 0x03c0, 0x2260, 0x00a3, 0x00b7, 0x007f,
     0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
diff -u --recursive --new-file pre2.0.14/linux/drivers/char/serial.c linux/drivers/char/serial.c
--- pre2.0.14/linux/drivers/char/serial.c	Thu Jun  6 22:35:44 1996
+++ linux/drivers/char/serial.c	Fri Jun  7 12:41:32 1996
@@ -17,7 +17,7 @@
  *
  *  rs_set_termios fixed to look also for changes of the input
  *      flags INPCK, BRKINT, PARMRK, IGNPAR and IGNBRK.
- *                                            Bernd Anhdupl 05/17/96.
+ *                                            Bernd Anhäupl 05/17/96.
  * 
  * This module exports the following rs232 io functions:
  *
diff -u --recursive --new-file pre2.0.14/linux/drivers/isdn/icn/icn.c linux/drivers/isdn/icn/icn.c
--- pre2.0.14/linux/drivers/isdn/icn/icn.c	Tue May 21 19:52:35 1996
+++ linux/drivers/isdn/icn/icn.c	Fri Jun  7 16:02:40 1996
@@ -1,4 +1,4 @@
-/* $Id: icn.c,v 1.22 1996/05/17 15:46:41 fritz Exp $
+/* $Id: icn.c,v 1.24 1996/06/06 13:58:33 fritz Exp $
  *
  * ISDN low-level module for the ICN active ISDN-Card.
  *
@@ -19,6 +19,12 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  *
  * $Log: icn.c,v $
+ * Revision 1.24  1996/06/06 13:58:33  fritz
+ * Changed code to be architecture independent
+ *
+ * Revision 1.23  1996/06/03 19:59:00  fritz
+ * Fixed typos.
+ *
  * Revision 1.22  1996/05/17 15:46:41  fritz
  * Removed own queue management.
  * Changed queue management to use sk_buffs.
@@ -113,7 +119,7 @@
 #undef MAP_DEBUG
 
 static char
-*revision = "$Revision: 1.22 $";
+*revision = "$Revision: 1.24 $";
 
 static int icn_addcard(int, char *, char *);
 
@@ -315,7 +321,8 @@
                                 card->rcvidx[channel] = 0;
                                 eflag = 0;
                         } else {
-                                memcpy(&card->rcvbuf[channel][card->rcvidx[channel]], rbuf_d, cnt);
+                                memcpy_fromio(&card->rcvbuf[channel][card->rcvidx[channel]],
+                                              rbuf_d, cnt);
                                 card->rcvidx[channel] += cnt;
                                 eflag = rbuf_f;
                         }
@@ -554,8 +561,8 @@
 
         if (icn_trymaplock_channel(card,mch)) {
                 avail = msg_avail;
-                for (left = avail, i = msg_o; left > 0; i++, left--) {
-                        c = dev.shmem->comm_buffers.iopc_buf[i & 0xff];
+                for (left = avail, i = readb(&msg_o); left > 0; i++, left--) {
+                        c = readb(&dev.shmem->comm_buffers.iopc_buf[i & 0xff]);
                         save_flags(flags);
                         cli();
                         *card->msg_buf_write++ = (c == 0xff) ? '\n' : c;
@@ -613,7 +620,7 @@
                                         card->iptr++;
                         }
                 }
-                msg_o = (msg_o + avail) & 0xff;
+                writeb((readb(&msg_o) + avail) & 0xff, &msg_o);
                 icn_release_channel();
         }
         if (avail) {
@@ -691,8 +698,8 @@
 #ifdef BOOT_DEBUG
                 printk(KERN_DEBUG "Loader %d ?\n", cardnumber);
 #endif
-                if (dev.shmem->data_control.scns ||
-                    dev.shmem->data_control.scnr) {
+                if (readb(&dev.shmem->data_control.scns) ||
+                    readb(&dev.shmem->data_control.scnr)) {
                         if (timer++ > 5) {
                                 printk(KERN_WARNING
                                        "icn: Boot-Loader %d timed out.\n",
@@ -744,6 +751,7 @@
 {
         int ret;
         ulong flags;
+        unsigned char codebuf[ICN_CODE_STAGE1];
 
 #ifdef BOOT_DEBUG
         printk(KERN_DEBUG "icn_loadboot called, buffaddr=%08lx\n", (ulong) buffer);
@@ -789,8 +797,6 @@
         SLEEP(1);
         save_flags(flags);
         cli();
-        dev.channel = 1;                                           /* Force Mapping    */
-        dev.mcard   = NULL;
 #ifdef BOOT_DEBUG
         printk(KERN_DEBUG "Map Bank 0\n");
 #endif
@@ -798,7 +804,8 @@
         icn_lock_channel(card,0);                                  /* Lock Bank 0      */
         restore_flags(flags);
         SLEEP(1);
-        memcpy_fromfs(dev.shmem, buffer, ICN_CODE_STAGE1);         /* Copy code        */
+        memcpy_fromfs(codebuf, buffer, ICN_CODE_STAGE1);           /* Copy code        */
+        memcpy_toio(dev.shmem, codebuf, ICN_CODE_STAGE1);
 #ifdef BOOT_DEBUG
         printk(KERN_DEBUG "Bootloader transfered\n");
 #endif
@@ -814,7 +821,8 @@
                 icn_lock_channel(card,2);                          /* Lock Bank 8     */
                 restore_flags(flags);
                 SLEEP(1);
-                memcpy_fromfs(dev.shmem, buffer, ICN_CODE_STAGE1); /* Copy code       */
+                memcpy_fromfs(codebuf, buffer, ICN_CODE_STAGE1);   /* Copy code        */
+                memcpy_toio(dev.shmem, codebuf, ICN_CODE_STAGE1);
 #ifdef BOOT_DEBUG
                 printk(KERN_DEBUG "Bootloader transfered\n");
 #endif
@@ -887,7 +895,7 @@
         sbuf_n = 0x20;
         timer = 0;
         while (1) {
-                if (cmd_o || cmd_i) {
+                if (readb(&cmd_o) || readb(&cmd_i)) {
 #ifdef BOOT_DEBUG
                         printk(KERN_DEBUG "Proto?\n");
 #endif
@@ -984,8 +992,9 @@
                         *card->msg_buf_write++ = '>';
                         if (card->msg_buf_write > card->msg_buf_end)
                                 card->msg_buf_write = card->msg_buf;
-                        for (p = msg, pp = cmd_i, i = count; i > 0; i--, p++, pp++) {
-                                dev.shmem->comm_buffers.pcio_buf[pp & 0xff] = (*p == '\n') ? 0xff : *p;
+                        for (p = msg, pp = readb(&cmd_i), i = count; i > 0; i--, p++, pp++) {
+                                writeb((*p == '\n') ? 0xff : *p,
+                                       &dev.shmem->comm_buffers.pcio_buf[pp & 0xff]);
                                 *card->msg_buf_write++ = *p;
                                 if ((*p == '\n') && (i > 1)) {
                                         *card->msg_buf_write++ = '>';
@@ -1003,7 +1012,7 @@
                         cmd.driver = card->myid;
                         cmd.arg = ocount;
                         card->interface.statcallb(&cmd);
-                        cmd_i = (cmd_i + count) & 0xff;
+                        writeb((readb(&cmd_i) + count) & 0xff, &cmd_i);
                         icn_release_channel();
                         waitflg = 0;
                 } else
@@ -1550,6 +1559,8 @@
 
         memset(&dev, 0, sizeof(icn_dev));
         dev.shmem = (icn_shmem *) (membase & 0x0ffc000);
+        dev.channel = -1;
+        dev.mcard   = NULL;
 
         /* No symbols to export, hide all symbols */
         register_symtab(NULL);
diff -u --recursive --new-file pre2.0.14/linux/drivers/isdn/icn/icn.h linux/drivers/isdn/icn/icn.h
--- pre2.0.14/linux/drivers/isdn/icn/icn.h	Mon May 20 08:20:59 1996
+++ linux/drivers/isdn/icn/icn.h	Fri Jun  7 16:02:40 1996
@@ -1,4 +1,4 @@
-/* $Id: icn.h,v 1.17 1996/05/18 00:47:04 fritz Exp $
+/* $Id: icn.h,v 1.19 1996/06/06 13:58:35 fritz Exp $
  *
  * ISDN lowlevel-module for the ICN active ISDN-Card.
  *
@@ -19,6 +19,12 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  *
  * $Log: icn.h,v $
+ * Revision 1.19  1996/06/06 13:58:35  fritz
+ * Changed code to be architecture independent
+ *
+ * Revision 1.18  1996/06/03 19:59:30  fritz
+ * Removed include of config.h
+ *
  * Revision 1.17  1996/05/18 00:47:04  fritz
  * Removed callback debug code.
  *
@@ -276,46 +282,50 @@
 #define ICN_BANK   (card->port+3)
 
 /* Return true, if there is a free transmit-buffer */
-#define sbfree (((dev.shmem->data_control.scns+1) & 0xf) != \
-                dev.shmem->data_control.scnr)
+#define sbfree (((readb(&dev.shmem->data_control.scns)+1) & 0xf) != \
+                readb(&dev.shmem->data_control.scnr))
 
 /* Switch to next transmit-buffer */
-#define sbnext (dev.shmem->data_control.scns = \
-               ((dev.shmem->data_control.scns+1) & 0xf))
+#define sbnext (writeb((readb(&dev.shmem->data_control.scns)+1) & 0xf, \
+                       &dev.shmem->data_control.scns))
 
 /* Shortcuts for transmit-buffer-access */
 #define sbuf_n dev.shmem->data_control.scns
-#define sbuf_d dev.shmem->data_buffers.send_buf[sbuf_n].data
-#define sbuf_l dev.shmem->data_buffers.send_buf[sbuf_n].length
-#define sbuf_f dev.shmem->data_buffers.send_buf[sbuf_n].endflag
+#define sbuf_d dev.shmem->data_buffers.send_buf[readb(&sbuf_n)].data
+#define sbuf_l dev.shmem->data_buffers.send_buf[readb(&sbuf_n)].length
+#define sbuf_f dev.shmem->data_buffers.send_buf[readb(&sbuf_n)].endflag
 
 /* Return true, if there is receive-data is available */
-#define rbavl  (dev.shmem->data_control.ecnr != \
-                dev.shmem->data_control.ecns)
+#define rbavl  (readb(&dev.shmem->data_control.ecnr) != \
+                readb(&dev.shmem->data_control.ecns))
 
 /* Switch to next receive-buffer */
-#define rbnext (dev.shmem->data_control.ecnr = \
-               ((dev.shmem->data_control.ecnr+1) & 0xf))
+#define rbnext (writeb((readb(&dev.shmem->data_control.ecnr)+1) & 0xf, \
+                       &dev.shmem->data_control.ecnr))
 
 /* Shortcuts for receive-buffer-access */
 #define rbuf_n dev.shmem->data_control.ecnr
-#define rbuf_d dev.shmem->data_buffers.receive_buf[rbuf_n].data
-#define rbuf_l dev.shmem->data_buffers.receive_buf[rbuf_n].length
-#define rbuf_f dev.shmem->data_buffers.receive_buf[rbuf_n].endflag
+#define rbuf_d dev.shmem->data_buffers.receive_buf[readb(&rbuf_n)].data
+#define rbuf_l dev.shmem->data_buffers.receive_buf[readb(&rbuf_n)].length
+#define rbuf_f dev.shmem->data_buffers.receive_buf[readb(&rbuf_n)].endflag
 
 /* Shortcuts for command-buffer-access */
 #define cmd_o (dev.shmem->comm_control.pcio_o)
 #define cmd_i (dev.shmem->comm_control.pcio_i)
 
 /* Return free space in command-buffer */
-#define cmd_free ((cmd_i>=cmd_o)?0x100-cmd_i+cmd_o:cmd_o-cmd_i)
+#define cmd_free ((readb(&cmd_i)>=readb(&cmd_o))? \
+                  0x100-readb(&cmd_i)+readb(&cmd_o): \
+                  readb(&cmd_o)-readb(&cmd_i))
 
 /* Shortcuts for message-buffer-access */
 #define msg_o (dev.shmem->comm_control.iopc_o)
 #define msg_i (dev.shmem->comm_control.iopc_i)
 
 /* Return length of Message, if avail. */
-#define msg_avail ((msg_o>msg_i)?0x100-msg_o+msg_i:msg_i-msg_o)
+#define msg_avail ((readb(&msg_o)>readb(&msg_i))? \
+                   0x100-readb(&msg_o)+readb(&msg_i): \
+                   readb(&msg_i)-readb(&msg_o))
 
 #define CID (card->interface.id)
 
diff -u --recursive --new-file pre2.0.14/linux/drivers/isdn/isdn_audio.c linux/drivers/isdn/isdn_audio.c
--- pre2.0.14/linux/drivers/isdn/isdn_audio.c	Mon May 20 08:20:59 1996
+++ linux/drivers/isdn/isdn_audio.c	Fri Jun  7 16:02:40 1996
@@ -1,8 +1,9 @@
-/* $Id: isdn_audio.c,v 1.4 1996/05/17 03:48:01 fritz Exp $
+/* $Id: isdn_audio.c,v 1.6 1996/06/06 14:43:31 fritz Exp $
  *
  * Linux ISDN subsystem, audio conversion and compression (linklevel).
  *
  * Copyright 1994,95,96 by Fritz Elfert (fritz@wuemaus.franken.de)
+ * DTMF code (c) 1996 by Christian Mock (cm@kukuruz.ping.at)
  * 
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -19,6 +20,12 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  *
  * $Log: isdn_audio.c,v $
+ * Revision 1.6  1996/06/06 14:43:31  fritz
+ * Changed to support DTMF decoding on audio playback also.
+ *
+ * Revision 1.5  1996/06/05 02:24:08  fritz
+ * Added DTMF decoder for audio mode.
+ *
  * Revision 1.4  1996/05/17 03:48:01  fritz
  * Removed some test statements.
  * Added revision string.
@@ -38,8 +45,9 @@
 #include <linux/module.h>
 #include <linux/isdn.h>
 #include "isdn_audio.h"
+#include "isdn_common.h"
 
-char *isdn_audio_revision        = "$Revision: 1.4 $";
+char *isdn_audio_revision        = "$Revision: 1.6 $";
 
 /*
  * Misc. lookup-tables.
@@ -189,6 +197,46 @@
         0x8a, 0x8a, 0x6a, 0x6a, 0xea, 0xea, 0x2a, 0x2a
 };
 
+#define NCOEFF           16     /* number of frequencies to be analyzed       */
+#define DTMF_TRESH    50000     /* above this is dtmf                         */
+#define SILENCE_TRESH   100     /* below this is silence                      */
+#define H2_TRESH      10000     /* 2nd harmonic                               */
+#define AMP_BITS          9     /* bits per sample, reduced to avoid overflow */
+#define LOGRP             0
+#define HIGRP             1
+
+typedef struct {
+        int grp;        /* low/high group     */
+        int k;          /* k                  */
+        int k2;         /* k fuer 2. harmonic */
+} dtmf_t;
+
+/* For DTMF recognition:
+ * 2 * cos(2 * PI * k / N) precalculated for all k
+ */
+static int cos2pik[NCOEFF] = {
+        55812,  29528, 53603,  24032, 51193,  14443, 48590,   6517,
+        38113, -21204, 33057, -32186, 25889, -45081, 18332, -55279
+};
+
+static dtmf_t dtmf_tones[8] = {
+        { LOGRP,  0,  1 }, /*  697 Hz */
+        { LOGRP,  2,  3 }, /*  770 Hz */
+        { LOGRP,  4,  5 }, /*  852 Hz */
+        { LOGRP,  6,  7 }, /*  941 Hz */
+        { HIGRP,  8,  9 }, /* 1209 Hz */
+        { HIGRP, 10, 11 }, /* 1336 Hz */
+        { HIGRP, 12, 13 }, /* 1477 Hz */
+        { HIGRP, 14, 15 }  /* 1633 Hz */
+};
+
+static char dtmf_matrix[4][4] = {
+        {'1', '2', '3', 'A'},
+        {'4', '5', '6', 'B'},
+        {'7', '8', '9', 'C'},
+        {'*', '0', '#', 'D'}
+};
+
 #if ((CPU == 386) || (CPU == 486) || (CPU == 586))
 static inline void
 isdn_audio_tlookup(const void *table, void *buff, unsigned long n)
@@ -314,15 +362,10 @@
 }
 
 adpcm_state *
-isdn_audio_adpcm_init(int nbits)
+isdn_audio_adpcm_init(adpcm_state *s, int nbits)
 {
-static adpcm_state *s;
-
-#ifdef ATEST
-        s = (adpcm_state *) malloc(sizeof(adpcm_state));
-#else
-        s = (adpcm_state *) kmalloc(sizeof(adpcm_state), GFP_ATOMIC);
-#endif
+        if (!s)
+                s = (adpcm_state *) kmalloc(sizeof(adpcm_state), GFP_ATOMIC);
         if (s) {
                 s->a     = 0;
                 s->d     = 5;
@@ -333,6 +376,18 @@
         return s;
 }
 
+dtmf_state *
+isdn_audio_dtmf_init(dtmf_state *s)
+{
+        if (!s)
+                s = (dtmf_state *) kmalloc(sizeof(dtmf_state), GFP_ATOMIC);
+        if (s) {
+                s->idx   = 0;
+                s->last  = ' ';
+        }
+        return s;
+}
+
 /*
  * Decompression of adpcm data to a/u-law
  *
@@ -425,4 +480,143 @@
 	s->d = d;
         return olen;
 }
+
+/*
+ * Goertzel algorithm.
+ * See http://ptolemy.eecs.berkeley.edu/~pino/Ptolemy/papers/96/dtmf_ict/
+ * for more info.
+ * Result is stored into an sk_buff and queued up for later
+ * evaluation.
+ */
+void
+isdn_audio_goertzel(int *sample, modem_info *info) {
+        int sk, sk1, sk2;
+        int k, n;
+        struct sk_buff *skb;
+        int *result;
+
+        skb = dev_alloc_skb(sizeof(int) * NCOEFF);
+        if (!skb) {
+                printk(KERN_WARNING
+                       "isdn_audio: Could not alloc DTMF result for ttyI%d\n",
+                       info->line);
+                return;
+        }
+        result = (int *)skb_put(skb, sizeof(int) * NCOEFF);
+        skb->free = 1;
+        skb->users = 0;
+        for (k = 0; k < NCOEFF; k++) {
+                sk = sk1 = sk2 = 0;
+                for (n = 0; n < DTMF_NPOINTS; n++) {
+                        sk = sample[n] + ((cos2pik[k] * sk1) >> 15) - sk2;
+                        sk2 = sk1;
+                        sk1 = sk;
+                }
+                result[k] =
+                        ((sk * sk) >> AMP_BITS) - 
+                        ((((cos2pik[k] * sk) >> 15) * sk2) >> AMP_BITS) +
+                        ((sk2 * sk2) >> AMP_BITS);
+        }
+        skb_queue_tail(&info->dtmf_queue, skb);
+        isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1);
+}
+
+void
+isdn_audio_eval_dtmf(modem_info *info)
+{
+        struct sk_buff *skb;
+        int *result;
+        dtmf_state *s;
+        int silence;
+        int i;
+        int di;
+        int ch;
+        unsigned long flags;
+        int grp[2];
+        char what;
+        char *p;
+
+        while ((skb = skb_dequeue(&info->dtmf_queue))) {
+                result = (int *)skb->data;
+                s = info->dtmf_state;
+                grp[LOGRP] = grp[HIGRP] = -2;
+                silence = 0;
+                for(i = 0; i < 8; i++) {
+                        if ((result[dtmf_tones[i].k] > DTMF_TRESH) &&
+                            (result[dtmf_tones[i].k2] < H2_TRESH)    )
+                                grp[dtmf_tones[i].grp] = (grp[dtmf_tones[i].grp] == -2)?i:-1;
+                        else
+                                if ((result[dtmf_tones[i].k] < SILENCE_TRESH) &&
+                                    (result[dtmf_tones[i].k2] < SILENCE_TRESH)  )
+                                        silence++;
+                }
+                if(silence == 8)
+                        what = ' ';
+                else {
+                        if((grp[LOGRP] >= 0) && (grp[HIGRP] >= 0)) {
+                                what = dtmf_matrix[grp[LOGRP]][grp[HIGRP] - 4];
+                                if(s->last != ' ' && s->last != '.')
+                                        s->last = what;  /* min. 1 non-DTMF between DTMF */
+                        } else
+                                what = '.';
+                }
+                if ((what != s->last) && (what != ' ') && (what != '.')) {
+                        printk(KERN_DEBUG "dtmf: tt='%c'\n", what);
+                        p = skb->data;
+                        *p++ = 0x10;
+                        *p = what;
+                        skb_trim(skb, 2);
+                        save_flags(flags);
+                        cli();
+                        di = info->isdn_driver;
+                        ch = info->isdn_channel;
+                        __skb_queue_tail(&dev->drv[di]->rpqueue[ch], skb);
+                        dev->drv[di]->rcvcount[ch] += 2;
+                        restore_flags(flags);
+                        /* Schedule dequeuing */
+                        if ((dev->modempoll) && (info->rcvsched))
+                                isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 1);
+                        wake_up_interruptible(&dev->drv[di]->rcv_waitq[ch]);
+                } else
+                        kfree_skb(skb, FREE_READ);
+                s->last = what;
+        }
+}
+
+/*
+ * Decode DTMF tones, queue result in separate sk_buf for
+ * later examination.
+ * Parameters:
+ *   s    = pointer to state-struct.
+ *   buf  = input audio data
+ *   len  = size of audio data.
+ *   fmt  = audio data format (0 = ulaw, 1 = alaw)
+ */
+void
+isdn_audio_calc_dtmf(modem_info *info, unsigned char *buf, int len, int fmt)
+{
+        dtmf_state *s = info->dtmf_state;
+        int i;
+        int c;
+
+        while (len) {
+                c = MIN(len, (DTMF_NPOINTS - s->idx));
+                if (c <= 0)
+                        break;
+                for (i = 0; i < c; i++) {
+                        if (fmt)
+                                s->buf[s->idx++] =
+                                        isdn_audio_alaw_to_s16[*buf++] >> (15 - AMP_BITS);
+                        else
+                                s->buf[s->idx++] =
+                                        isdn_audio_ulaw_to_s16[*buf++] >> (15 - AMP_BITS);
+                }
+                if (s->idx == DTMF_NPOINTS) {
+                        isdn_audio_goertzel(s->buf, info);
+                        s->idx = 0;
+                }
+                len -= c;
+        }
+}
+
 
diff -u --recursive --new-file pre2.0.14/linux/drivers/isdn/isdn_audio.h linux/drivers/isdn/isdn_audio.h
--- pre2.0.14/linux/drivers/isdn/isdn_audio.h	Mon May 20 08:20:59 1996
+++ linux/drivers/isdn/isdn_audio.h	Fri Jun  7 16:02:40 1996
@@ -1,4 +1,4 @@
-/* $Id: isdn_audio.h,v 1.2 1996/05/10 08:48:32 fritz Exp $
+/* $Id: isdn_audio.h,v 1.4 1996/06/06 14:43:32 fritz Exp $
  *
  * Linux ISDN subsystem, audio conversion and compression (linklevel).
  *
@@ -19,6 +19,12 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  *
  * $Log: isdn_audio.h,v $
+ * Revision 1.4  1996/06/06 14:43:32  fritz
+ * Changed to support DTMF decoding on audio playback also.
+ *
+ * Revision 1.3  1996/06/05 02:24:09  fritz
+ * Added DTMF decoder for audio mode.
+ *
  * Revision 1.2  1996/05/10 08:48:32  fritz
  * Corrected adpcm bugs.
  *
@@ -27,17 +33,27 @@
  *
  */
 
+#define DTMF_NPOINTS 205       /* Number of samples for DTMF recognition */
 typedef struct adpcm_state {
-        int a;
-        int d;
-        int word;
-        int nleft;
-        int nbits;
+        int  a;
+        int  d;
+        int  word;
+        int  nleft;
+        int  nbits;
 } adpcm_state;
 
+typedef struct dtmf_state {
+        char last;
+        int  idx;
+        int  buf[DTMF_NPOINTS];
+} dtmf_state;
+
 extern void isdn_audio_ulaw2alaw(unsigned char *, unsigned long);
 extern void isdn_audio_alaw2ulaw(unsigned char *, unsigned long);
-extern adpcm_state *isdn_audio_adpcm_init(int);
-extern int isdn_audio_adpcm2xlaw(adpcm_state *, int, unsigned char *, unsigned char *, int);
-extern int isdn_audio_xlaw2adpcm(adpcm_state *, int, unsigned char *, unsigned char *, int);
-extern int isdn_audio_2adpcm_flush(adpcm_state *s, unsigned char *out);
+extern adpcm_state *isdn_audio_adpcm_init(adpcm_state *, int);
+extern int  isdn_audio_adpcm2xlaw(adpcm_state *, int, unsigned char *, unsigned char *, int);
+extern int  isdn_audio_xlaw2adpcm(adpcm_state *, int, unsigned char *, unsigned char *, int);
+extern int  isdn_audio_2adpcm_flush(adpcm_state *s, unsigned char *out);
+extern void isdn_audio_calc_dtmf(modem_info *, unsigned char *, int, int);
+extern void isdn_audio_eval_dtmf(modem_info *);
+dtmf_state *isdn_audio_dtmf_init(dtmf_state *);
diff -u --recursive --new-file pre2.0.14/linux/drivers/isdn/isdn_common.c linux/drivers/isdn/isdn_common.c
--- pre2.0.14/linux/drivers/isdn/isdn_common.c	Sat Jun  1 20:11:31 1996
+++ linux/drivers/isdn/isdn_common.c	Fri Jun  7 16:02:40 1996
@@ -1,4 +1,4 @@
-/* $Id: isdn_common.c,v 1.15 1996/05/31 01:10:54 fritz Exp $
+/* $Id: isdn_common.c,v 1.18 1996/06/06 14:51:51 fritz Exp $
  *
  * Linux ISDN subsystem, common used functions (linklevel).
  *
@@ -21,6 +21,16 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  *
  * $Log: isdn_common.c,v $
+ * Revision 1.18  1996/06/06 14:51:51  fritz
+ * Changed to support DTMF decoding on audio playback also.
+ *
+ * Revision 1.17  1996/06/05 02:24:10  fritz
+ * Added DTMF decoder for audio mode.
+ *
+ * Revision 1.16  1996/06/03 20:09:05  fritz
+ * Bugfix: called wrong function pointer for locking in
+ *         isdn_get_free_channel().
+ *
  * Revision 1.15  1996/05/31 01:10:54  fritz
  * Bugfixes:
  *   Lowlevel modules did not get locked correctly.
@@ -109,7 +119,7 @@
 isdn_dev *dev = (isdn_dev *) 0;
 
 static int  has_exported = 0;
-static char *isdn_revision      = "$Revision: 1.15 $";
+static char *isdn_revision      = "$Revision: 1.18 $";
 
 extern char *isdn_net_revision;
 extern char *isdn_tty_revision;
@@ -252,6 +262,9 @@
 	ulong flags;
 	int i;
         int midx;
+#ifdef CONFIG_ISDN_AUDIO
+        int ifmt;
+#endif
 	modem_info *info;
         
         if ((i = isdn_dc2minor(di,channel))==-1) {
@@ -271,6 +284,12 @@
                         return;
                 }
                 info  = &dev->mdm.info[midx];
+#ifdef CONFIG_ISDN_AUDIO
+                ifmt = 1;
+
+                if (info->vonline)
+                        isdn_audio_calc_dtmf(info, skb->data, skb->len, ifmt);
+#endif
                 if ((info->online < 2) &&
                     (!(info->vonline & 1))) {
                         /* If Modem not listening, drop data */
@@ -288,7 +307,6 @@
                 skb->users = 0;
 #ifdef CONFIG_ISDN_AUDIO
                 if (info->vonline & 1) {
-                        int ifmt = 1;
                         /* voice conversion/compression */
                         switch (info->emu.vpar[3]) {
                                 case 2:
@@ -1713,7 +1731,7 @@
                                                 cmd.driver = i;
                                                 cmd.arg = 0;
                                                 cmd.command = ISDN_CMD_LOCK;
-                                                (void) dev->drv[i]->interface->command(&cmd);
+                                                (void) dev->drv[d]->interface->command(&cmd);
 						restore_flags(flags);
 						return i;
 					} else {
@@ -1724,7 +1742,7 @@
                                                         cmd.driver = i;
                                                         cmd.arg = 0;
                                                         cmd.command = ISDN_CMD_LOCK;
-                                                        (void) dev->drv[i]->interface->command(&cmd);
+                                                        (void) dev->drv[d]->interface->command(&cmd);
 							restore_flags(flags);
 							return i;
 						}
diff -u --recursive --new-file pre2.0.14/linux/drivers/isdn/isdn_net.c linux/drivers/isdn/isdn_net.c
--- pre2.0.14/linux/drivers/isdn/isdn_net.c	Mon May 20 08:20:59 1996
+++ linux/drivers/isdn/isdn_net.c	Fri Jun  7 16:02:41 1996
@@ -1,4 +1,4 @@
-/* $Id: isdn_net.c,v 1.11 1996/05/18 01:36:59 fritz Exp $
+/* $Id: isdn_net.c,v 1.13 1996/06/06 14:25:44 fritz Exp $
  *
  * Linux ISDN subsystem, network interfaces and related functions (linklevel).
  *
@@ -21,6 +21,13 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  *
  * $Log: isdn_net.c,v $
+ * Revision 1.13  1996/06/06 14:25:44  fritz
+ * Changed loglevel of "incoming ... without OAD" message, since
+ * with audio support this is quite normal.
+ *
+ * Revision 1.12  1996/06/05 02:36:45  fritz
+ * Minor bugfixes by M. Hipp.
+ *
  * Revision 1.11  1996/05/18 01:36:59  fritz
  * Added spelling corrections and some minor changes
  * to stay in sync with kernel.
@@ -98,7 +105,7 @@
  
 extern void dev_purge_queues(struct device *dev);	/* move this to net/core/dev.c */
 
-char *isdn_net_revision = "$Revision: 1.11 $";
+char *isdn_net_revision = "$Revision: 1.13 $";
 
  /*
   * Code for raw-networking over ISDN
@@ -256,6 +263,15 @@
 				if ((lp->flags & ISDN_NET_CONNECTED) &&
 				    (!lp->dialstate)) {
 					lp->stats.tx_packets++;
+					if(lp->p_encap == ISDN_NET_ENCAP_SYNCPPP && lp->first_skb) {
+						if(!isdn_net_send_skb(&lp->netdev->dev,lp,lp->first_skb)) {
+							dev_kfree_skb(lp->first_skb,FREE_WRITE);
+							lp->first_skb = NULL;
+							mark_bh(NET_BH);
+						}
+						else
+							return 1;
+					}
                                         if (clear_bit(0,(void*)&(p->dev.tbusy)))
                                                 mark_bh(NET_BH);
 				}
@@ -719,9 +735,11 @@
 	
 	lp->transcount += skb->len;
         ret = isdn_writebuf_skb_stub(lp->isdn_device, lp->isdn_channel, skb);
-	if (ret == skb->len)
+	if (ret == skb->len) {
 		clear_bit(0, (void *)&(ndev->tbusy));
-	return (!ret);
+		return 0;
+	}
+	return 1;
 }                                      
 	
 
@@ -1476,7 +1494,7 @@
 	if (num[0] == ',') {
 		nr[0] = '0';
 		strncpy(&nr[1], num, 30);
-		printk(KERN_WARNING "isdn_net: Incoming call without OAD, assuming '0'\n");
+		printk(KERN_INFO "isdn_net: Incoming call without OAD, assuming '0'\n");
 	} else
 		strncpy(nr, num, 30);
 	s = strtok(nr, ",");
diff -u --recursive --new-file pre2.0.14/linux/drivers/isdn/isdn_tty.c linux/drivers/isdn/isdn_tty.c
--- pre2.0.14/linux/drivers/isdn/isdn_tty.c	Mon Jun  3 16:46:54 1996
+++ linux/drivers/isdn/isdn_tty.c	Fri Jun  7 16:02:41 1996
@@ -1,4 +1,4 @@
-/* $Id: isdn_tty.c,v 1.13 1996/05/31 01:33:29 fritz Exp $
+/* $Id: isdn_tty.c,v 1.18 1996/06/07 11:17:33 tsbogend Exp $
  *
  * Linux ISDN subsystem, tty functions and AT-command emulator (linklevel).
  *
@@ -20,6 +20,27 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  *
  * $Log: isdn_tty.c,v $
+ * Revision 1.18  1996/06/07 11:17:33  tsbogend
+ * added missing #ifdef CONFIG_ISDN_AUDIO to make compiling without
+ * audio support possible
+ *
+ * Revision 1.17  1996/06/06 14:55:47  fritz
+ * Changed to support DTMF decoding on audio playback also.
+ * Bugfix: Added check for invalid info->isdn_driver in
+ *         isdn_tty_senddown().
+ * Clear ncarrier flag on last close() of a tty.
+ *
+ * Revision 1.16  1996/06/05 02:24:12  fritz
+ * Added DTMF decoder for audio mode.
+ *
+ * Revision 1.15  1996/06/03 20:35:01  fritz
+ * Fixed typos.
+ *
+ * Revision 1.14  1996/06/03 20:12:19  fritz
+ * Fixed typos.
+ * Added call to write_wakeup via isdn_tty_flush_buffer()
+ * in isdn_tty_modem_hup().
+ *
  * Revision 1.13  1996/05/31 01:33:29  fritz
  * Changed buffering due to bad performance with mgetty.
  * Now sk_buff is delayed allocated in isdn_tty_senddown
@@ -95,6 +116,7 @@
 static void isdn_tty_modem_reset_regs(atemu *, int);
 static void isdn_tty_cmd_ATA(modem_info *);
 static void isdn_tty_at_cout(char *, modem_info *);
+static void isdn_tty_flush_buffer(struct tty_struct *);
 
 /* Leave this unchanged unless you know what you do! */
 #define MODEM_PARANOIA_CHECK
@@ -105,7 +127,7 @@
 static int bit2si[8] = {1,5,7,7,7,7,7,7};
 static int si2bit[8] = {4,1,4,4,4,4,4,4};
                                 
-char *isdn_tty_revision        = "$Revision: 1.13 $";
+char *isdn_tty_revision        = "$Revision: 1.18 $";
 
 #define DLE 0x10
 #define ETX 0x03
@@ -179,6 +201,9 @@
                         info = &dev->mdm.info[midx];
 			if (info->online) {
 				r = 0;
+#ifdef CONFIG_ISDN_AUDIO
+				isdn_audio_eval_dtmf(info);
+#endif
 				if ((tty = info->tty)) {
 					if (info->mcr & UART_MCR_RTS) {
 						c = TTY_FLIPBUF_SIZE - tty->flip.count;
@@ -226,6 +251,11 @@
                         skb->free = 1;
                         kfree_skb(skb, FREE_WRITE);
                 }
+        if (skb_queue_len(&info->dtmf_queue))
+                while ((skb = skb_dequeue(&info->dtmf_queue))) {
+                        skb->free = 1;
+                        kfree_skb(skb, FREE_WRITE);
+                }
         restore_flags(flags);
 }
 
@@ -362,6 +392,11 @@
                 restore_flags(flags);
                 return;
         }
+        if (info->isdn_driver < 0) {
+                info->xmit_count = 0;
+                restore_flags(flags);
+                return;
+        }
         skb_res = dev->drv[info->isdn_driver]->interface->hl_hdrlen + 4;
         if (info->vonline & 2) {
 #ifdef CONFIG_ISDN_AUDIO
@@ -558,7 +593,7 @@
                 return;
         info->rcvsched = 0;
         info->online = 0;
-        isdn_tty_cleanup_xmit(info);
+        isdn_tty_flush_buffer(info->tty);
         if (info->vonline & 1) {
                 /* voice-recording, add DLE-ETX */
                 isdn_tty_at_cout("\020\003", info);
@@ -568,6 +603,11 @@
                 isdn_tty_at_cout("\020\024", info);
         }
         info->vonline = 0;
+#ifdef CONFIG_ISDN_AUDIO
+        if (info->dtmf_state) {
+                kfree(info->dtmf_state);
+                info->dtmf_state = NULL;
+        }
         if (info->adpcms) {
                 kfree(info->adpcms);
                 info->adpcms = NULL;
@@ -576,6 +616,7 @@
                 kfree(info->adpcmr);
                 info->adpcmr = NULL;
         }
+#endif
         info->msr &= ~(UART_MSR_DCD | UART_MSR_RI);
         info->lsr |= UART_LSR_TEMT;
 	if (info->isdn_driver >= 0) {
@@ -1406,6 +1447,7 @@
 	if (tty->ldisc.flush_buffer)
 		tty->ldisc.flush_buffer(tty);
 	info->tty = 0;
+        info->ncarrier = 0;
 	tty->closing = 0;
 	if (info->blocked_open) {
                 current->state = TASK_INTERRUPTIBLE;
@@ -1566,6 +1608,7 @@
 		info->drv_index = -1;
 		info->xmit_size = ISDN_SERIAL_XMIT_SIZE;
                 skb_queue_head_init(&info->xmit_queue);
+                skb_queue_head_init(&info->dtmf_queue);
                 if (!(info->xmit_buf = kmalloc(ISDN_SERIAL_XMIT_SIZE + 5, GFP_KERNEL))) {
                         printk(KERN_ERR "Could not allocate modem xmit-buffer\n");
                         return -3;
@@ -1598,7 +1641,7 @@
 	if (num[0] == ',') {
 		nr[0] = '0';
 		strncpy(&nr[1], num, 29);
-		printk(KERN_WARNING "isdn_tty: Incoming call without OAD, assuming '0'\n");
+		printk(KERN_INFO "isdn_tty: Incoming call without OAD, assuming '0'\n");
 	} else
 		strncpy(nr, num, 30);
 	s = strtok(nr, ",");
@@ -1829,6 +1872,14 @@
                                 return;
                         }
                         restore_flags(flags);
+                        if (info->vonline & 1) {
+                                /* voice-recording, add DLE-ETX */
+                                isdn_tty_at_cout("\020\003", info);
+                        }
+                        if (info->vonline & 2) {
+                                /* voice-playing, add DLE-DC4 */
+                                isdn_tty_at_cout("\020\024", info);
+                        }
                         break;
                 case 1:
                 case 5:
@@ -1870,6 +1921,8 @@
 			restore_flags(flags);
 			return;
 		}
+                if (info->tty->ldisc.flush_buffer)
+                        info->tty->ldisc.flush_buffer(info->tty);
 		if ((info->flags & ISDN_ASYNC_CHECK_CD) &&
 		    (!((info->flags & ISDN_ASYNC_CALLOUT_ACTIVE) &&
 		       (info->flags & ISDN_ASYNC_CALLOUT_NOHUP)))) {
@@ -2271,8 +2324,13 @@
                         /* AT+VRX - Start recording */
                         if (!m->vpar[0])
                                 PARSE_ERROR1;
+                        info->dtmf_state = isdn_audio_dtmf_init(info->dtmf_state);
+                        if (!info->dtmf_state) {
+                                printk(KERN_WARNING "isdn_tty: Couldn't malloc dtmf state\n");
+                                PARSE_ERROR1;
+                        }
                         if (m->vpar[3] < 5) {
-                                info->adpcmr = isdn_audio_adpcm_init(m->vpar[3]);
+                                info->adpcmr = isdn_audio_adpcm_init(info->adpcmr, m->vpar[3]);
                                 if (!info->adpcmr) {
                                         printk(KERN_WARNING "isdn_tty: Couldn't malloc adpcm state\n");
                                         PARSE_ERROR1;
@@ -2372,8 +2430,13 @@
                         /* AT+VTX - Start sending */
                         if (!m->vpar[0])
                                 PARSE_ERROR1;
+                        info->dtmf_state = isdn_audio_dtmf_init(info->dtmf_state);
+                        if (!info->dtmf_state) {
+                                printk(KERN_WARNING "isdn_tty: Couldn't malloc dtmf state\n");
+                                PARSE_ERROR1;
+                        }
                         if (m->vpar[3] < 5) {
-                                info->adpcms = isdn_audio_adpcm_init(m->vpar[3]);
+                                info->adpcms = isdn_audio_adpcm_init(info->adpcms, m->vpar[3]);
                                 if (!info->adpcms) {
                                         printk(KERN_WARNING "isdn_tty: Couldn't malloc adpcm state\n");
                                         PARSE_ERROR1;
diff -u --recursive --new-file pre2.0.14/linux/drivers/isdn/teles/callc.c linux/drivers/isdn/teles/callc.c
--- pre2.0.14/linux/drivers/isdn/teles/callc.c	Sat Jun  1 20:11:32 1996
+++ linux/drivers/isdn/teles/callc.c	Fri Jun  7 16:02:41 1996
@@ -1,6 +1,15 @@
-/* $Id: callc.c,v 1.8 1996/05/31 01:00:38 fritz Exp $
+/* $Id: callc.c,v 1.11 1996/06/07 12:32:20 fritz Exp $
  *
  * $Log: callc.c,v $
+ * Revision 1.11  1996/06/07 12:32:20  fritz
+ * More changes to support suspend/resume.
+ *
+ * Revision 1.10  1996/06/06 21:24:21  fritz
+ * Started adding support for suspend/resume.
+ *
+ * Revision 1.9  1996/05/31 12:23:57  jdenoud
+ * Jan: added channel open check to teles_writebuf
+ *
  * Revision 1.8  1996/05/31 01:00:38  fritz
  * Changed return code of teles_writebuf, when out of memory.
  *
@@ -126,6 +135,8 @@
         EV_HANGUP,         /* 17 */
         EV_BC_REL,         /* 18 */
         EV_CINF,           /* 19 */
+        EV_SUSPEND,        /* 20 */
+        EV_RESUME,         /* 21 */
 };
 
 #define EVENT_COUNT (EV_CINF+1)
@@ -150,6 +161,8 @@
         "EV_HANGUP",
         "EV_BC_REL",
         "EV_CINF",
+        "EV_SUSPEND",
+        "EV_RESUME",
 };
 
 enum {
@@ -1328,6 +1341,22 @@
                           command_debug(chanp, "HANGUP");
                   FsmEvent(&chanp->fi, EV_HANGUP, NULL);
                   break;
+          case (ISDN_CMD_SUSPEND):
+                  chanp = chanlist + ic->arg;
+                  if (chanp->debug & 1) {
+                          sprintf(tmp, "SUSPEND %s", ic->num);
+                          command_debug(chanp, tmp);
+                  }
+                 FsmEvent(&chanp->fi, EV_SUSPEND, ic);
+                  break;
+          case (ISDN_CMD_RESUME):
+                  chanp = chanlist + ic->arg;
+                  if (chanp->debug & 1) {
+                          sprintf(tmp, "RESUME %s", ic->num);
+                          command_debug(chanp, tmp);
+                  }
+                  FsmEvent(&chanp->fi, EV_RESUME, ic);
+                  break;
           case (ISDN_CMD_LOCK):
                   teles_mod_inc_use_count();
                   break;
@@ -1388,6 +1417,11 @@
         int             err, i;
         byte           *ptr;
 
+	if (!chanp->data_open) {
+		printk(KERN_DEBUG "teles_writebuf: channel not open\n");
+		return -ENOMEM;
+	}
+	
         err = BufPoolGet(&ibh, st->l1.sbufpool, GFP_ATOMIC, st, 21);
         if (err)
                 return -ENOMEM;
diff -u --recursive --new-file pre2.0.14/linux/drivers/isdn/teles/card.c linux/drivers/isdn/teles/card.c
--- pre2.0.14/linux/drivers/isdn/teles/card.c	Sat Jun  1 20:11:32 1996
+++ linux/drivers/isdn/teles/card.c	Fri Jun  7 16:02:42 1996
@@ -1,4 +1,4 @@
-/* $Id: card.c,v 1.7 1996/05/31 01:02:21 fritz Exp $
+/* $Id: card.c,v 1.9 1996/06/06 14:42:09 fritz Exp $
  *
  * card.c     low level stuff for the Teles S0 isdn card
  * 
@@ -7,6 +7,9 @@
  * Beat Doebeli         log all D channel traffic
  * 
  * $Log: card.c,v $
+ * Revision 1.9  1996/06/06 14:42:09  fritz
+ * Bugfix: forgot hsp-> in last change.
+ *
  * Revision 1.7  1996/05/31 01:02:21  fritz
  * Cosmetic changes.
  *
@@ -438,7 +441,7 @@
 			if (!r & 0x80)
 				printk(KERN_WARNING
                                        "Teles: HSCX invalid frame\n");
-			if (r & 0x40)
+			if ((r & 0x40) && hsp->mode)
 				printk(KERN_WARNING "Teles: HSCX RDO mode=%d\n",hsp->mode);
 			if (!r & 0x20)
 				printk(KERN_WARNING "Teles: HSCX CRC error\n");
diff -u --recursive --new-file pre2.0.14/linux/drivers/isdn/teles/isdnl3.c linux/drivers/isdn/teles/isdnl3.c
--- pre2.0.14/linux/drivers/isdn/teles/isdnl3.c	Mon Jun  3 16:46:54 1996
+++ linux/drivers/isdn/teles/isdnl3.c	Fri Jun  7 16:02:42 1996
@@ -1,6 +1,16 @@
-/* $Id: isdnl3.c,v 1.6 1996/05/21 11:33:50 keil Exp $
+/* $Id: isdnl3.c,v 1.9 1996/06/06 14:22:27 fritz Exp $
  *
  * $Log: isdnl3.c,v $
+ * Revision 1.9  1996/06/06 14:22:27  fritz
+ * Changed level of "non-digital call..." message, since
+ * with audio support, this is quite normal.
+ *
+ * Revision 1.8  1996/06/03 20:35:04  fritz
+ * Fixed typos.
+ *
+ * Revision 1.7  1996/06/03 20:03:39  fritz
+ * Fixed typos.
+ *
  * Revision 1.6  1996/05/21 11:33:50  keil
  * Adding SETUP_ACKNOWLEDGE as answer of a SETUP message.
  *
@@ -298,7 +308,7 @@
 
         if (bcfound) {
                 if (st->pa->info != 7) {
-                        printk(KERN_WARNING "non-digital call: %s -> %s\n",
+                        printk(KERN_DEBUG "non-digital call: %s -> %s\n",
                                st->pa->calling,
                                st->pa->called);
                 }
diff -u --recursive --new-file pre2.0.14/linux/drivers/isdn/teles/l3_1TR6.c linux/drivers/isdn/teles/l3_1TR6.c
--- pre2.0.14/linux/drivers/isdn/teles/l3_1TR6.c	Mon May 20 08:21:00 1996
+++ linux/drivers/isdn/teles/l3_1TR6.c	Fri Jun  7 16:02:42 1996
@@ -1,6 +1,10 @@
-/* $Id: l3_1TR6.c,v 1.3 1996/04/30 21:54:42 isdn4dev Exp $
+/* $Id: l3_1TR6.c,v 1.4 1996/06/06 14:22:28 fritz Exp $
  *
  * $Log: l3_1TR6.c,v $
+ * Revision 1.4  1996/06/06 14:22:28  fritz
+ * Changed level of "non-digital call..." message, since
+ * with audio support, this is quite normal.
+ *
  * Revision 1.3  1996/04/30 21:54:42  isdn4dev
  * SPV, callback , remove some debugging code  Karsten Keil
  *
@@ -156,7 +160,7 @@
 
         /* Signal all services, linklevel takes care of Service-Indicator */
 	if (st->pa->info != 7) {
-                printk(KERN_INFO "non-digital call: %s -> %s\n",
+                printk(KERN_DEBUG "non-digital call: %s -> %s\n",
                        st->pa->calling,
                        st->pa->called);
 	}
diff -u --recursive --new-file pre2.0.14/linux/drivers/isdn/teles/llglue.c linux/drivers/isdn/teles/llglue.c
--- pre2.0.14/linux/drivers/isdn/teles/llglue.c	Sat Jun  1 20:11:32 1996
+++ linux/drivers/isdn/teles/llglue.c	Fri Jun  7 16:02:42 1996
@@ -1,6 +1,9 @@
-/* $Id: llglue.c,v 1.5 1996/05/31 00:58:47 fritz Exp $
+/* $Id: llglue.c,v 1.6 1996/06/03 20:03:39 fritz Exp $
  *
  * $Log: llglue.c,v $
+ * Revision 1.6  1996/06/03 20:03:39  fritz
+ * Fixed typos.
+ *
  * Revision 1.5  1996/05/31 00:58:47  fritz
  * Errata: Reverted change from rev 1.4.
  *
diff -u --recursive --new-file pre2.0.14/linux/drivers/isdn/teles/q931.c linux/drivers/isdn/teles/q931.c
--- pre2.0.14/linux/drivers/isdn/teles/q931.c	Tue May 21 19:52:35 1996
+++ linux/drivers/isdn/teles/q931.c	Fri Jun  7 16:02:42 1996
@@ -1,4 +1,4 @@
-/* $Id: q931.c,v 1.4 1996/05/17 03:46:17 fritz Exp $
+/* $Id: q931.c,v 1.5 1996/06/03 20:03:40 fritz Exp $
  *
  * q931.c               code to decode ITU Q.931 call control messages
  * 
@@ -14,6 +14,9 @@
  *
  * 
  * $Log: q931.c,v $
+ * Revision 1.5  1996/06/03 20:03:40  fritz
+ * Fixed typos.
+ *
  * Revision 1.4  1996/05/17 03:46:17  fritz
  * General cleanup.
  *
diff -u --recursive --new-file pre2.0.14/linux/drivers/net/arcnet.c linux/drivers/net/arcnet.c
--- pre2.0.14/linux/drivers/net/arcnet.c	Tue May  7 16:22:27 1996
+++ linux/drivers/net/arcnet.c	Fri Jun  7 11:58:11 1996
@@ -17,6 +17,10 @@
          
 	**********************
 	
+	v2.53 (96/06/06)
+	  - arc0e and arc0s wouldn't initialize in newer kernels, which
+	    don't like dev->open==NULL or dev->stop==NULL.
+	
 	v2.52 (96/04/20)
 	  - Replaced more decimal node ID's with hex, for consistency.
 	  - Changed a couple of printk debug levels.
@@ -180,7 +184,7 @@
 */
 
 static const char *version =
- "arcnet.c: v2.52 96/04/20 Avery Pennarun <apenwarr@foxnet.net>\n";
+ "arcnet.c: v2.53 96/06/06 Avery Pennarun <apenwarr@foxnet.net>\n";
 
  
 
@@ -635,6 +639,7 @@
 #ifdef CONFIG_ARCNET_ETH
 	/* functions specific to Ethernet-Encap */
 static int arcnetE_init(struct device *dev);
+static int arcnetE_open_close(struct device *dev);
 static int arcnetE_send_packet(struct sk_buff *skb, struct device *dev);
 static void arcnetE_rx(struct device *dev,u_char *arcsoft,
 	int length,u_char saddr, u_char daddr);
@@ -643,6 +648,7 @@
 #ifdef CONFIG_ARCNET_1051
 	/* functions specific to RFC1051 */
 static int arcnetS_init(struct device *dev);
+static int arcnetS_open_close(struct device *dev);
 static int arcnetS_send_packet(struct sk_buff *skb, struct device *dev);
 static void arcnetS_rx(struct device *dev,u_char *buf,
 	int length,u_char saddr, u_char daddr);
@@ -2755,8 +2761,8 @@
 	dev->dev_addr[0]=0;
 	dev->dev_addr[5]=lp->stationid;
 	dev->mtu=512-sizeof(struct HardHeader)-dev->hard_header_len-1;
-	dev->open=NULL;
-	dev->stop=NULL;
+	dev->open=arcnetE_open_close;
+	dev->stop=arcnetE_open_close;
 	dev->hard_start_xmit=arcnetE_send_packet;
 
 	BUGMSG(D_EXTRA,"ARCnet Ethernet-Encap protocol initialized.\n");
@@ -2765,6 +2771,15 @@
 }
 
 
+/* Bring up/down the arc0e device - we don't actually have to do anything,
+ * since our parent arc0 handles the card I/O itself.
+ */
+static int arcnetE_open_close(struct device *dev)
+{
+	return 0;
+}
+
+
 /* Called by the kernel in order to transmit an ethernet-type packet.
  */
 static int
@@ -2925,13 +2940,22 @@
 	dev->hard_header_len=sizeof(struct S_ClientData);
 	dev->mtu=512-sizeof(struct HardHeader)-dev->hard_header_len
 		+ S_EXTRA_CLIENTDATA;
-	dev->open=NULL;
-	dev->stop=NULL;
+	dev->open=arcnetS_open_close;
+	dev->stop=arcnetS_open_close;
 	dev->hard_start_xmit=arcnetS_send_packet;
 	dev->hard_header=arcnetS_header;
 	dev->rebuild_header=arcnetS_rebuild_header;
 	BUGMSG(D_EXTRA,"ARCnet RFC1051 (NetBSD, AmiTCP) protocol initialized.\n");
 
+	return 0;
+}
+
+
+/* Bring up/down the arc0s device - we don't actually have to do anything,
+ * since our parent arc0 handles the card I/O itself.
+ */
+static int arcnetS_open_close(struct device *dev)
+{
 	return 0;
 }
 
diff -u --recursive --new-file pre2.0.14/linux/drivers/net/eexpress.c linux/drivers/net/eexpress.c
--- pre2.0.14/linux/drivers/net/eexpress.c	Fri May 31 08:02:19 1996
+++ linux/drivers/net/eexpress.c	Fri Jun  7 14:21:04 1996
@@ -1068,8 +1068,9 @@
 	outb_p(i586_RST,ioaddr+EEPROM_Ctrl);
 	udelay(2000);  /* delay 20ms */
         {
-		unsigned short ofs, i;
+		unsigned long ofs;
 		for (ofs = 0; ofs < lp->rx_buf_end; ofs += 32) {
+			unsigned long i;
 			outw_p(ofs, ioaddr+SM_PTR);
 			for (i = 0; i < 16; i++) {
 				outw_p(0, ioaddr+SM_ADDR(i<<1));
diff -u --recursive --new-file pre2.0.14/linux/drivers/scsi/Makefile linux/drivers/scsi/Makefile
--- pre2.0.14/linux/drivers/scsi/Makefile	Mon May 20 08:21:02 1996
+++ linux/drivers/scsi/Makefile	Fri Jun  7 11:53:09 1996
@@ -35,7 +35,10 @@
 endif
 
 ifeq ($(CONFIG_SCSI),y)
-L_OBJS += hosts.o scsi.o scsi_ioctl.o constants.o scsicam.o scsi_proc.o
+L_OBJS += hosts.o scsi.o scsi_ioctl.o constants.o scsicam.o
+  ifeq ($(CONFIG_PROC_FS),y)
+    L_OBJS += scsi_proc.o
+  endif
 LX_OBJS += scsi_syms.o
 else
   ifeq ($(CONFIG_SCSI),m)
diff -u --recursive --new-file pre2.0.14/linux/drivers/scsi/aha152x.c linux/drivers/scsi/aha152x.c
--- pre2.0.14/linux/drivers/scsi/aha152x.c	Fri May 17 15:32:16 1996
+++ linux/drivers/scsi/aha152x.c	Sun Jun  9 12:47:12 1996
@@ -20,9 +20,12 @@
  * General Public License for more details.
  *
  *
- * $Id: aha152x.c,v 1.15 1996/04/30 14:52:06 fischer Exp fischer $
+ * $Id: aha152x.c,v 1.16 1996/06/09 00:04:56 root Exp $
  *
  * $Log: aha152x.c,v $
+ * Revision 1.16  1996/06/09 00:04:56  root
+ * - added configuration symbols for insmod (aha152x/aha152x1)
+ *
  * Revision 1.15  1996/04/30 14:52:06  fischer
  * - proc info fixed
  * - support for extended translation for >1GB disks
@@ -333,6 +336,16 @@
   sync_ok      = 0x0080,
 };
 
+#if defined(MODULE)
+#if defined(DEBUG_AHA152X)
+int aha152x[]  = { 0, 11, 7, 1, 1, 0, DELAY_DEFAULT, DEBUG_DEFAULT };
+int aha152x1[] = { 0, 11, 7, 1, 1, 0, DELAY_DEFAULT, DEBUG_DEFAULT };
+#else
+int aha152x[]  = { 0, 11, 7, 1, 1, 0, DELAY_DEFAULT };
+int aha152x1[] = { 0, 11, 7, 1, 1, 0, DELAY_DEFAULT };
+#endif
+#endif
+
 /* set by aha152x_setup according to the command line */
 static int  setup_count=0;
 static struct aha152x_setup {
@@ -680,14 +693,12 @@
 	}
 
 #ifdef SETUP0
-  if(setup_count<2)
-	{
+  if(setup_count<2) {
       struct aha152x_setup override = SETUP0;
 
       if(setup_count==0 || (override.io_port != setup[0].io_port))
-        if(!aha152x_checksetup(&override))
-	{
-                printk("\naha152x: SETUP0 (0x%x, %d, %d, %d, %d, %d, %d) invalid\n",
+      if(!aha152x_checksetup(&override)) {
+        printk("\naha152x: invalid override SETUP0={0x%x,%d,%d,%d,%d,%d,%d}\n",
         	      override.io_port,
         	      override.irq,
         	      override.scsiid,
@@ -695,21 +706,18 @@
         	      override.parity,
         	      override.synchronous,
         	      override.delay);
-	}
-        else
+      } else
           setup[setup_count++] = override;
 	}
 #endif
 
 #ifdef SETUP1
-  if(setup_count<2)
-	{
+  if(setup_count<2) {
       struct aha152x_setup override = SETUP1;
 
       if(setup_count==0 || (override.io_port != setup[0].io_port))
-        if(!aha152x_checksetup(&override))
-	{
-                printk("\naha152x: SETUP1 (0x%x, %d, %d, %d, %d, %d, %d) invalid\n",
+      if(!aha152x_checksetup(&override)) {
+        printk("\naha152x: invalid override SETUP1={0x%x,%d,%d,%d,%d,%d,%d}\n",
         	       override.io_port,
         	       override.irq,
         	       override.scsiid,
@@ -717,15 +725,65 @@
         	       override.parity,
         	       override.synchronous,
         	       override.delay);
+      } else
+        setup[setup_count++] = override;
     }
+#endif
+
+#if defined(MODULE)
+  if(setup_count<2 && aha152x[0]!=0) {
+    setup[setup_count].conf        = "";
+    setup[setup_count].io_port     = aha152x[0];
+    setup[setup_count].irq         = aha152x[1];
+    setup[setup_count].scsiid      = aha152x[2];
+    setup[setup_count].reconnect   = aha152x[3];
+    setup[setup_count].parity      = aha152x[4];
+    setup[setup_count].synchronous = aha152x[5];
+    setup[setup_count].delay       = aha152x[6];
+#ifdef DEBUG_AHA152X
+    setup[setup_count].debug       = aha152x[7];
+#endif
+    if(aha152x_checksetup(&setup[setup_count]))
+      setup_count++;
   else
-          setup[setup_count++] = override;
+      printk("\naha152x: invalid module argument aha152x=0x%x,%d,%d,%d,%d,%d,%d\n",
+             setup[setup_count].io_port,
+             setup[setup_count].irq,
+             setup[setup_count].scsiid,
+             setup[setup_count].reconnect,
+             setup[setup_count].parity,
+             setup[setup_count].synchronous,
+             setup[setup_count].delay);
+  }
+
+  if(setup_count<2 && aha152x1[0]!=0) {
+    setup[setup_count].conf        = "";
+    setup[setup_count].io_port     = aha152x1[0];
+    setup[setup_count].irq         = aha152x1[1];
+    setup[setup_count].scsiid      = aha152x1[2];
+    setup[setup_count].reconnect   = aha152x1[3];
+    setup[setup_count].parity      = aha152x1[4];
+    setup[setup_count].synchronous = aha152x1[5];
+    setup[setup_count].delay       = aha152x1[6];
+#ifdef DEBUG_AHA152X
+    setup[setup_count].debug       = aha152x1[7];
+#endif
+    if(aha152x_checksetup(&setup[setup_count]))
+      setup_count++;
+    else
+      printk("\naha152x: invalid module argument aha152x1=0x%x,%d,%d,%d,%d,%d,%d\n",
+             setup[setup_count].io_port,
+             setup[setup_count].irq,
+             setup[setup_count].scsiid,
+             setup[setup_count].reconnect,
+             setup[setup_count].parity,
+             setup[setup_count].synchronous,
+             setup[setup_count].delay);
     }
 #endif
   
 #if defined(AUTOCONF)
-  if(setup_count<2)
-    {
+  if(setup_count<2) {
 #if !defined(SKIP_BIOSTEST)
       ok=0;
       for(i=0; i < ADDRESS_COUNT && !ok; i++)
@@ -742,13 +800,13 @@
       printk("aha152x: ");
 #endif /* !SKIP_BIOSTEST */
  
-      for(i=0; i<PORT_COUNT && setup_count<2; i++)
-            {
+    ok=0;
+    for(i=0; i<PORT_COUNT && setup_count<2; i++) {
               if((setup_count==1) && (setup[0].io_port == ports[i]))
                 continue;
 
-              if(aha152x_porttest(ports[i]))
-	{
+      if(aha152x_porttest(ports[i])) {
+        ok++;
                   setup[setup_count].io_port = ports[i];
               
                   conf.cf_port =
@@ -767,11 +825,12 @@
                 }
 	}
 
+    if(ok)
       printk("auto configuration: ok, ");
     }
 #endif
 
-  printk("detection complete\n");
+  printk("detected %d controllers\n", setup_count);
 
   for(i=0; i<setup_count; i++)
     {
@@ -2772,11 +2831,11 @@
   char *start = pos;
   int i;
   
-  SPRINTF("0x%08x: target=%d; lun=%d; cmnd=(",
+  SPRINTF("0x%08x: target=%d; lun=%d; cmnd=( ",
           (unsigned int) ptr, ptr->target, ptr->lun);
   
   for(i=0; i<COMMAND_SIZE(ptr->cmnd[0]); i++)
-    SPRINTF("0x%02x", ptr->cmnd[i]);
+    SPRINTF("0x%02x ", ptr->cmnd[i]);
   
   SPRINTF("); residual=%d; buffers=%d; phase |",
           ptr->SCp.this_residual, ptr->SCp.buffers_residual);
diff -u --recursive --new-file pre2.0.14/linux/drivers/scsi/aha152x.h linux/drivers/scsi/aha152x.h
--- pre2.0.14/linux/drivers/scsi/aha152x.h	Sun May  5 08:52:00 1996
+++ linux/drivers/scsi/aha152x.h	Sun Jun  9 12:48:07 1996
@@ -2,7 +2,7 @@
 #define _AHA152X_H
 
 /*
- * $Id: aha152x.h,v 1.15 1996/04/30 14:59:35 fischer Exp $
+ * $Id: aha152x.h,v 1.16 1996/06/09 00:08:30 fischer Exp $
  */
 
 #if defined(__KERNEL__)
@@ -23,7 +23,7 @@
    (unless we support more than 1 cmd_per_lun this should do) */
 #define AHA152X_MAXQUEUE	7		
 
-#define AHA152X_REVID "Adaptec 152x SCSI driver; $Revision: 1.15 $"
+#define AHA152X_REVID "Adaptec 152x SCSI driver; $Revision: 1.16 $"
 
 extern struct proc_dir_entry proc_scsi_aha152x;
 
diff -u --recursive --new-file pre2.0.14/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
--- pre2.0.14/linux/drivers/scsi/scsi.c	Mon Jun  3 16:46:56 1996
+++ linux/drivers/scsi/scsi.c	Fri Jun  7 11:46:54 1996
@@ -151,6 +151,7 @@
 /* This is the pointer to the /proc/scsi code. 
  * It is only initialized to !=0 if the scsi code is present 
  */ 
+#if CONFIG_PROC_FS 
 extern int (* dispatch_scsi_info_ptr)(int ino, char *buffer, char **start, 
 				      off_t offset, int length, int inout); 
 extern int dispatch_scsi_info(int ino, char *buffer, char **start, 
@@ -163,6 +164,7 @@
     NULL, NULL,
     NULL, NULL, NULL
 };
+#endif
 
 /*
  *  As the scsi do command functions are intelligent, and may need to
@@ -2503,7 +2505,9 @@
 #endif
 
     /* Yes we're here... */
+#if CONFIG_PROC_FS 
     dispatch_scsi_info_ptr = dispatch_scsi_info;
+#endif
 
     /* Init a few things so we can "malloc" memory. */
     scsi_loadable_module_flag = 0;
@@ -3391,7 +3395,9 @@
     /*
      * This makes /proc/scsi visible.
      */
+#if CONFIG_PROC_FS
     dispatch_scsi_info_ptr = dispatch_scsi_info;
+#endif
 
     timer_table[SCSI_TIMER].fn = scsi_main_timeout;
     timer_table[SCSI_TIMER].expires = 0;
@@ -3428,10 +3434,10 @@
 {
 #if CONFIG_PROC_FS
     proc_scsi_unregister(0, PROC_SCSI_SCSI);
-#endif
 
     /* No, we're not here anymore. Don't show the /proc/scsi files. */
     dispatch_scsi_info_ptr = 0L;
+#endif
 
     /*
      * Free up the DMA pool.
diff -u --recursive --new-file pre2.0.14/linux/drivers/scsi/scsi_ioctl.c linux/drivers/scsi/scsi_ioctl.c
--- pre2.0.14/linux/drivers/scsi/scsi_ioctl.c	Wed Jun  5 10:41:28 1996
+++ linux/drivers/scsi/scsi_ioctl.c	Sat Jun  8 11:41:46 1996
@@ -342,13 +342,13 @@
 	if(!dev->tagged_supported) return -EINVAL;
 	dev->tagged_queue = 1;
 	dev->current_tag = 1;
-	break;
+	return 0;
     case SCSI_IOCTL_TAGGED_DISABLE:
 	if(!suser())  return -EACCES;
 	if(!dev->tagged_supported) return -EINVAL;
 	dev->tagged_queue = 0;
 	dev->current_tag = 0;
-	break;
+	return 0;
     case SCSI_IOCTL_PROBE_HOST:
 	return ioctl_probe(dev->host, arg);
     case SCSI_IOCTL_SEND_COMMAND:
diff -u --recursive --new-file pre2.0.14/linux/drivers/sound/Makefile linux/drivers/sound/Makefile
--- pre2.0.14/linux/drivers/sound/Makefile	Mon Mar 25 09:20:45 1996
+++ linux/drivers/sound/Makefile	Fri Jun  7 11:58:11 1996
@@ -108,9 +108,7 @@
 #	@echo \#define SOUND_CONFIG_DOMAIN \"`hostname -d`\" >> local.h 2>/dev/null
 	@echo \#define SOUND_UNAME_A \"`uname -a`\" >> local.h
 
-kernelconfig: setup-$(TARGET_OS)
-	rm -f configure
-	$(HOSTCC) -o configure configure.c
+kernelconfig: setup-$(TARGET_OS) configure
 	./configure fixedlocal > local.h
 	./configure fixeddefines > .defines
 	@echo \#define SOUND_CONFIG_DATE \"`date`\" >> local.h
@@ -119,9 +117,7 @@
 #	@echo \#define SOUND_CONFIG_DOMAIN \"`hostname -d`\" >> local.h 2>/dev/null
 	@echo \#define SOUND_UNAME_A \"`uname -a`\" >> local.h
 
-mkscript: setup-$(TARGET_OS)
-	rm -f configure
-	$(HOSTCC) -o configure configure.c
+mkscript: setup-$(TARGET_OS) configure
 	./configure script > Config.in
 	./configure fixedlocal > local.h
 	./configure fixeddefines > .defines
diff -u --recursive --new-file pre2.0.14/linux/fs/ext2/super.c linux/fs/ext2/super.c
--- pre2.0.14/linux/fs/ext2/super.c	Sun May  5 08:52:03 1996
+++ linux/fs/ext2/super.c	Fri Jun  7 15:45:21 1996
@@ -411,11 +411,20 @@
 		MOD_DEC_USE_COUNT;
 		return NULL;
 	}
-	if ((es->s_rev_level > EXT2_GOOD_OLD_REV) &&
-	    (es->s_feature_incompat & !EXT2_FEATURE_INCOMPAT_SUPP)) {
-		printk("EXT2-fs: %s: couldn't mount because of "
-		       "unsupported optional features.\n", kdevname(dev));
-		goto failed_mount;
+	if (es->s_rev_level > EXT2_GOOD_OLD_REV) {
+		if (es->s_feature_incompat & ~EXT2_FEATURE_INCOMPAT_SUPP) {
+			printk("EXT2-fs: %s: couldn't mount because of "
+			       "unsupported optional features.\n", 
+			       kdevname(dev));
+			goto failed_mount;
+		}
+		if (!(sb->s_flags & MS_RDONLY) &&
+		    (es->s_feature_ro_compat & ~EXT2_FEATURE_RO_COMPAT_SUPP)) {
+			printk("EXT2-fs: %s: couldn't mount RDWR because of "
+			       "unsupported optional features.\n", 
+			       kdevname(dev));
+			goto failed_mount;
+		}
 	}
 	sb->s_blocksize_bits = sb->u.ext2_sb.s_es->s_log_block_size + 10;
 	sb->s_blocksize = 1 << sb->s_blocksize_bits;
diff -u --recursive --new-file pre2.0.14/linux/fs/locks.c linux/fs/locks.c
--- pre2.0.14/linux/fs/locks.c	Mon Jun  3 16:46:56 1996
+++ linux/fs/locks.c	Sat Jun  8 16:50:57 1996
@@ -304,8 +304,8 @@
 /* warn a bit for now, but don't overdo it */
 {
 	static int count = 0;
-	if (count < 5) {
-		count++;
+	if (!count) {
+		count=1;
 		printk(KERN_WARNING
 		       "fcntl_setlk() called by process %d (%s) with broken flock() emulation\n",
 		       current->pid, current->comm);
diff -u --recursive --new-file pre2.0.14/linux/fs/nfs/bio.c linux/fs/nfs/bio.c
--- pre2.0.14/linux/fs/nfs/bio.c	Sun Apr 21 12:39:02 1996
+++ linux/fs/nfs/bio.c	Sun Jun  9 11:21:12 1996
@@ -108,7 +108,7 @@
 		set_bit(PG_uptodate, &page->flags);
 	} else {
 		fail++;
-		printk("BIO: %d successful reads, %d failures\n", succ, fail);
+		dprintk("BIO: %d successful reads, %d failures\n", succ, fail);
 		set_bit(PG_error, &page->flags);
 	}
 	clear_bit(PG_locked, &page->flags);
diff -u --recursive --new-file pre2.0.14/linux/fs/super.c linux/fs/super.c
--- pre2.0.14/linux/fs/super.c	Tue May  7 16:22:36 1996
+++ linux/fs/super.c	Sat Jun  8 11:10:49 1996
@@ -1040,6 +1040,10 @@
 	old_root = current->fs->root;
 	old_pwd = current->fs->pwd;
 	old_root_dev = ROOT_DEV;
+	if (!fs_may_mount(new_root_dev)) {
+		printk(KERN_CRIT "New root is busy. Staying in initrd.\n");
+		return -EBUSY;
+	}
 	ROOT_DEV = new_root_dev;
 	do_mount_root();
 	old_fs = get_fs();
diff -u --recursive --new-file pre2.0.14/linux/include/asm-alpha/unistd.h linux/include/asm-alpha/unistd.h
--- pre2.0.14/linux/include/asm-alpha/unistd.h	Fri May 17 15:32:18 1996
+++ linux/include/asm-alpha/unistd.h	Sat Jun  8 11:09:40 1996
@@ -164,6 +164,7 @@
 #define __NR_afs_syscall		338
 #define __NR_uname			339
 #define __NR_nanosleep			340
+#define __NR_mremap			341
 
 #ifdef __LIBRARY__
 
diff -u --recursive --new-file pre2.0.14/linux/include/linux/ext2_fs.h linux/include/linux/ext2_fs.h
--- pre2.0.14/linux/include/linux/ext2_fs.h	Tue May 21 19:52:37 1996
+++ linux/include/linux/ext2_fs.h	Fri Jun  7 15:45:21 1996
@@ -362,7 +362,8 @@
 	__u16	s_block_group_nr; 	/* block group # of this superblock */
 	__u32	s_feature_compat; 	/* compatible feature set */
 	__u32	s_feature_incompat; 	/* incompatible feature set */
-	__u32	s_reserved[231];	/* Padding to the end of the block */
+	__u32	s_feature_ro_compat; 	/* readonly-compatible feature set */
+	__u32	s_reserved[230];	/* Padding to the end of the block */
 };
 
 /*
@@ -418,6 +419,7 @@
  */
 #define EXT2_FEATURE_COMPAT_SUPP	0
 #define EXT2_FEATURE_INCOMPAT_SUPP	0
+#define EXT2_FEATURE_RO_COMPAT_SUPP	0
 
 #ifdef __KERNEL__
 /*
diff -u --recursive --new-file pre2.0.14/linux/include/linux/isdn.h linux/include/linux/isdn.h
--- pre2.0.14/linux/include/linux/isdn.h	Sat Jun  1 20:11:36 1996
+++ linux/include/linux/isdn.h	Fri Jun  7 16:02:43 1996
@@ -1,4 +1,4 @@
-/* $Id: isdn.h,v 1.11 1996/05/31 01:37:47 fritz Exp $
+/* $Id: isdn.h,v 1.14 1996/06/06 21:24:23 fritz Exp $
  *
  * Main header for the Linux ISDN subsystem (linklevel).
  *
@@ -21,6 +21,15 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  *
  * $Log: isdn.h,v $
+ * Revision 1.14  1996/06/06 21:24:23  fritz
+ * Started adding support for suspend/resume.
+ *
+ * Revision 1.13  1996/06/05 02:18:20  fritz
+ * Added DTMF decoding stuff.
+ *
+ * Revision 1.12  1996/06/03 19:55:08  fritz
+ * Fixed typos.
+ *
  * Revision 1.11  1996/05/31 01:37:47  fritz
  * Minor changes, due to changes in isdn_tty.c
  *
@@ -451,10 +460,12 @@
   int                   xmit_count;      /* # of chars in xmit_buf         */
   unsigned char         *xmit_buf;       /* transmit buffer                */
   struct sk_buff_head   xmit_queue;      /* transmit queue                 */
+  struct sk_buff_head   dtmf_queue;      /* queue for dtmf results         */
   struct tty_struct 	*tty;            /* Pointer to corresponding tty   */
   atemu                 emu;             /* AT-emulator data               */
   void                  *adpcms;         /* state for adpcm decompression  */
   void                  *adpcmr;         /* state for adpcm compression    */
+  void                  *dtmf_state;     /* state for dtmf decoder         */
   struct termios	normal_termios;  /* For saving termios structs     */
   struct termios	callout_termios;
   struct wait_queue	*open_wait;
diff -u --recursive --new-file pre2.0.14/linux/include/linux/isdnif.h linux/include/linux/isdnif.h
--- pre2.0.14/linux/include/linux/isdnif.h	Mon May 20 08:21:04 1996
+++ linux/include/linux/isdnif.h	Fri Jun  7 16:02:43 1996
@@ -1,4 +1,4 @@
-/* $Id: isdnif.h,v 1.8 1996/05/18 01:45:37 fritz Exp $
+/* $Id: isdnif.h,v 1.9 1996/06/06 21:24:24 fritz Exp $
  *
  * Linux ISDN subsystem
  *
@@ -22,6 +22,9 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  *
  * $Log: isdnif.h,v $
+ * Revision 1.9  1996/06/06 21:24:24  fritz
+ * Started adding support for suspend/resume.
+ *
  * Revision 1.8  1996/05/18 01:45:37  fritz
  * More spelling corrections.
  *
@@ -85,21 +88,23 @@
  *
  */
 #define ISDN_CMD_IOCTL   0       /* Perform ioctl                         */
-#define ISDN_CMD_DIAL    1       /* Dial out                              */
-#define ISDN_CMD_ACCEPTD 2       /* Accept an incoming call on D-Chan.    */
-#define ISDN_CMD_ACCEPTB 3       /* Request B-Channel connect.            */
-#define ISDN_CMD_HANGUP  4       /* Hangup                                */
-#define ISDN_CMD_CLREAZ  5       /* Clear EAZ(s) of channel               */
-#define ISDN_CMD_SETEAZ  6       /* Set EAZ(s) of channel                 */
-#define ISDN_CMD_GETEAZ  7       /* Get EAZ(s) of channel                 */
-#define ISDN_CMD_SETSIL  8       /* Set Service-Indicator-List of channel */
-#define ISDN_CMD_GETSIL  9       /* Get Service-Indicator-List of channel */
-#define ISDN_CMD_SETL2  10       /* Set B-Chan. Layer2-Parameter          */
-#define ISDN_CMD_GETL2  11       /* Get B-Chan. Layer2-Parameter          */
-#define ISDN_CMD_SETL3  12       /* Set B-Chan. Layer3-Parameter          */
-#define ISDN_CMD_GETL3  13       /* Get B-Chan. Layer3-Parameter          */
-#define ISDN_CMD_LOCK   14       /* Signal usage by upper levels          */
-#define ISDN_CMD_UNLOCK 15       /* Release usage-lock                    */
+#define ISDN_CMD_DIAL     1       /* Dial out                              */
+#define ISDN_CMD_ACCEPTD  2       /* Accept an incoming call on D-Chan.    */
+#define ISDN_CMD_ACCEPTB  3       /* Request B-Channel connect.            */
+#define ISDN_CMD_HANGUP   4       /* Hangup                                */
+#define ISDN_CMD_CLREAZ   5       /* Clear EAZ(s) of channel               */
+#define ISDN_CMD_SETEAZ   6       /* Set EAZ(s) of channel                 */
+#define ISDN_CMD_GETEAZ   7       /* Get EAZ(s) of channel                 */
+#define ISDN_CMD_SETSIL   8       /* Set Service-Indicator-List of channel */
+#define ISDN_CMD_GETSIL   9       /* Get Service-Indicator-List of channel */
+#define ISDN_CMD_SETL2   10       /* Set B-Chan. Layer2-Parameter          */
+#define ISDN_CMD_GETL2   11       /* Get B-Chan. Layer2-Parameter          */
+#define ISDN_CMD_SETL3   12       /* Set B-Chan. Layer3-Parameter          */
+#define ISDN_CMD_GETL3   13       /* Get B-Chan. Layer3-Parameter          */
+#define ISDN_CMD_LOCK    14       /* Signal usage by upper levels          */
+#define ISDN_CMD_UNLOCK  15       /* Release usage-lock                    */
+#define ISDN_CMD_SUSPEND 16       /* Suspend connection                    */
+#define ISDN_CMD_RESUME  17       /* Resume connection                     */
 
 /*
  * Status-Values delivered from lowlevel to linklevel via
diff -u --recursive --new-file pre2.0.14/linux/include/net/sock.h linux/include/net/sock.h
--- pre2.0.14/linux/include/net/sock.h	Thu Jun  6 17:42:38 1996
+++ linux/include/net/sock.h	Sun Jun  9 12:25:41 1996
@@ -545,6 +545,6 @@
  *	Enable debug/info messages 
  */
 
-#define NETDEBUG(x)		x
+#define NETDEBUG(x)	do { } while (0)
 
 #endif	/* _SOCK_H */
diff -u --recursive --new-file pre2.0.14/linux/kernel/printk.c linux/kernel/printk.c
--- pre2.0.14/linux/kernel/printk.c	Fri Mar 15 10:23:04 1996
+++ linux/kernel/printk.c	Fri Jun  7 11:54:06 1996
@@ -33,7 +33,7 @@
 #define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING */
 
 /* We show everything that is MORE important than this.. */
-#define MINIMUM_CONSOLE_LOGLEVEL 5 /* Minimum loglevel we let people use */
+#define MINIMUM_CONSOLE_LOGLEVEL 1 /* Minimum loglevel we let people use */
 #define DEFAULT_CONSOLE_LOGLEVEL 7 /* anything MORE serious than KERN_DEBUG */
 
 unsigned long log_size = 0;
diff -u --recursive --new-file pre2.0.14/linux/kernel/sysctl.c linux/kernel/sysctl.c
--- pre2.0.14/linux/kernel/sysctl.c	Mon May 13 23:02:50 1996
+++ linux/kernel/sysctl.c	Fri Jun  7 15:45:21 1996
@@ -526,15 +526,13 @@
 		((char *) table->data)[len] = 0;
 		filp->f_pos += *lenp;
 	} else {
-		len = strlen(table->data) + 1;
+		len = strlen(table->data);
 		if (len > table->maxlen)
 			len = table->maxlen;
 		if (len > *lenp)
 			len = *lenp;
-		if (len) {			
-			memcpy_tofs(buffer, table->data, len-1);
-			put_user(0, ((char *) buffer) + len - 1);
-		}
+		if (len)
+			memcpy_tofs(buffer, table->data, len);
 		if (len < *lenp) {
 			put_user('\n', ((char *) buffer) + len);
 			len++;
diff -u --recursive --new-file pre2.0.14/linux/mm/kmalloc.c linux/mm/kmalloc.c
--- pre2.0.14/linux/mm/kmalloc.c	Mon Jun  3 16:46:59 1996
+++ linux/mm/kmalloc.c	Sat Jun  8 18:12:33 1996
@@ -375,69 +375,78 @@
 	return NULL;
 }
 
-void kfree(void *ptr)
+void kfree(void *__ptr)
 {
-	int size, dma;
+	int dma;
 	unsigned long flags;
-	int order;
-	register struct block_header *p;
+	unsigned int order;
 	struct page_descriptor *page, **pg;
+	struct size_descriptor *bucket;
 
-	if (!ptr)
-		return;
-	p = ((struct block_header *) ptr) - 1;
-	dma = 0;
-	page = PAGE_DESC(p);
+	if (!__ptr)
+		goto null_kfree;
+#define ptr ((struct block_header *) __ptr)
+	page = PAGE_DESC(ptr);
+	__ptr = ptr - 1;
+	if (~PAGE_MASK & (unsigned long)page->next)
+		goto bad_order;
 	order = page->order;
-	pg = &sizes[order].firstfree;
-	if (p->bh_flags == MF_DMA) {
+	if (order >= sizeof(sizes) / sizeof(sizes[0]))
+		goto bad_order;
+	bucket = sizes + order;
+	dma = 0;
+	pg = &bucket->firstfree;
+	if (ptr->bh_flags == MF_DMA) {
 		dma = 1;
-		p->bh_flags = MF_USED;
-		pg = &sizes[order].dmafree;
-	}
-
-	if ((order < 0) ||
-	    (order >= sizeof(sizes) / sizeof(sizes[0])) ||
-	    (((long) (page->next)) & ~PAGE_MASK) ||
-	    (p->bh_flags != MF_USED)) {
-		printk("kfree of non-kmalloced memory: %p, next= %p, order=%d\n",
-		       p, page->next, page->order);
-		return;
+		ptr->bh_flags = MF_USED;
+		pg = &bucket->dmafree;
 	}
-	size = p->bh_length;
-	p->bh_flags = MF_FREE;	/* As of now this block is officially free */
+	if (ptr->bh_flags != MF_USED)
+		goto bad_order;
+	ptr->bh_flags = MF_FREE;	/* As of now this block is officially free */
 #ifdef SADISTIC_KMALLOC
-	memset(p+1, 0xe0, size);
+	memset(ptr+1, 0xe0, ptr->bh_length);
 #endif
 	save_flags(flags);
 	cli();
-	p->bh_next = page->firstfree;
-	page->firstfree = p;
-	page->nfree++;
 
-	if (page->nfree == 1) {
+	bucket->nfrees++;
+	bucket->nbytesmalloced -= ptr->bh_length;
+
+	ptr->bh_next = page->firstfree;
+	page->firstfree = ptr;
+	if (!page->nfree++) {
 /* Page went from full to one free block: put it on the freelist. */
+		if (bucket->nblocks == 1)
+			goto free_page;
 		page->next = *pg;
 		*pg = page;
 	}
 /* If page is completely free, free it */
-	if (page->nfree == NBLOCKS(order)) {
+	if (page->nfree == bucket->nblocks) {
 		for (;;) {
 			struct page_descriptor *tmp = *pg;
-			if (!tmp) {
-				printk("Ooops. page %p doesn't show on freelist.\n", page);
-				break;
-			}
-			if (tmp == page) {
-				*pg = page->next;
+			if (!tmp)
+				goto not_on_freelist;
+			if (tmp == page)
 				break;
-			}
 			pg = &tmp->next;
 		}
-		sizes[order].npages--;
-		free_kmalloc_pages(page, sizes[order].gfporder, dma);
+		*pg = page->next;
+free_page:
+		bucket->npages--;
+		free_kmalloc_pages(page, bucket->gfporder, dma);
 	}
-	sizes[order].nfrees++;
-	sizes[order].nbytesmalloced -= size;
+	restore_flags(flags);
+null_kfree:
+	return;
+
+bad_order:
+	printk("kfree of non-kmalloced memory: %p, next= %p, order=%d\n",
+	       ptr+1, page->next, page->order);
+	return;
+
+not_on_freelist:
+	printk("Ooops. page %p doesn't show on freelist.\n", page);
 	restore_flags(flags);
 }
diff -u --recursive --new-file pre2.0.14/linux/net/core/sock.c linux/net/core/sock.c
--- pre2.0.14/linux/net/core/sock.c	Tue Apr  2 13:32:24 1996
+++ linux/net/core/sock.c	Fri Jun  7 11:58:11 1996
@@ -175,6 +175,8 @@
 				val = SK_WMEM_MAX*2;
 			if(val < 256)
 				val = 256;
+			if(val > 65535)
+				val = 65535;
 			sk->sndbuf = val;
 			return 0;
 
diff -u --recursive --new-file pre2.0.14/linux/net/ipv4/af_inet.c linux/net/ipv4/af_inet.c
--- pre2.0.14/linux/net/ipv4/af_inet.c	Sat Jun  1 20:11:37 1996
+++ linux/net/ipv4/af_inet.c	Fri Jun  7 10:14:29 1996
@@ -429,11 +429,8 @@
 	{
 		/* this should never happen. */
 		/* actually it can if an ack has just been sent. */
-		/*
-		 *	Make this a NETDEBUG at 2.0pre
-		 */
-		/*NETDEBUG(*/printk("Socket destroy delayed (r=%d w=%d)\n",
-			sk->rmem_alloc, sk->wmem_alloc)/*)*/;
+		NETDEBUG(printk("Socket destroy delayed (r=%d w=%d)\n",
+			sk->rmem_alloc, sk->wmem_alloc));
 		sk->destroy = 1;
 		sk->ack_backlog = 0;
 		release_sock(sk);
diff -u --recursive --new-file pre2.0.14/linux/net/ipv4/ip_fw.c linux/net/ipv4/ip_fw.c
--- pre2.0.14/linux/net/ipv4/ip_fw.c	Sat Jun  1 20:11:37 1996
+++ linux/net/ipv4/ip_fw.c	Sun Jun  9 09:22:34 1996
@@ -546,7 +546,7 @@
 						 * Note that redirport will become
 						 * 0xFFFF for non-TCP/UDP packets.
 						 */
-						*redirport = dst_port;
+						*redirport = htons(dst_port);
 					}
 				answer = FW_REDIRECT;
 			} else
diff -u --recursive --new-file pre2.0.14/linux/net/ipv4/raw.c linux/net/ipv4/raw.c
--- pre2.0.14/linux/net/ipv4/raw.c	Wed Jun  5 10:41:29 1996
+++ linux/net/ipv4/raw.c	Sat Jun  8 20:06:45 1996
@@ -204,7 +204,8 @@
 	 	 *	Deliberate breach of modularity to keep 
 	 	 *	ip_build_xmit clean (well less messy).
 		 */
-		iph->id = htons(ip_id_count++);
+		if (!iph->id)
+			iph->id = htons(ip_id_count++);
 		iph->check=ip_fast_csum((unsigned char *)iph, iph->ihl);
 	}
 }
diff -u --recursive --new-file pre2.0.14/linux/net/ipv4/tcp.c linux/net/ipv4/tcp.c
--- pre2.0.14/linux/net/ipv4/tcp.c	Sat Jun  1 20:11:37 1996
+++ linux/net/ipv4/tcp.c	Sat Jun  8 12:09:09 1996
@@ -1187,8 +1187,6 @@
 
 /*
  *	Send an ack if one is backlogged at this point.
- *
- *	This is called for delayed acks also.
  */
 
 void tcp_read_wakeup(struct sock *sk)
diff -u --recursive --new-file pre2.0.14/linux/net/ipv4/tcp_input.c linux/net/ipv4/tcp_input.c
--- pre2.0.14/linux/net/ipv4/tcp_input.c	Thu Jun  6 22:35:44 1996
+++ linux/net/ipv4/tcp_input.c	Sun Jun  9 11:39:09 1996
@@ -64,9 +64,15 @@
 		if (m <= 0)
 			m = 1;
 
-		if (m > (sk->rtt >> 3))
+		/* This used to test against sk->rtt.
+		 * On a purely receiving link, there is no rtt measure.
+		 * The result is that we loose delayed ACKs on one way links.
+		 * Therefore we test against sk->rto, which will always
+		 * at least have a default value.
+		 */
+		if (m > sk->rto)
 		{
-			sk->ato = sk->rtt >> 3;
+			sk->ato = sk->rto;
 			/*
 			 * printk(KERN_DEBUG "ato: rtt %lu\n", sk->ato);
 			 */
@@ -124,7 +130,12 @@
 	 *	Now update timeout.  Note that this removes any backoff.
 	 */
 			 
+	/* Jacobson's algorithm calls for rto = R + 4V.
+	 * We diverge from Jacobson's algorithm here. See the commentary
+	 * in tcp_ack to understand why.
+	 */
 	sk->rto = (sk->rtt >> 3) + sk->mdev;
+	sk->rto += (sk->rto>>2) + (sk->rto >> (sk->cong_window-1));
 	if (sk->rto > 120*HZ)
 		sk->rto = 120*HZ;
 	if (sk->rto < HZ/5)	/* Was 1*HZ - keep .2 as minimum cos of the BSD delayed acks */
@@ -195,7 +206,7 @@
 	/*
 	 * 	This packet is old news. Usually this is just a resend
 	 * 	from the far end, but sometimes it means the far end lost
-	 *	an ACK we send, so we better send an ACK.
+	 *	an ACK we sent, so we better send an ACK.
 	 */
 	tcp_send_ack(sk);
 }
@@ -842,8 +853,22 @@
 			 *  RTO = R*4V
 			 * In particular this gives better performance over
 			 * slow links, and should not effect fast links.
-			 */
+			 *
+			 * Note: Jacobson's algorithm is fine on BSD which
+			 * has a 1/2 second granularity clock, but with our
+			 * 1/100 second granularity clock we become too
+	 		 * sensitive to minor changes in the round trip time.
+			 * We add in two compensating factors.
+			 * First we multiply by 5/4. For large congestion
+			 * windows this allows us to tollerate burst traffic
+			 * delaying up to 1/4 of our packets.
+			 * We also add in a rtt / cong_window term.
+			 * For small congestion windows this allows
+			 * a single packet delay, but has neglibible effect
+			 * on the compensation for large windows.
+	 		 */
 			sk->rto = (sk->rtt >> 3) + sk->mdev;
+			sk->rto += (sk->rto>>2) + (sk->rto >> (sk->cong_window-1));
 			if (sk->rto > 120*HZ)
 				sk->rto = 120*HZ;
 			if (sk->rto < HZ/5)	/* Was 1*HZ, then 1 - turns out we must allow about
@@ -1247,8 +1272,18 @@
 			if (sk->ip_xmit_timeout != TIME_WRITE) {
 				if (sk->send_head)
 					tcp_reset_xmit_timer(sk, TIME_WRITE, sk->rto);
-				else
-					printk(KERN_ERR "send_head NULL in FIN_WAIT1\n");
+				else if (sk->ip_xmit_timeout != TIME_PROBE0
+				|| skb_queue_empty(&sk->write_queue)) {
+					/* BUG check case.
+					 * We have a problem here if there
+					 * is no timer running [leads to
+					 * frozen socket] or no data in the
+					 * write queue [means we sent a fin
+					 * and lost it from the queue before
+					 * changing the ack properly].
+					 */
+					printk(KERN_ERR "Lost timer or fin packet in tcp_fin.");
+				}
 			}
 			tcp_set_state(sk,TCP_CLOSING);
 			break;
@@ -1358,7 +1393,7 @@
 		} else {
 			if (sk->debug)
 				printk("Ack duplicate packet.\n");
-	    		tcp_send_ack(sk);
+			tcp_send_ack(sk);
 			return;
 		}
 
@@ -1865,8 +1900,14 @@
 			/* Crossed SYN or previous junk segment */
 			if(th->ack)
 			{
-				/* We got an ack, but it's not a good ack */
-				if(!tcp_ack(sk,th,skb->ack_seq,len))
+				/* We got an ack, but it's not a good ack.
+				 * We used to test this with a call to tcp_ack,
+				 * but this looses, because it takes the SYN
+				 * packet out of the send queue, even if
+				 * the ACK doesn't have the SYN bit sent, and
+				 * therefore isn't the one we are waiting for.
+				 */
+				if (after(skb->ack_seq, sk->sent_seq) || before(skb->ack_seq, sk->rcv_ack_seq))
 				{
 					/* Reset the ack - it's an ack from a 
 					   different connection  [ th->rst is checked in tcp_send_reset()] */
@@ -1888,6 +1929,15 @@
 					kfree_skb(skb, FREE_READ);
 					return 0;
 				}
+
+				/* process the ACK, get the SYN packet out
+				 * of the send queue, do other initial
+				 * processing stuff. [We know its good, and
+				 * we know it's the SYN,ACK we want.]
+				 */
+				tcp_ack(sk,th,skb->ack_seq,len);
+
+
 				/*
 				 *	Ok.. it's good. Set up sequence numbers and
 				 *	move to established.
diff -u --recursive --new-file pre2.0.14/linux/net/ipv4/tcp_output.c linux/net/ipv4/tcp_output.c
--- pre2.0.14/linux/net/ipv4/tcp_output.c	Thu Jun  6 17:42:39 1996
+++ linux/net/ipv4/tcp_output.c	Sat Jun  8 16:22:56 1996
@@ -882,11 +882,12 @@
 
 	/* Calculate new timeout */
 	now = jiffies;
-	if (timeout > max_timeout || sk->bytes_rcv >= sk->max_unacked) {
+	if (timeout > max_timeout)
+		timeout = max_timeout;
+	timeout += now;
+	if (sk->bytes_rcv >= sk->max_unacked) {
 		timeout = now;
 		mark_bh(TIMER_BH);
-	} else {
-		timeout += now;
 	}
 
 	/* Use new timeout only if there wasn't a older one earlier  */
diff -u --recursive --new-file pre2.0.14/linux/scripts/Makefile linux/scripts/Makefile
--- pre2.0.14/linux/scripts/Makefile	Mon Apr 15 12:20:22 1996
+++ linux/scripts/Makefile	Fri Jun  7 11:58:11 1996
@@ -2,12 +2,19 @@
 HEADER=header.tk
 TAIL=tail.tk
 
-SOUNDSCRIPT=${TOPDIR}/drivers/sound/Config.in
-
-${SOUNDSCRIPT}: ${TOPDIR}/drivers/sound/configure.c
+# We allow the Makefile in drivers/sound to decide when to rebuild its
+# files, rather than trying to second-guess it like we did before.
+#
+soundscript:
 	make -C ${TOPDIR}/drivers/sound mkscript
+	@echo
 
-kconfig.tk: ${SOUNDSCRIPT} ${TOPDIR}/Makefile ../arch/${ARCH}/config.in \
+# There is probably a better way to decide when to rebuild kconfig.tk; this
+# one won't catch every last change to the various Config.in files.  However,
+# the reliance on ${TOPDIR}/Makefile makes sure we at least rebuild when the
+# kernel version number changes.
+#
+kconfig.tk: soundscript ${TOPDIR}/Makefile ${TOPDIR}/arch/${ARCH}/config.in \
 		tkparse ${HEADER} ${TAIL}
 	./tkparse < ../arch/${ARCH}/config.in  > kconfig.tmp
 	@if [ -f /usr/local/bin/wish ];	then \
