diff -u --recursive --new-file v2.1.84/linux/CREDITS linux/CREDITS
--- v2.1.84/linux/CREDITS	Fri Jan 23 18:10:31 1998
+++ linux/CREDITS	Mon Feb  2 15:18:15 1998
@@ -730,6 +730,16 @@
 S: Wantage, New Jersey 07461
 S: USA
 
+N: Harald Hoyer
+E: HarryH@Royal.Net
+W: http://hot.spotline.de/
+W: http://home.pages.de/~saturn
+D: ip_masq_quake
+D: md boot support
+S: Alleenstrasse 27
+S: D-71679 Asperg
+S: Germany
+
 N: Miguel de Icaza Amozurrutia
 E: miguel@nuclecu.unam.mx
 D: Linux/SPARC team, Midnight Commander maintainer
@@ -1361,8 +1371,9 @@
 S: Germany
 
 N: Joerg Reuter
-E: jreuter@lykos.oche.de
-E: dl1bke@db0pra.ampr.org
+E: jreuter@poboxes.com
+W: http://www.rat.de/jr/
+W: http://qsl.net/dl1bke/
 D: Generic Z8530 driver, AX.25 DAMA slave implementation
 D: Several AX.25 hacks
 
diff -u --recursive --new-file v2.1.84/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- v2.1.84/linux/Documentation/Configure.help	Fri Jan 30 11:28:05 1998
+++ linux/Documentation/Configure.help	Mon Feb  2 14:51:31 1998
@@ -658,6 +658,11 @@
   want to compile it as a module, say M here and read
   Documentation/modules.txt. If unsure, say Y.
 
+Boot support (linear, striped)
+CONFIG_MD_BOOT
+  To boot with an initial linear or striped md device you have to 
+  select this. For lilo and loadlin options see Documentation/md.txt.
+
 Support for Deskstation RPC44 
 CONFIG_DESKSTATION_RPC44
   This is a machine with a R4400 100 MHz CPU. To compile a Linux
@@ -2737,29 +2742,54 @@
 
 IBMMCA SCSI support
 CONFIG_SCSI_IBMMCA
-  If your computer sports an MCA bus system architecture (IBM PS/2)
-  with an SCSI harddrive, say Y here. Please read
-  Documentation/mca.txt. This driver is also available as a module ( =
-  code which can be inserted in and removed from the running kernel
-  whenever you want). The module will be called ibmmca.o. If you want
-  to compile it as a module, say M here and read
-  Documentation/modules.txt.  
-  Normally, all IBM MCA SCSI adapters are automatically detected. If
-  that doesn't work right however, you can completely override
-  auto-detection by specifying "ibmmcascsi=io1,io2,..." at the boot
-  loader's command prompt or "io_port=io1,io2,... scsi_id=id1,id2,..."
-  as a parameter of insmod.  "io" and "id" are the I/O base address
-  and the SCSI ID of each adapter, respectively.
-  If you want to compile this driver as a module ( = code which can be
-  inserted in and removed from the running kernel whenever you want),
-  say M here and read Documentation/modules.txt. The module will be
-  called ibmmca.o.
-
-reset SCSI-devices while booting
-CONFIG_SCSI_IBMMCA_DEV_RESET
-  If you say Y here, each connected SCSI device will get a reset
-  command at boot time. This can be necessary for some special SCSI
-  devices. If unsure, say N.
+  This is support for the IBM SCSI adapter found in many of the PS/2
+  series.  CONFIG_MCA must be set for this to work.  If the adapter
+  isn't found during boot (a common problem for models 56, 57, 76, and
+  77) you'll need to use the 'ibmmcascsi=<pun>', where <pun> is the id
+  of the SCSI subsystem (usually 7, but if that doesn't work check your
+  reference diskette). Owners of model 95 with a LED-matrix-display
+  can in addition activate some activity info like under OS/2, but more
+  informative, by setting 'ibmmcascsi=display' as additional kernel-
+  parameter.
+
+Standard SCSI-order
+CONFIG_IBMMCA_SCSI_ORDER_STANDARD
+  In the PC-world and in most modern SCSI-BIOS-setups, SCSI-harddisks
+  are assigned to the driveletters, starting with the lowest SCSI-id
+  (physical number - pun) to be drive C:, as seen from DOS and similar
+  operating systems. When looking into papers, describing the
+  ANSI-SCSI-standard, this assignment of drives appears to be wrong.
+  The SCSI-standard follows a hardware-hierarchy which says, that
+  id 7 has the highest priority and id 0 the lowest. Therefore, the
+  hostadapters are still today everywhere placed as SCSI-id 7 by
+  default. In the SCSI-standard, the driveletters express the priority
+  of the disk. C: should be the harddisk or a partition on it, with the
+  highest priority. This must therefore be the disk with the highest
+  SCSI-id (e.g. 6) and not the one with the lowest! IBM-BIOS kept the
+  original definition of the SCSI-standard as also industrial- and
+  process-control-machines, like VME-CPUs running under realtime-OSs
+  (e.g. LynxOS, OS9) do.
+  If you like to run Linux on your MCA-machine with the same assignment,
+  of harddisks, as seen from e.g. DOS or OS/2 on your machine, which
+  is in addition conform to the SCSI-standard, you must say 'y' here.
+  This is also necessary for MCA-Linux-users who want to keep downward-
+  compatibility to older releases of the IBM-MCA-SCSI-driver (older than
+  driver-release 2.00 and older than June 1997).
+  If you like to have the lowest SCSI-id assigned as drive C:, as modern
+  SCSI-BIOS do, which is not conform to the standard, but widely spread
+  and common in the PC-world of today, you must say 'n' here.
+
+Reset SCSI-devices at boottime
+CONFIG_IBMMCA_SCSI_DEV_RESET
+  By default, SCSI-devices are reset, when the machine is powered on.
+  However, some devices exist, like special-control-devices,
+  SCSI-CNC-machines, SCSI-printer or scanners of older type, that
+  do not reset, when switched on. If you say 'y' here, each device
+  along your SCSI-bus will get a reset-command after it has been
+  probed, while the kernel is booting. Say always 'n' here, if you
+  have no such strange SCSI-devices on your bus. If you say 'y' and
+  some more modern devices, like harddisks, do not like too much
+  resets, your system will hang when booting.
 
 Always IN2000 SCSI support
 CONFIG_SCSI_IN2000
diff -u --recursive --new-file v2.1.84/linux/Documentation/IO-APIC.txt linux/Documentation/IO-APIC.txt
--- v2.1.84/linux/Documentation/IO-APIC.txt	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/IO-APIC.txt	Tue Feb  3 15:28:34 1998
@@ -0,0 +1,137 @@
+
+most (all) Intel SMP boards have the so-called 'IO-APIC', which is
+an enhanced interrupt controller, able to route hardware interrupts
+to multiple CPUs, or to CPU groups.
+
+Linux supports the IO-APIC, but unfortunately there are broken boards
+out there which make it unsafe to enable the IO-APIC unconditionally.
+The Linux policy thus is to enable the IO-APIC only if it's 100% safe, ie.:
+
+	   - the board is on the 'whitelist'
+
+	or - the board does not have PCI pins connected to the IO-APIC
+
+	or - the user has overriden blacklisted settings with the
+	     pirq= boot option line.
+
+Kernel messages tell you wether the board is 'safe'. If your box
+boots with enabled IO-APIC IRQs, then you have nothing else to do. Your
+/proc/interrupts will look like this one:
+
+   ---------------------------->
+   hell:~> cat /proc/interrupts
+              CPU0       CPU1
+     0:      90782          0   XT PIC   timer
+     1:       4135       2375  IO-APIC   keyboard
+     2:          0          0   XT PIC   cascade
+     3:        851        807  IO-APIC   serial
+     9:          6         22  IO-APIC   ncr53c8xx
+    11:        307        154  IO-APIC   NE2000
+    13:          4          0   XT PIC   fpu
+    14:      56000      30610  IO-APIC   ide0
+   NMI:          0
+   IPI:          0
+   <----------------------------
+
+some interrupts will still be 'XT PIC', but this is not a problem, none
+of those IRQ sources is 'heavy'.
+
+If one of your boot messages says 'unlisted/blacklisted board, DISABLING
+IO-APIC IRQs', then you should do this to get multi-CPU IO-APIC IRQs
+running:
+
+	A) if your board is unlisted, then mail to linux-smp to get
+	   it into either the white or the blacklist
+	B) if your board is blacklisted, then figure out the apropriate
+	   pirq= option to get your system boot
+
+
+pirq= lines look like the following in /etc/lilo.conf:
+
+	append="pirq=15,11,10"
+
+the actual numbers depend on your system, on your PCI cards and on their
+PCI slot position. Usually PCI slots are 'daisy chained' before they are
+connected to the PCI chipset irq routing facility (the incoming PIRQ1-4
+lines):
+
+               ,-.        ,-.        ,-.        ,-.        ,-.
+     PIRQ4 ----| |-.    ,-| |-.    ,-| |-.    ,-| |--------| |
+               |S|  \  /  |S|  \  /  |S|  \  /  |S|        |S|
+     PIRQ3 ----|l|-. `/---|l|-. `/---|l|-. `/---|l|--------|l|
+               |o|  \/    |o|  \/    |o|  \/    |o|        |o|
+     PIRQ2 ----|t|-./`----|t|-./`----|t|-./`----|t|--------|t|
+               |1| /\     |2| /\     |3| /\     |4|        |5|
+     PIRQ1 ----| |-  `----| |-  `----| |-  `----| |--------| |
+               `-'        `-'        `-'        `-'        `-'
+
+every PCI card emits a PCI IRQ, which can be INTA,INTB,INTC,INTD:
+
+                               ,-.
+                         INTD--| |
+                               |S|
+                         INTC--|l|
+                               |o|
+                         INTB--|t|
+                               |x|
+                         INTA--| |
+                               `-'
+
+These INTA-D PCI IRQs are always 'local to the card', their real meaning
+depends on which slot they are in. If you look at the daisy chaining diagram,
+a card in slot4, issuing INTA IRQ, it will end up as a signal on PIRQ2 of
+the PCI chipset. Most cards issue INTA, this creates optimal distibution
+between the PIRQ lines. (distributing IRQ sources properly is not a
+necessity, PCI IRQs can be shared at will, but it's a good for performance
+to have non shared interrupts). Slot5 should be used for videocards, they
+dont use interrupts normally, thus they are not daisy chained either.
+
+so if you have your SCSI card (IRQ11) in Slot1, Tulip card (IRQ9) in
+Slot2, then you'll have to specify this pirq= line:
+
+	append="pirq=11,9"
+
+the following script tries to figure out such a default pirq= line from
+your PCI configuration:
+
+	echo -n pirq=; echo `scanpci | grep T_L | cut -c56-` | sed 's/ /,/g'
+
+note that this script wont work if you have skipped a few slots or if your
+board does not do default daisy-chaining. (or the IO-APIC has the PIRQ pins
+connected in some strange way). Eg. if in the above case you have your SCSI
+card (IRQ11) in Slot3, and have Slot1 empty:
+
+	append="pirq=0,9,11"
+
+[value '0' is a generic 'placeholder', reserved for empty (or non-IRQ emitting)
+slots.]
+
+generally, it's always possible to find out the correct pirq= settings, just
+permutate all IRQ numbers properly ... it will take some time though. An
+'incorrect' pirq line will cause the booting process to hang, or a device
+wont function properly (if it's inserted as eg. a module).
+
+If you have 2 PCI buses, then you can use up to 8 pirq values. Although such
+boards tend to have a good configuration and will be included in the
+whitelist.
+
+Be prepared that it might happen that you need some strange pirq line:
+
+	append="pirq=0,0,0,0,0,0,9,11"
+
+use smart try-and-err techniques to find out the correct pirq line ...
+
+
+the following pirq line can be used to force a board into the whitelist:
+
+	append="pirq=0"
+
+[if your system works with no problems after this, then it should be added
+to the official whitelist, contact us]
+
+good luck and mail to linux-smp@vger.rutgers.edu or
+linux-kernel@vger.rutger.edu if you have any problems that are not covered
+by this document.
+
+-- mingo
+
diff -u --recursive --new-file v2.1.84/linux/Documentation/filesystems/isofs.txt linux/Documentation/filesystems/isofs.txt
--- v2.1.84/linux/Documentation/filesystems/isofs.txt	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/filesystems/isofs.txt	Mon Feb  2 14:47:47 1998
@@ -0,0 +1,32 @@
+Mount options that are the same as for msdos and vfat partitions.
+
+  conv=binary   Data is returned exactly as is, with CRLF's.  [default]
+  conv=text     (Carriage return, line feed) is replaced with newline.
+  conv=mtext    (Carriage return, line feed) is returned as is (?).
+  conv=auto     Chooses, file by file, conv=binary or conv=text (by guessing)
+  gid=nnn	All files in the partition will be in group nnn.
+  uid=nnn	All files in the partition will be owned by user id nnn.
+  umask=nnn	The permission mask (see umask(1)) for the partition.
+
+Mount options that are the same as vfat partitions. These are only useful
+when using discs encoded using Microsoft's Joliet extensions.
+  iocharset=name Character set to use for converting from Unicode to
+		ASCII.  Joliet filenames are stored in Unicode format, but
+		Unix for the most part doesn't know how to deal with Unicode.
+		There is also an option of doing UTF8 translations with the
+		utf8 option.
+  utf8          Encode Unicode names in UTF8 format. Default is no.
+
+Mount options that are unique to the isofs filesystem.
+  block=512     Set the block size for the disk to 512 bytes
+  block=1024    Set the block size for the disk to 1024 bytes
+  block=2048    Set the block size for the disk to 2048 bytes
+  check=relaxed Matches filenames with different cases
+  check=strict  Matches only filenames with the exact same case
+  cruft         Try to handle badly formatted CDs.
+  map=off       Do not map non-rockridge filenames to lowercase
+  map=normal    Map rockridge filenames to lowercase
+  mode=xxx      Sets the permissions on files to xxx
+  nojoliet      Ignore Joliet extensions if they are present.
+  norock        Ignore rockridge extensions if they are present.
+  unhide        Show hidden files.
diff -u --recursive --new-file v2.1.84/linux/Documentation/md.txt linux/Documentation/md.txt
--- v2.1.84/linux/Documentation/md.txt	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/md.txt	Mon Feb  2 13:07:47 1998
@@ -0,0 +1,37 @@
+Tools that manage md devices can be found at sweet-smoke.ufr-info-p7.ibp.fr
+in public/Linux/md035.tar.gz.
+
+	Marc ZYNGIER <zyngier@ufr-info-p7.ibp.fr>
+
+--
+
+You can boot (if you selected boot support in the configuration) with your md 
+device with the following kernel command line:
+
+md=<md device no.>,<raid level>,<chunk size factor>,<fault level>,dev0,dev1,...,devn
+
+md device no. = the number of the md device ... 
+              0 means md0, 
+	      1 md1,
+	      2 md2,
+	      3 md3,
+	      4 md4
+
+raid level = -1 linear mode
+              0 striped mode
+	      other modes are currently unsupported.
+
+chunk size factor = (raid-0 and raid-1 only)
+              Set  the chunk size as PAGE_SIZE << n.
+	      
+fault level = (raid-1 only)
+              Set  the maximum fault number as n.
+	      Currently unsupported due to lack of boot support for raid1.
+			    
+dev0-devn: e.g. /dev/hda1,/dev/hdc1,/dev/sda1,/dev/sdb1
+			    
+my loadlin line looks like this:
+
+e:\loadlin\loadlin e:\zimage root=/dev/md0 md=0,0,4,0,/dev/hdb2,/dev/hdc3 ro
+			    
+        Harald Hoyer <HarryH@Royal.Net>
diff -u --recursive --new-file v2.1.84/linux/Documentation/networking/scc.txt linux/Documentation/networking/scc.txt
--- v2.1.84/linux/Documentation/networking/scc.txt	Sat Nov 29 10:33:18 1997
+++ linux/Documentation/networking/scc.txt	Wed Dec 31 16:00:00 1969
@@ -1,23 +0,0 @@
-
-You will find subset of the documentation in
-
-                 linux/Documentation/networking/z8530drv.txt
-
-To use this driver you MUST have the full package from:
-
-Internet:
-=========
-
-1. db0bm.automation.fh-aachen.de/incoming/dl1bke/z8530drv-utils-3.0.tar.gz
-
-2. ftp.ucsd.edu:/hamradio/packet/tcpip/incoming/z8530drv-utils-3.0.tar.gz
-   If you can't find it there, try .../tcpip/linux/z8530drv-utils-3.0.tar.gz
-
-and various mirrors (i.e. nic.switch.ch)
-
-The package includes the utilities necessary to initialize and
-control the driver.
-
-Joerg Reuter	ampr-net: dl1bke@db0pra.ampr.org
-		AX-25   : DL1BKE @ DB0ACH.#NRW.DEU.EU
-		Internet: jreuter@lykos.oche.de
diff -u --recursive --new-file v2.1.84/linux/Documentation/networking/z8530drv.txt linux/Documentation/networking/z8530drv.txt
--- v2.1.84/linux/Documentation/networking/z8530drv.txt	Sat Nov 29 16:29:37 1997
+++ linux/Documentation/networking/z8530drv.txt	Mon Feb  2 15:18:15 1998
@@ -4,9 +4,9 @@
 Internet:
 =========
 
-1. ftp://db0bm.automation.fh-aachen.de/incoming/z8530drv/z8530drv-utils-3.0.tar.gz
+1. ftp://ftp.ccac.rwth-aachen.de/pub/jr/z8530drv-utils-3.0-1.tar.gz
 
-2. ftp://ftp.pspt.fi/pub/ham/linux/ax25/z8530drv-utils-3.0.tar.gz
+2. ftp://ftp.pspt.fi/pub/ham/linux/ax25/z8530drv-utils-3.0-1.tar.gz
 
 3. ftp://ftp.ucsd.edu/hamradio/packet/tcpip/incoming/z8530drv-utils-3.0.tar.gz
    If you can't find it there, try .../tcpip/linux/z8530drv-utils-3.0.tar.gz
@@ -23,7 +23,7 @@
 
    ********************************************************************
 
-        (c) 1993,1997 by Joerg Reuter DL1BKE <jreuter@poboxes.com>
+        (c) 1993,1998 by Joerg Reuter DL1BKE <jreuter@poboxes.com>
 
         portions (c) 1993 Guido ten Dolle PE1NNZ
 
diff -u --recursive --new-file v2.1.84/linux/MAINTAINERS linux/MAINTAINERS
--- v2.1.84/linux/MAINTAINERS	Mon Jan 12 15:21:04 1998
+++ linux/MAINTAINERS	Mon Feb  2 15:18:15 1998
@@ -156,7 +156,9 @@
 
 DAMA SLAVE for AX.25
 P:	Joerg Reuter
-M:	jreuter@lykos.oche.de
+M:	jreuter@poboxes.com
+W:	http://www.rat.de/jr/
+W:	http://qsl.net/dl1bke/
 L:	linux-hams@vger.rutgers.edu
 S:	Maintained
 
@@ -602,7 +604,9 @@
 
 Z8530 DRIVER FOR AX.25
 P:	Joerg Reuter
-M:	jreuter@lykos.oche.de
+M:	jreuter@poboxes.com
+W:	http://www.rat.de/jr/
+W:	http://qsl.net/dl1bke/
 L:	linux-hams@vger.rutgers.edu
 S:	Maintained
 
diff -u --recursive --new-file v2.1.84/linux/Makefile linux/Makefile
--- v2.1.84/linux/Makefile	Tue Feb  3 18:26:28 1998
+++ linux/Makefile	Mon Feb  2 15:06:34 1998
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 1
-SUBLEVEL = 84
+SUBLEVEL = 85
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/)
 
diff -u --recursive --new-file v2.1.84/linux/arch/alpha/config.in linux/arch/alpha/config.in
--- v2.1.84/linux/arch/alpha/config.in	Fri Jan 30 11:28:05 1998
+++ linux/arch/alpha/config.in	Mon Feb  2 15:18:15 1998
@@ -191,7 +191,7 @@
   endmenu
 fi
 
-source drivers/net/hamradio/Config.in
+source net/ax25/Config.in
 
 mainmenu_option next_comment
 comment 'ISDN subsystem'
diff -u --recursive --new-file v2.1.84/linux/arch/alpha/kernel/alpha_ksyms.c linux/arch/alpha/kernel/alpha_ksyms.c
--- v2.1.84/linux/arch/alpha/kernel/alpha_ksyms.c	Mon Dec 22 09:58:21 1997
+++ linux/arch/alpha/kernel/alpha_ksyms.c	Mon Feb  2 13:41:06 1998
@@ -40,7 +40,7 @@
 extern void __divqu (void);
 extern void __remqu (void);
 
-EXPORT_SYMBOL(__alpha_bh_counter);
+EXPORT_SYMBOL(local_bh_count);
 EXPORT_SYMBOL(local_irq_count);
 
 /* platform dependent support */
diff -u --recursive --new-file v2.1.84/linux/arch/alpha/kernel/irq.c linux/arch/alpha/kernel/irq.c
--- v2.1.84/linux/arch/alpha/kernel/irq.c	Fri Jan 30 11:28:05 1998
+++ linux/arch/alpha/kernel/irq.c	Mon Feb  2 13:41:06 1998
@@ -524,7 +524,7 @@
 }
 
 unsigned int local_irq_count[NR_CPUS];
-atomic_t __alpha_bh_counter;
+unsigned int local_bh_count[NR_CPUS];
 
 #ifdef __SMP__
 #error "Me no hablo Alpha SMP"
diff -u --recursive --new-file v2.1.84/linux/arch/i386/Makefile linux/arch/i386/Makefile
--- v2.1.84/linux/arch/i386/Makefile	Tue Oct 14 18:24:09 1997
+++ linux/arch/i386/Makefile	Mon Feb  2 15:25:16 1998
@@ -23,7 +23,9 @@
 LDFLAGS=-e stext
 LINKFLAGS =-T $(TOPDIR)/arch/i386/vmlinux.lds $(LDFLAGS)
 
-CFLAGS := $(CFLAGS) -pipe -fno-strength-reduce
+CFLAGS_PIPE := -pipe
+CFLAGS_NSR  := -fno-strength-reduce
+CFLAGS := $(CFLAGS) $(CFLAGS_PIPE) $(CFLAGS_NSR)
 
 ifdef CONFIG_M386
 CFLAGS := $(CFLAGS) -m386 -DCPU=386
diff -u --recursive --new-file v2.1.84/linux/arch/i386/config.in linux/arch/i386/config.in
--- v2.1.84/linux/arch/i386/config.in	Fri Jan 30 11:28:05 1998
+++ linux/arch/i386/config.in	Mon Feb  2 15:18:15 1998
@@ -93,7 +93,7 @@
   endmenu
 fi
 
-source drivers/net/hamradio/Config.in
+source net/ax25/Config.in
 
 mainmenu_option next_comment
 comment 'ISDN subsystem'
diff -u --recursive --new-file v2.1.84/linux/arch/i386/kernel/bios32.c linux/arch/i386/kernel/bios32.c
--- v2.1.84/linux/arch/i386/kernel/bios32.c	Sun Dec 21 17:27:18 1997
+++ linux/arch/i386/kernel/bios32.c	Tue Feb  3 16:20:18 1998
@@ -78,6 +78,13 @@
 #include <asm/system.h>
 #include <asm/io.h>
 
+#include <linux/smp_lock.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+#include <asm/smp.h>
+
+#include "irq.h"
+
 /*
  * Generic PCI access -- indirect calls according to detected HW.
  */
@@ -133,7 +140,39 @@
 int pcibios_read_config_byte (unsigned char bus,
 	unsigned char device_fn, unsigned char where, unsigned char *value)
 {
-	return access_pci->read_config_byte(bus, device_fn, where, value);
+	int res;
+
+	res = access_pci->read_config_byte(bus, device_fn, where, value);
+
+#ifdef __SMP__
+/*
+ * IOAPICs can take PCI IRQs directly, lets first check the mptable:
+ */
+	if (where == PCI_INTERRUPT_LINE) {
+		int irq;
+		char pin;
+
+		/*
+		 * get the PCI IRQ INT _physical pin_ for this device
+		 */
+		access_pci->read_config_byte(bus, device_fn,
+						PCI_INTERRUPT_PIN, &pin);
+		/*
+		 * subtle, PCI pins are numbered starting from 1 ...
+		 */
+		pin--;
+
+		irq = IO_APIC_get_PCI_irq_vector (bus,PCI_SLOT(device_fn),pin);
+		if (irq != -1)
+			*value = (unsigned char) irq;
+
+		printk("PCI->APIC IRQ transform: (B%d,I%d,P%d) -> %d\n",
+			bus,PCI_SLOT(device_fn), pin, irq);
+
+	}
+#endif
+
+	return res;
 }
 
 int pcibios_read_config_word (unsigned char bus,
diff -u --recursive --new-file v2.1.84/linux/arch/i386/kernel/io_apic.c linux/arch/i386/kernel/io_apic.c
--- v2.1.84/linux/arch/i386/kernel/io_apic.c	Tue Jan 20 12:52:09 1998
+++ linux/arch/i386/kernel/io_apic.c	Tue Feb  3 18:05:20 1998
@@ -109,7 +109,7 @@
 	*(io_apic_reg+4) = value;
 }
 
-void enable_IO_APIC_irq (int irq)
+void enable_IO_APIC_irq (unsigned int irq)
 {
 	struct IO_APIC_route_entry entry;
 
@@ -121,7 +121,11 @@
 	io_apic_write(0x10+2*irq, *(((int *)&entry)+0));
 }
 
-void disable_IO_APIC_irq (int irq)
+/*
+ * this function is just here to make things complete, otherwise it's
+ * unused
+ */
+void disable_IO_APIC_irq (unsigned int irq)
 {
 	struct IO_APIC_route_entry entry;
 
@@ -133,7 +137,7 @@
 	io_apic_write(0x10+2*irq, *(((int *)&entry)+0));
 }
 
-void clear_IO_APIC_irq (int irq)
+void clear_IO_APIC_irq (unsigned int irq)
 {
 	struct IO_APIC_route_entry entry;
 
@@ -151,8 +155,9 @@
  * specific CPU-side IRQs.
  */
 
-#define MAX_PIRQS 4
+#define MAX_PIRQS 8
 int pirq_entries [MAX_PIRQS];
+int pirqs_enabled;
 
 void ioapic_pirq_setup(char *str, int *ints)
 {
@@ -161,9 +166,12 @@
 	for (i=0; i<MAX_PIRQS; i++)
 		pirq_entries[i]=-1;
 
-	if (!ints)
+	if (!ints) {
+		pirqs_enabled=0;
 		printk("PIRQ redirection SETUP, trusting MP-BIOS.\n");
-	else {
+
+	} else {
+		pirqs_enabled=1;
 		printk("PIRQ redirection SETUP, working around broken MP-BIOS.\n");
 		max = MAX_PIRQS;
 		if (ints[0] < MAX_PIRQS)
@@ -229,9 +237,10 @@
 			}
 			case MP_BUS_PCI: /* PCI pin */
 			{
-				irq = mp_irqs[idx].mpc_srcbusirq >> 2;
-				if (irq>=16)
-					printk("WARNING: MP BIOS says PIRQ%d is redirected to %d, suspicious.\n",idx-16, irq); 
+				/*
+				 * PCI IRQs are 'directly mapped'
+				 */
+				irq = i;
 				break;
 			}
 			default:
@@ -358,7 +367,7 @@
 		printk(" not connected.\n");
 }
 
-void setup_IO_APIC_irq_ISA_default (int irq)
+void setup_IO_APIC_irq_ISA_default (unsigned int irq)
 {
 	struct IO_APIC_route_entry entry;
 
@@ -381,8 +390,23 @@
 	io_apic_write(0x11+2*irq, *(((int *)&entry)+1));
 }
 
-void setup_IO_APIC_irq (int irq)
+int IO_APIC_get_PCI_irq_vector (int bus, int slot, int pci_pin)
 {
+	int i;
+
+	for (i=0; i<mp_irq_entries; i++) {
+		int lbus = mp_irqs[i].mpc_srcbus;
+
+		if (IO_APIC_IRQ(i) &&
+		    (mp_bus_id_to_type[lbus] == MP_BUS_PCI) &&
+		    !mp_irqs[i].mpc_irqtype &&
+		    (bus == mp_irqs[i].mpc_srcbus) &&
+		    (slot == (mp_irqs[i].mpc_srcbusirq >> 2)) &&
+		    (pci_pin == (mp_irqs[i].mpc_srcbusirq & 3)))
+
+			return mp_irqs[i].mpc_dstirq;
+	}
+	return -1;
 }
 
 void print_IO_APIC (void)
@@ -471,6 +495,47 @@
 	printk("...done.\n");
 }
 
+char ioapic_OEM_ID [16];
+char ioapic_Product_ID [16];
+
+struct ioapic_list_entry {
+	char * oem_id;
+	char * product_id;
+};
+
+struct ioapic_list_entry ioapic_whitelist [] = {
+
+	{ "INTEL   "	, 	"PR440FX     "	},
+	{ 0		,	0		}
+};
+
+struct ioapic_list_entry ioapic_blacklist [] = {
+
+	{ "OEM00000"	,	"PROD00000000"	},
+	{ 0		,	0		}
+};
+
+
+static int in_ioapic_list (struct ioapic_list_entry * table)
+{
+	for (;table->oem_id; table++)
+		if ((!strcmp(table->oem_id,ioapic_OEM_ID)) &&
+		    (!strcmp(table->product_id,ioapic_Product_ID)))
+			return 1;
+	return 0;
+}
+
+static int ioapic_whitelisted (void)
+{
+	return in_ioapic_list(ioapic_whitelist);
+}
+
+static int ioapic_blacklisted (void)
+{
+	return in_ioapic_list(ioapic_blacklist);
+}
+
+
 void setup_IO_APIC (void)
 {
 	int i;
@@ -490,8 +555,6 @@
 		nr_ioapic_registers = reg_01.entries+1;
 	}
 
-	init_IO_APIC_traps();
-
 	/*
 	 * do not trust the IO-APIC being empty at bootup
 	 */
@@ -504,6 +567,30 @@
 			setup_IO_APIC_irq_ISA_default (i);
 #endif
 
+	/*
+	 * the following IO-APIC's can be enabled:
+	 *
+	 * - whitelisted ones
+	 * - those which have no PCI pins connected
+	 * - those for which the user has specified a pirq= parameter
+	 */
+	if (	ioapic_whitelisted() ||
+		(nr_ioapic_registers == 16) ||
+		pirqs_enabled)
+	{
+		printk("ENABLING IO-APIC IRQs\n");
+		io_apic_irqs = ~((1<<0)|(1<<2)|(1<<13));
+	} else {
+		if (ioapic_blacklisted())
+			printk(" blacklisted board, DISABLING IO-APIC IRQs\n");
+		else
+			printk(" unlisted board, DISABLING IO-APIC IRQs\n");
+
+		printk(" see Documentation/IO-APIC.txt to enable them\n");
+		io_apic_irqs = 0;
+	}
+
+	init_IO_APIC_traps();
 	setup_IO_APIC_irqs ();
 
 	printk("nr of MP irq sources: %d.\n", mp_irq_entries);
diff -u --recursive --new-file v2.1.84/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c
--- v2.1.84/linux/arch/i386/kernel/irq.c	Fri Jan 30 15:50:56 1998
+++ linux/arch/i386/kernel/irq.c	Tue Feb  3 15:30:28 1998
@@ -1,7 +1,7 @@
 /*
  *	linux/arch/i386/kernel/irq.c
  *
- *	Copyright (C) 1992 Linus Torvalds
+ *	Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
  *
  * This file contains the code used by various IRQ handling routines:
  * asking for different IRQ's should be done through these routines
@@ -41,33 +41,6 @@
 
 #include "irq.h"
 
-/*
- * I had a lockup scenario where a tight loop doing
- * spin_unlock()/spin_lock() on CPU#1 was racing with
- * spin_lock() on CPU#0. CPU#0 should have noticed spin_unlock(), but
- * apparently the spin_unlock() information did not make it
- * through to CPU#0 ... nasty, is this by design, do we haveto limit
- * 'memory update oscillation frequency' artificially like here?
- *
- * Such 'high frequency update' races can be avoided by careful design, but
- * some of our major constructs like spinlocks use similar techniques,
- * it would be nice to clarify this issue. Set this define to 0 if you
- * want to check wether your system freezes. I suspect the delay done
- * by SYNC_OTHER_CORES() is in correlation with 'snooping latency', but
- * i thought that such things are guaranteed by design, since we use
- * the 'LOCK' prefix.
- */
-#define SUSPECTED_CPU_OR_CHIPSET_BUG_WORKAROUND 1
-
-#if SUSPECTED_CPU_OR_CHIPSET_BUG_WORKAROUND
-# define SYNC_OTHER_CORES(x) udelay(x+1)
-#else
-/*
- * We have to allow irqs to arrive between __sti and __cli
- */
-# define SYNC_OTHER_CORES(x) __asm__ __volatile__ ("nop")
-#endif
-
 unsigned int local_bh_count[NR_CPUS];
 unsigned int local_irq_count[NR_CPUS];
 
@@ -96,11 +69,8 @@
 
 spinlock_t irq_controller_lock;
 
-static int irq_events [NR_IRQS] = { -1, };
+static unsigned int irq_events [NR_IRQS] = { -1, };
 static int disabled_irq [NR_IRQS] = { 0, };
-#ifdef __SMP__
-static int irq_owner [NR_IRQS] = { NO_PROC_ID, };
-#endif
 
 /*
  * Not all IRQs can be routed through the IO-APIC, eg. on certain (older)
@@ -125,10 +95,54 @@
    *  - explicitly use irq 16-19 depending on which PCI irq
    *    line your PCI controller uses.
    */
-  unsigned int io_apic_irqs = 0xff0000;
+  unsigned int io_apic_irqs = 0;
+#endif
+
+struct hw_interrupt_type {
+	void (*handle)(unsigned int irq, int cpu, struct pt_regs * regs);
+	void (*enable)(unsigned int irq);
+	void (*disable)(unsigned int irq);
+};
+
+
+static void do_8259A_IRQ (unsigned int irq, int cpu, struct pt_regs * regs);
+static void enable_8259A_irq (unsigned int irq);
+static void disable_8259A_irq (unsigned int irq);
+
+static struct hw_interrupt_type i8259A_irq_type = {
+	do_8259A_IRQ,
+	enable_8259A_irq,
+	disable_8259A_irq
+};
+
+
+#ifdef __SMP__
+static void do_ioapic_IRQ (unsigned int irq, int cpu, struct pt_regs * regs);
+static void enable_ioapic_irq (unsigned int irq);
+static void disable_ioapic_irq (unsigned int irq);
+
+static struct hw_interrupt_type ioapic_irq_type = {
+	do_ioapic_IRQ,
+	enable_ioapic_irq,
+	disable_ioapic_irq
+};
 #endif
 
-static inline void mask_8259A(int irq)
+struct hw_interrupt_type *irq_handles[NR_IRQS] =
+{
+	[0 ... 15] = &i8259A_irq_type			/* standard ISA IRQs */
+#ifdef __SMP__
+	, [16 ... NR_IRQS-1] = &ioapic_irq_type		/* 'high' PCI IRQs */
+#endif
+};
+
+
+/*
+ * These have to be protected by the irq controller spinlock
+ * before being called.
+ */
+
+static inline void mask_8259A(unsigned int irq)
 {
 	cached_irq_mask |= 1 << irq;
 	if (irq & 8) {
@@ -138,7 +152,7 @@
 	}
 }
 
-static inline void unmask_8259A(int irq)
+static inline void unmask_8259A(unsigned int irq)
 {
 	cached_irq_mask &= ~(1 << irq);
 	if (irq & 8) {
@@ -148,7 +162,7 @@
 	}
 }
 
-void set_8259A_irq_mask(int irq)
+void set_8259A_irq_mask(unsigned int irq)
 {
 	/*
 	 * (it might happen that we see IRQ>15 on a UP box, with SMP
@@ -163,21 +177,7 @@
 	}
 }
 
-/*
- * These have to be protected by the spinlock
- * before being called.
- */
-void mask_irq(unsigned int irq)
-{
-	if (IO_APIC_IRQ(irq))
-		disable_IO_APIC_irq(irq);
-	else {
-		cached_irq_mask |= 1 << irq;
-		set_8259A_irq_mask(irq);
-	}
-}
-
-void unmask_irq(unsigned int irq)
+void unmask_generic_irq(unsigned int irq)
 {
 	if (IO_APIC_IRQ(irq))
 		enable_IO_APIC_irq(irq);
@@ -218,8 +218,8 @@
 BUILD_IRQ(16) BUILD_IRQ(17) BUILD_IRQ(18) BUILD_IRQ(19)
 
 /*
- * [FIXME: anyone with 2 separate PCI buses and 2 IO-APICs,
- *         please speak up and request experimental patches.
+ * [FIXME: anyone with 2 separate PCI buses and 2 IO-APICs, please
+ *	   speak up if problems and request experimental patches.
  *         --mingo ]
  */
 
@@ -417,6 +417,33 @@
 	} while (atomic_read(&global_bh_count) != 0);
 }
 
+/*
+ * I had a lockup scenario where a tight loop doing
+ * spin_unlock()/spin_lock() on CPU#1 was racing with
+ * spin_lock() on CPU#0. CPU#0 should have noticed spin_unlock(), but
+ * apparently the spin_unlock() information did not make it
+ * through to CPU#0 ... nasty, is this by design, do we have to limit
+ * 'memory update oscillation frequency' artificially like here?
+ *
+ * Such 'high frequency update' races can be avoided by careful design, but
+ * some of our major constructs like spinlocks use similar techniques,
+ * it would be nice to clarify this issue. Set this define to 0 if you
+ * want to check wether your system freezes. I suspect the delay done
+ * by SYNC_OTHER_CORES() is in correlation with 'snooping latency', but
+ * i thought that such things are guaranteed by design, since we use
+ * the 'LOCK' prefix.
+ */
+#define SUSPECTED_CPU_OR_CHIPSET_BUG_WORKAROUND 1
+
+#if SUSPECTED_CPU_OR_CHIPSET_BUG_WORKAROUND
+# define SYNC_OTHER_CORES(x) udelay(x+1)
+#else
+/*
+ * We have to allow irqs to arrive between __sti and __cli
+ */
+# define SYNC_OTHER_CORES(x) __asm__ __volatile__ ("nop")
+#endif
+
 static inline void wait_on_irq(int cpu)
 {
 	int count = MAXCOUNT;
@@ -563,7 +590,7 @@
 
 #endif
 
-static int handle_IRQ_event(int irq, struct pt_regs * regs)
+static int handle_IRQ_event(unsigned int irq, struct pt_regs * regs)
 {
 	struct irqaction * action;
 	int status;
@@ -591,43 +618,118 @@
 }
 
 
-/*
- * disable/enable_irq() wait for all irq contexts to finish
- * executing. Also it's recursive.
- */
 void disable_irq(unsigned int irq)
 {
 	unsigned long flags;
 
 	spin_lock_irqsave(&irq_controller_lock, flags);
-	disabled_irq[irq]++;
-	mask_irq(irq);
+	irq_handles[irq]->disable(irq);
 	spin_unlock_irqrestore(&irq_controller_lock, flags);
 
 	synchronize_irq();
 }
 
-void enable_irq(unsigned int irq)
+/*
+ * disable/enable_irq() wait for all irq contexts to finish
+ * executing. Also it's recursive.
+ */
+static void disable_8259A_irq(unsigned int irq)
 {
-	unsigned long flags;
+	disabled_irq[irq]++;
+	cached_irq_mask |= 1 << irq;
+	set_8259A_irq_mask(irq);
+}
+
+#ifdef __SMP__
+static void disable_ioapic_irq(unsigned int irq)
+{
+	disabled_irq[irq]++;
+	/*
+	 * We do not disable IO-APIC irqs in hardware ...
+	 */
+}
+#endif
 
+void enable_8259A_irq (unsigned int irq)
+{
+	unsigned long flags;
 	spin_lock_irqsave(&irq_controller_lock, flags);
-	disabled_irq[irq]--;
-	unmask_irq(irq);
+	if (disabled_irq[irq])
+		disabled_irq[irq]--;
+	else {
+		spin_unlock_irqrestore(&irq_controller_lock, flags);
+		return;
+	}
+	cached_irq_mask &= ~(1 << irq);
+	set_8259A_irq_mask(irq);
 	spin_unlock_irqrestore(&irq_controller_lock, flags);
 }
 
+#ifdef __SMP__
+void enable_ioapic_irq (unsigned int irq)
+{
+	unsigned long flags;
+	int cpu = smp_processor_id(), should_handle_irq;
+
+	spin_lock_irqsave(&irq_controller_lock, flags);
+	if (disabled_irq[irq])
+		disabled_irq[irq]--;
+	else {
+		spin_unlock_irqrestore(&irq_controller_lock, flags);
+		return;
+	}
+	/*
+	 * In the SMP+IOAPIC case it might happen that there are an unspecified
+	 * number of pending IRQ events unhandled. We protect against multiple
+	 * enable_irq()'s executing them via disable_irq[irq]++
+	 */
+	if (!disabled_irq[irq] && irq_events[irq]) {
+		struct pt_regs regs; /* FIXME: these are fake currently */
+
+		disabled_irq[irq]++;
+		spin_unlock(&irq_controller_lock);
+		release_irqlock(cpu);
+		irq_enter(cpu, irq);
+again:
+		handle_IRQ_event(irq, &regs);
+
+		spin_lock(&irq_controller_lock);
+		disabled_irq[irq]--;
+		should_handle_irq=0;
+		if (--irq_events[irq] && !disabled_irq[irq]) {
+			should_handle_irq=1;
+			disabled_irq[irq]++;
+		}
+		spin_unlock(&irq_controller_lock);
+
+		if (should_handle_irq)
+			goto again;
+
+		irq_exit(cpu, irq);
+		__restore_flags(flags);
+	} else {
+		enable_IO_APIC_irq(irq);
+		spin_unlock_irqrestore(&irq_controller_lock, flags);
+	}
+}
+#endif
+
+void enable_irq(unsigned int irq)
+{
+	irq_handles[irq]->enable(irq);
+}
+
 /*
  * Careful! The 8259A is a fragile beast, it pretty
  * much _has_ to be done exactly like this (mask it
  * first, _then_ send the EOI, and the order of EOI
  * to the two 8259s is important!
  */
-static inline void mask_and_ack_8259A(int irq_nr)
+static inline void mask_and_ack_8259A(unsigned int irq)
 {
 	spin_lock(&irq_controller_lock);
-	cached_irq_mask |= 1 << irq_nr;
-	if (irq_nr & 8) {
+	cached_irq_mask |= 1 << irq;
+	if (irq & 8) {
 		inb(0xA1);	/* DUMMY */
 		outb(cached_A1,0xA1);
 		outb(0x62,0x20);	/* Specific EOI to cascade */
@@ -640,7 +742,7 @@
 	spin_unlock(&irq_controller_lock);
 }
 
-static void do_8259A_IRQ(int irq, int cpu, struct pt_regs * regs)
+static void do_8259A_IRQ(unsigned int irq, int cpu, struct pt_regs * regs)
 {
 	mask_and_ack_8259A(irq);
 
@@ -656,45 +758,36 @@
 }
 
 #ifdef __SMP__
-/*
- * FIXME! This is completely broken.
- */
-static void do_ioapic_IRQ(int irq, int cpu, struct pt_regs * regs)
+static void do_ioapic_IRQ(unsigned int irq, int cpu, struct pt_regs * regs)
 {
-	int should_handle_irq;
+	int should_handle_irq = 0;
+
+	ack_APIC_irq();
 
 	spin_lock(&irq_controller_lock);
-	should_handle_irq = 0;
-	if (!irq_events[irq]++ && !disabled_irq[irq]) {
-		should_handle_irq = 1;
-		irq_owner[irq] = cpu;
-		hardirq_enter(cpu);
-	}
 
-	ack_APIC_irq();
+	if (!irq_events[irq]++ && !disabled_irq[irq])
+		should_handle_irq = 1;
 
 	spin_unlock(&irq_controller_lock);
-	
-	if (should_handle_irq) {
-again:
-		if (!handle_IRQ_event(irq, regs))
-			disabled_irq[irq] = 1;
 
-	}
+	irq_enter(cpu, irq);
 
-	spin_lock(&irq_controller_lock);
-	release_irqlock(cpu);
+	if (should_handle_irq) {
+again:
+		handle_IRQ_event(irq, regs);
 
-	if ((--irq_events[irq]) && (!disabled_irq[irq]) && should_handle_irq) {
+		spin_lock(&irq_controller_lock);
+		should_handle_irq=0;
+		if (--irq_events[irq] && !disabled_irq[irq])
+			should_handle_irq=1;
 		spin_unlock(&irq_controller_lock);
-		goto again;
-	}
 
-	irq_owner[irq] = NO_PROC_ID;
-	hardirq_exit(cpu);
-	spin_unlock(&irq_controller_lock);
+		if (should_handle_irq)
+			goto again;
+	}
 
-	enable_IO_APIC_irq(irq);
+	irq_exit(cpu, irq);
 }
 #endif
 
@@ -714,8 +807,6 @@
  */
 asmlinkage void do_IRQ(struct pt_regs regs)
 {	
-	void (*do_lowlevel_IRQ)(int, int, struct pt_regs *);
-
 	/* 
 	 * We ack quickly, we don't want the irq controller
 	 * thinking we're snobs just because some other CPU has
@@ -726,18 +817,11 @@
 	 * 0 return value means that this irq is already being
 	 * handled by some other CPU. (or is disabled)
 	 */
-	int irq = regs.orig_eax & 0xff;
+	unsigned int irq = regs.orig_eax & 0xff;
 	int cpu = smp_processor_id();
 
 	kstat.irqs[cpu][irq]++;
-
-	do_lowlevel_IRQ = do_8259A_IRQ;
-#ifdef __SMP__
-	if (IO_APIC_IRQ(irq))
-		do_lowlevel_IRQ = do_ioapic_IRQ;
-#endif
-	
-	do_lowlevel_IRQ(irq, cpu, &regs);
+	irq_handles[irq]->handle(irq, cpu, &regs);
 
 	/*
 	 * This should be conditional: we should really get
@@ -751,7 +835,7 @@
 	}
 }
 
-int setup_x86_irq(int irq, struct irqaction * new)
+int setup_x86_irq(unsigned int irq, struct irqaction * new)
 {
 	int shared = 0;
 	struct irqaction *old, **p;
@@ -780,16 +864,18 @@
 
 	if (!shared) {
 		spin_lock(&irq_controller_lock);
+#ifdef __SMP__
 		if (IO_APIC_IRQ(irq)) {
+			irq_handles[irq] = &ioapic_irq_type;
 			/*
 			 * First disable it in the 8259A:
 			 */
 			cached_irq_mask |= 1 << irq;
 			if (irq < 16)
 				set_8259A_irq_mask(irq);
-			setup_IO_APIC_irq(irq);
 		}
-		unmask_irq(irq);
+#endif
+		unmask_generic_irq(irq);
 		spin_unlock(&irq_controller_lock);
 	}
 	restore_flags(flags);
@@ -873,10 +959,11 @@
 	 */
 	for (i = NR_IRQS-1; i > 0; i--) {
 		if (!irq_action[i]) {
-			spin_lock(&irq_controller_lock);
-			unmask_irq(i);
+			unsigned long flags;
+			spin_lock_irqsave(&irq_controller_lock, flags);
+			unmask_generic_irq(i);
 			irqs |= (1 << i);
-			spin_unlock(&irq_controller_lock);
+			spin_unlock_irqrestore(&irq_controller_lock, flags);
 		}
 	}
 
@@ -921,6 +1008,7 @@
 	return irq_found;
 }
 
+#ifdef __SMP__
 void init_IO_APIC_traps(void)
 {
 	int i;
@@ -938,16 +1026,17 @@
 	for (i = 0; i < NR_IRQS ; i++)
 		if (IO_APIC_GATE_OFFSET+(i<<3) <= 0xfe)  /* HACK */ {
 			if (IO_APIC_IRQ(i)) {
+				irq_handles[i] = &ioapic_irq_type;
 				/*
 				 * First disable it in the 8259A:
 				 */
 				cached_irq_mask |= 1 << i;
 				if (i < 16)
 					set_8259A_irq_mask(i);
-				setup_IO_APIC_irq(i);
 			}
 		}
 }
+#endif
 
 __initfunc(void init_IRQ(void))
 {
@@ -961,9 +1050,6 @@
 	printk("INIT IRQ\n");
 	for (i=0; i<NR_IRQS; i++) {
 		irq_events[i] = 0;
-#ifdef __SMP__
-		irq_owner[i] = NO_PROC_ID;
-#endif
 		disabled_irq[i] = 0;
 	}
 	/*
diff -u --recursive --new-file v2.1.84/linux/arch/i386/kernel/irq.h linux/arch/i386/kernel/irq.h
--- v2.1.84/linux/arch/i386/kernel/irq.h	Fri Jan 23 18:10:31 1998
+++ linux/arch/i386/kernel/irq.h	Tue Feb  3 15:28:34 1998
@@ -9,15 +9,15 @@
 
 #define IO_APIC_GATE_OFFSET 0x51
 
-void mask_irq(unsigned int irq_nr);
-void unmask_irq(unsigned int irq_nr);
-void enable_IO_APIC_irq (int irq);
-void disable_IO_APIC_irq (int irq);
-void set_8259A_irq_mask(int irq_nr);
-void setup_IO_APIC_irq (int irq);
+void mask_irq(unsigned int irq);
+void unmask_irq(unsigned int irq);
+void enable_IO_APIC_irq (unsigned int irq);
+void disable_IO_APIC_irq (unsigned int irq);
+void set_8259A_irq_mask(unsigned int irq);
 void ack_APIC_irq (void);
 void setup_IO_APIC (void);
 void init_IO_APIC_traps(void);
+int IO_APIC_get_PCI_irq_vector (int bus, int slot, int fn);
 
 #ifdef __SMP__
  extern unsigned int io_apic_irqs;
@@ -34,6 +34,8 @@
 	MP_BUS_PCI
 };
 extern int mp_bus_id_to_type [MAX_MP_BUSSES];
+extern char ioapic_OEM_ID [16];
+extern char ioapic_Product_ID [16];
 
 extern spinlock_t irq_controller_lock; /*
 					* Protects both the 8259 and the
@@ -44,7 +46,7 @@
 
 #include <asm/atomic.h>
 
-static inline void irq_enter(int cpu, int irq)
+static inline void irq_enter(int cpu, unsigned int irq)
 {
 	hardirq_enter(cpu);
 	while (test_bit(0,&global_irq_lock)) {
@@ -52,7 +54,7 @@
 	}
 }
 
-static inline void irq_exit(int cpu, int irq)
+static inline void irq_exit(int cpu, unsigned int irq)
 {
 	hardirq_exit(cpu);
 	release_irqlock(cpu);
diff -u --recursive --new-file v2.1.84/linux/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c
--- v2.1.84/linux/arch/i386/kernel/setup.c	Tue Jan 20 16:44:57 1998
+++ linux/arch/i386/kernel/setup.c	Mon Feb  2 13:31:51 1998
@@ -331,8 +331,9 @@
 
 static struct cpu_model_info cpu_models[] __initdata = {
 	{ X86_VENDOR_INTEL,	4,
-		{ "486 DX-25/33", "486 DX-50", "486 SX", "487 DX", "486 DX/2", "486 SL", "486 SX/2",
-		  NULL, "486 DX/2-WB", "486 DX/4", "486 DX/4-WB", NULL, NULL, NULL, NULL }},
+		{ "486 DX-25/33", "486 DX-50", "486 SX", "486 DX/2", "486 SL", "486 SX/2",
+		  NULL, "486 DX/2-WB", "486 DX/4", "486 DX/4-WB", NULL, NULL, NULL, NULL,
+		  NULL, NULL }},
 	{ X86_VENDOR_INTEL,	5,
 	  { "Pentium 60/66 A-step", "Pentium 60/66", "Pentium 75+",
 	    "OverDrive PODP5V83", "Pentium MMX", NULL, NULL,
diff -u --recursive --new-file v2.1.84/linux/arch/i386/kernel/smp.c linux/arch/i386/kernel/smp.c
--- v2.1.84/linux/arch/i386/kernel/smp.c	Fri Jan 23 18:10:31 1998
+++ linux/arch/i386/kernel/smp.c	Tue Feb  3 15:28:34 1998
@@ -258,10 +258,14 @@
 	}
 	memcpy(str,mpc->mpc_oem,8);
 	str[8]=0;
+	memcpy(ioapic_OEM_ID,str,9);
 	printk("OEM ID: %s ",str);
+	
 	memcpy(str,mpc->mpc_productid,12);
 	str[12]=0;
+	memcpy(ioapic_Product_ID,str,13);
 	printk("Product ID: %s ",str);
+
 	printk("APIC at: 0x%lX\n",mpc->mpc_lapic);
 
 	/* set the local APIC address */
@@ -367,14 +371,6 @@
 					--mp_irq_entries;
 				}
 
-printk(" Itype:%d Iflag:%d srcbus:%d srcbusI:%d dstapic:%d dstI:%d.\n",
-		m->mpc_irqtype,
-		m->mpc_irqflag,
-		m->mpc_srcbus,
-		m->mpc_srcbusirq,
-		m->mpc_dstapic,
-		m->mpc_dstirq);
-
 				mpt+=sizeof(*m);
 				count+=sizeof(*m);
 				break;
@@ -1372,10 +1368,13 @@
 				p->counter = 0;
 				need_resched = 1;
 			}
-			if (p->priority < DEF_PRIORITY)
+			if (p->priority < DEF_PRIORITY) {
 				kstat.cpu_nice += user;
-			else
+				kstat.per_cpu_nice[cpu] += user;
+			} else {
 				kstat.cpu_user += user;
+				kstat.per_cpu_user[cpu] += user;
+			}
 
 			kstat.cpu_system += system;
 			kstat.per_cpu_system[cpu] += system;
diff -u --recursive --new-file v2.1.84/linux/arch/ppc/config.in linux/arch/ppc/config.in
--- v2.1.84/linux/arch/ppc/config.in	Mon Jan 12 15:18:13 1998
+++ linux/arch/ppc/config.in	Mon Feb  2 15:18:15 1998
@@ -129,7 +129,7 @@
   endmenu
 fi
 
-source drivers/net/hamradio/Config.in
+source net/ax25/Config.in
 
 mainmenu_option next_comment
 comment 'ISDN subsystem'
diff -u --recursive --new-file v2.1.84/linux/drivers/block/Config.in linux/drivers/block/Config.in
--- v2.1.84/linux/drivers/block/Config.in	Fri Jan 30 11:28:06 1998
+++ linux/drivers/block/Config.in	Mon Feb  2 13:07:47 1998
@@ -65,6 +65,9 @@
   tristate '   RAID-1 (mirroring) mode' CONFIG_MD_MIRRORING
   tristate '   RAID-4/RAID-5 mode' CONFIG_MD_RAID5
 fi
+if [ "$CONFIG_MD_LINEAR" = "y" -o "$CONFIG_MD_STRIPED" = "y" ]; then
+  bool '      Boot support (linear, striped)' CONFIG_MD_BOOT
+fi
 tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
 if [ "$CONFIG_BLK_DEV_RAM" = "y" ]; then
   bool '   Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD
diff -u --recursive --new-file v2.1.84/linux/drivers/block/genhd.c linux/drivers/block/genhd.c
--- v2.1.84/linux/drivers/block/genhd.c	Fri Jan 23 18:10:31 1998
+++ linux/drivers/block/genhd.c	Mon Feb  2 13:07:47 1998
@@ -1094,6 +1094,9 @@
 #ifdef CONFIG_PARPORT
 	extern int parport_init(void);
 #endif
+#ifdef CONFIG_MD_BOOT
+        extern void md_setup_drive(void) __init;
+#endif
 	struct gendisk *p;
 	int nr=0;
 
@@ -1123,5 +1126,8 @@
 	else
 #endif
 	rd_load();
+#endif
+#ifdef CONFIG_MD_BOOT
+        md_setup_drive();
 #endif
 }
diff -u --recursive --new-file v2.1.84/linux/drivers/block/md.c linux/drivers/block/md.c
--- v2.1.84/linux/drivers/block/md.c	Fri Jan 23 18:10:31 1998
+++ linux/drivers/block/md.c	Tue Feb  3 15:19:45 1998
@@ -8,6 +8,7 @@
    A lot of inspiration came from hd.c ...
 
    kerneld support by Boris Tobotras <boris@xtalk.msk.su>
+   boot support for linear and striped mode by Harald Hoyer <HarryH@Royal.Net>
 
    RAID-1/RAID-5 extensions by:
         Ingo Molnar, Miguel de Icaza, Gadi Oxman
@@ -59,6 +60,10 @@
 #include <asm/bitops.h>
 #include <asm/atomic.h>
 
+#ifdef CONFIG_MD_BOOT
+extern dev_t name_to_dev_t(char *line) __init;
+#endif
+
 static struct hd_struct md_hd_struct[MAX_MD_DEV];
 static int md_blocksizes[MAX_MD_DEV];
 int md_maxreadahead[MAX_MD_DEV];
@@ -988,10 +993,13 @@
 		cli();
 		if (!test_bit(THREAD_WAKEUP, &thread->flags)) {
 			do {
-			         spin_lock_irq(&current->sigmask_lock);
+			         spin_lock(&current->sigmask_lock);
 				 flush_signals(current);
-				 spin_unlock_irq(&current->sigmask_lock);
+				 spin_unlock(&current->sigmask_lock);
 				 interruptible_sleep_on(&thread->wqueue);
+				 cli();
+				 if (test_bit(THREAD_WAKEUP, &thread->flags))
+				 	break;
 			} while (signal_pending(current));
 		}
 	}
@@ -1055,7 +1063,7 @@
 		 */
 		curr_bsize = blksize_size[major][minor];
 		if (curr_bsize != blocksize) {
-diff_blocksize:
+		diff_blocksize:
 			if (curr_bsize > blocksize)
 				/*
 				 * this is safe, rounds downwards.
@@ -1163,6 +1171,102 @@
 	
 }
 
+#ifdef CONFIG_MD_BOOT
+struct {
+	int set;
+	int ints[100];
+	char str[100];
+} md_setup_args __initdata = {
+	0,{0},{0}
+};
+
+/* called from init/main.c */
+__initfunc(void md_setup(char *str,int *ints))
+{
+	int i;
+	for(i=0;i<=ints[0];i++) {
+		md_setup_args.ints[i] = ints[i];
+		strcpy(md_setup_args.str, str);
+/*      printk ("md: ints[%d]=%d.\n", i, ints[i]);*/
+	}
+	md_setup_args.set=1;
+	return;
+}
+
+__initfunc(void do_md_setup(char *str,int *ints))
+{
+	int minor, pers, factor, fault;
+	dev_t dev;
+	int i=1;
+
+	if(ints[0] < 4) {
+		printk ("md: Too few Arguments (%d).\n", ints[0]);
+		return;
+	}
+   
+	minor=ints[i++];
+   
+	if (minor >= MAX_MD_DEV) {
+		printk ("md: Minor device number too high.\n");
+		return;
+	}
+
+	pers = 0;
+	
+	switch(ints[i++]) {  /* Raidlevel  */
+	case -1:
+#ifdef CONFIG_MD_LINEAR
+		pers = LINEAR;
+		printk ("md: Setting up md%d as linear device.\n",minor);
+#else 
+	        printk ("md: Linear mode not configured." 
+			"Recompile the kernel with linear mode enabled!\n");
+#endif
+		break;
+	case 0:
+		pers = STRIPED;
+#ifdef CONFIG_MD_STRIPED
+		printk ("md: Setting up md%d as a striped device.\n",minor);
+#else 
+	        printk ("md: Striped mode not configured." 
+			"Recompile the kernel with striped mode enabled!\n");
+#endif
+		break;
+/*      not supported yet
+	case 1:
+		pers = RAID1;
+		printk ("md: Setting up md%d as a raid1 device.\n",minor);
+		break;
+	case 5:
+		pers = RAID5;
+		printk ("md: Setting up md%d as a raid5 device.\n",minor);
+		break;
+*/
+	default:	   
+		printk ("md: Unknown or not supported raid level %d.\n", ints[--i]);
+		return;
+	}
+
+	if(pers) {
+
+	  factor=ints[i++]; /* Chunksize  */
+	  fault =ints[i++]; /* Faultlevel */
+   
+	  pers=pers | factor | (fault << FAULT_SHIFT);   
+   
+	  while( str && (dev = name_to_dev_t(str))) {
+	    do_md_add (minor, dev);
+	    if(str = strchr (str, ','))
+	      str++;
+	  }
+
+	  do_md_run (minor, pers);
+	  printk ("md: Loading md%d.\n",minor);
+	}
+   
+}
+#endif
+
 void linear_init (void);
 void raid0_init (void);
 void raid1_init (void);
@@ -1216,6 +1320,13 @@
 #ifdef CONFIG_MD_RAID5
   raid5_init ();
 #endif
-  
   return (0);
 }
+
+#ifdef CONFIG_MD_BOOT
+__initfunc(void md_setup_drive(void))
+{
+	if(md_setup_args.set)
+		do_md_setup(md_setup_args.str, md_setup_args.ints);
+}
+#endif
diff -u --recursive --new-file v2.1.84/linux/drivers/char/hfmodem/Config.in linux/drivers/char/hfmodem/Config.in
--- v2.1.84/linux/drivers/char/hfmodem/Config.in	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/hfmodem/Config.in	Mon Feb  2 15:18:15 1998
@@ -0,0 +1,6 @@
+comment 'Misc. hamradio protocols'
+tristate 'Shortwave radio modem driver' CONFIG_HFMODEM
+if [ "$CONFIG_HFMODEM" != "n" ]; then
+  bool '   HFmodem support for Soundblaster and compatible cards' CONFIG_HFMODEM_SBC
+  bool '   HFmodem support for WSS and Crystal cards' CONFIG_HFMODEM_WSS
+fi
diff -u --recursive --new-file v2.1.84/linux/drivers/net/8390.c linux/drivers/net/8390.c
--- v2.1.84/linux/drivers/net/8390.c	Wed Oct 22 08:27:31 1997
+++ linux/drivers/net/8390.c	Tue Feb  3 15:28:34 1998
@@ -54,6 +54,8 @@
 #include <asm/uaccess.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/delay.h>
 #include <linux/errno.h>
 #include <linux/fcntl.h>
 #include <linux/in.h>
@@ -185,10 +187,12 @@
 
     /* Mask interrupts from the ethercard. */
     outb_p(0x00, e8390_base + EN0_IMR);
+    disable_irq(dev->irq);
     synchronize_irq();
     if (dev->interrupt) {
 	printk("%s: Tx request while isr active.\n",dev->name);
 	outb_p(ENISR_ALL, e8390_base + EN0_IMR);
+	enable_irq(dev->irq);
 	ei_local->stat.tx_errors++;
 	dev_kfree_skb(skb, FREE_WRITE);
 	return 0;
@@ -226,6 +230,7 @@
 	ei_local->irqlock = 0;
 	dev->tbusy = 1;
 	outb_p(ENISR_ALL, e8390_base + EN0_IMR);
+	enable_irq(dev->irq);
 	ei_local->stat.tx_errors++;
 	return 1;
     }
@@ -272,6 +277,7 @@
     /* Turn 8390 interrupts back on. */
     ei_local->irqlock = 0;
     outb_p(ENISR_ALL, e8390_base + EN0_IMR);
+    enable_irq(dev->irq);
 
     dev_kfree_skb (skb, FREE_WRITE);
     ei_local->stat.tx_bytes += send_length;
@@ -608,7 +614,6 @@
 static void ei_rx_overrun(struct device *dev)
 {
     int e8390_base = dev->base_addr;
-    unsigned long wait_start_time;
     unsigned char was_txing, must_resend = 0;
     struct ei_device *ei_local = (struct ei_device *) dev->priv;
     
@@ -629,9 +634,7 @@
      * it "is not a reliable indicator and subsequently should be ignored."
      * We wait at least 10ms.
      */
-    wait_start_time = jiffies;
-    while (jiffies - wait_start_time <= 1*HZ/100)
-	barrier();
+    udelay(10*1000);
 
     /*
      * Reset RBCR[01] back to zero as per magic incantation.
diff -u --recursive --new-file v2.1.84/linux/drivers/net/de4x5.c linux/drivers/net/de4x5.c
--- v2.1.84/linux/drivers/net/de4x5.c	Fri Jan 30 11:28:07 1998
+++ linux/drivers/net/de4x5.c	Mon Feb  2 13:42:07 1998
@@ -2216,7 +2216,7 @@
 __initfunc(static void
 srom_search(int index))
 {
-    u_char pb, dev_fn;
+    u_char pb, dev_fn, tirq;
     u_short dev_id, dev_num, vendor, status;
     u_int tmp, irq = 0, device, class = DE4X5_CLASS_CODE;
     u_long iobase = 0;                     /* Clear upper 32 bits in Alphas */
@@ -2266,8 +2266,8 @@
 
 	/* Fetch the IRQ to be used */
 #ifndef __sparc_v9__
-	pcibios_read_config_byte(pb, PCI_DEVICE, PCI_INTERRUPT_LINE, 
-				                                 (char *)&irq);
+	pcibios_read_config_byte(pb, PCI_DEVICE, PCI_INTERRUPT_LINE, &tirq);
+	irq = tirq;
 #else
 	irq = pdev->irq;
 #endif
diff -u --recursive --new-file v2.1.84/linux/drivers/net/hamradio/Config.in linux/drivers/net/hamradio/Config.in
--- v2.1.84/linux/drivers/net/hamradio/Config.in	Sun Jan  4 10:40:16 1998
+++ linux/drivers/net/hamradio/Config.in	Mon Feb  2 15:18:15 1998
@@ -1,61 +1,27 @@
-#
-# Amateur Radio protocols and AX.25 device configuration
-#
-# 19971130	Now in an own category to make correct compilation of the 
-#		AX.25 stuff easier...
-#		Joerg Reuter DL1BKE <jreuter@poboxes.com>
+comment 'AX.25 network device drivers'
 
-mainmenu_option next_comment
-comment 'Amateur Radio support'
-bool 'Amateur Radio support' CONFIG_HAMRADIO
-
-if [ "$CONFIG_HAMRADIO" != "n" ] ; then
-  if [ "$CONFIG_NET" != "n" ] ; then
-    comment 'Packet Radio protocols'
-    tristate 'Amateur Radio AX.25 Level 2 protocol' CONFIG_AX25
-    if [ "$CONFIG_AX25" != "n" ]; then
-      bool '   AX.25 DAMA Slave support' CONFIG_AX25_DAMA_SLAVE
-#     bool '   AX.25 DAMA Master support' CONFIG_AX25_DAMA_MASTER
-      dep_tristate '   Amateur Radio NET/ROM protocol' CONFIG_NETROM $CONFIG_AX25
-      dep_tristate '   Amateur Radio X.25 PLP (Rose)' CONFIG_ROSE $CONFIG_AX25
-    fi
-    
-    if [ "$CONFIG_AX25" != "n" ]; then
-      comment 'AX.25 network device drivers'
-      tristate 'Serial port KISS driver' CONFIG_MKISS
-#     tristate 'Serial port 6PACK driver' CONFIG_6PACK
-      tristate 'BPQ Ethernet driver' CONFIG_BPQETHER
-    
-      dep_tristate 'High-speed (DMA) SCC driver for AX.25' CONFIG_DMASCC $CONFIG_AX25
-      tristate 'Z8530 SCC driver' CONFIG_SCC
-      if [ "$CONFIG_SCC" != "n" ]; then
-        bool '   additional delay for PA0HZP OptoSCC compatible boards' CONFIG_SCC_DELAY
-        bool '   support for TRX that feedback the tx signal to rx' CONFIG_SCC_TRXECHO
-      fi
+dep_tristate 'Serial port KISS driver' CONFIG_MKISS $CONFIG_AX25
+# dep_tristate 'Serial port 6PACK driver' CONFIG_6PACK $CONFIG_AX25
+dep_tristate 'BPQ Ethernet driver' CONFIG_BPQETHER $CONFIG_AX25
     
-      tristate 'BAYCOM ser12 fullduplex driver for AX.25' CONFIG_BAYCOM_SER_FDX
-      tristate 'BAYCOM ser12 halfduplex driver for AX.25' CONFIG_BAYCOM_SER_HDX
-      tristate 'BAYCOM picpar and par96 driver for AX.25' CONFIG_BAYCOM_PAR
-    
-      tristate 'Soundcard modem driver' CONFIG_SOUNDMODEM
-      if [ "$CONFIG_SOUNDMODEM" != "n" ]; then
-        bool '   soundmodem support for Soundblaster and compatible cards' CONFIG_SOUNDMODEM_SBC
-        bool '   soundmodem support for WSS and Crystal cards' CONFIG_SOUNDMODEM_WSS
-        bool '   soundmodem support for 1200 baud AFSK modulation' CONFIG_SOUNDMODEM_AFSK1200
-        bool '   soundmodem support for 2400 baud AFSK modulation (7.3728MHz crystal)' CONFIG_SOUNDMODEM_AFSK2400_7
-        bool '   soundmodem support for 2400 baud AFSK modulation (8MHz crystal)' CONFIG_SOUNDMODEM_AFSK2400_8
-        bool '   soundmodem support for 4800 baud HAPN-1 modulation' CONFIG_SOUNDMODEM_HAPN4800
-        bool '   soundmodem support for 9600 baud FSK G3RUH modulation' CONFIG_SOUNDMODEM_FSK9600
-      fi
-    fi
-  fi
-   
-  comment 'Misc. hamradio protocols'
-  tristate 'Shortwave radio modem driver' CONFIG_HFMODEM
-  if [ "$CONFIG_HFMODEM" != "n" ]; then
-    bool '   HFmodem support for Soundblaster and compatible cards' CONFIG_HFMODEM_SBC
-    bool '   HFmodem support for WSS and Crystal cards' CONFIG_HFMODEM_WSS
-  fi
+dep_tristate 'High-speed (DMA) SCC driver for AX.25' CONFIG_DMASCC $CONFIG_AX25
+dep_tristate 'Z8530 SCC driver' CONFIG_SCC $CONFIG_AX25
+if [ "$CONFIG_SCC" != "n" ]; then
+  bool '   additional delay for PA0HZP OptoSCC compatible boards' CONFIG_SCC_DELAY
+  bool '   support for TRX that feedback the tx signal to rx' CONFIG_SCC_TRXECHO
 fi
+    
+dep_tristate 'BAYCOM ser12 fullduplex driver for AX.25' CONFIG_BAYCOM_SER_FDX $CONFIG_AX25
+dep_tristate 'BAYCOM ser12 halfduplex driver for AX.25' CONFIG_BAYCOM_SER_HDX $CONFIG_AX25
+dep_tristate 'BAYCOM picpar and par96 driver for AX.25' CONFIG_BAYCOM_PAR $CONFIG_AX25
 
-endmenu
+dep_tristate 'Soundcard modem driver' CONFIG_SOUNDMODEM $CONFIG_AX25
+if [ "$CONFIG_SOUNDMODEM" != "n" ]; then
+  bool '   soundmodem support for Soundblaster and compatible cards' CONFIG_SOUNDMODEM_SBC
+  bool '   soundmodem support for WSS and Crystal cards' CONFIG_SOUNDMODEM_WSS
+  bool '   soundmodem support for 1200 baud AFSK modulation' CONFIG_SOUNDMODEM_AFSK1200
+  bool '   soundmodem support for 2400 baud AFSK modulation (7.3728MHz crystal)' CONFIG_SOUNDMODEM_AFSK2400_7
+  bool '   soundmodem support for 2400 baud AFSK modulation (8MHz crystal)' CONFIG_SOUNDMODEM_AFSK2400_8
+  bool '   soundmodem support for 4800 baud HAPN-1 modulation' CONFIG_SOUNDMODEM_HAPN4800
+  bool '   soundmodem support for 9600 baud FSK G3RUH modulation' CONFIG_SOUNDMODEM_FSK9600
+fi
diff -u --recursive --new-file v2.1.84/linux/drivers/net/hamradio/bpqether.c linux/drivers/net/hamradio/bpqether.c
--- v2.1.84/linux/drivers/net/hamradio/bpqether.c	Sat Nov 29 10:33:19 1997
+++ linux/drivers/net/hamradio/bpqether.c	Mon Feb  2 15:18:16 1998
@@ -51,6 +51,7 @@
  *						call.
  *						Fixed to match Linux networking
  *						changes - 2.1.15.
+ *	BPQ   004	Joerg(DL1BKE)		Fixed to not lock up on ifconfig.
  */
 
 #include <linux/config.h>
@@ -78,6 +79,7 @@
 #include <linux/firewall.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/rtnetlink.h>
 
 #include <net/ip.h>
 #include <net/arp.h>
@@ -186,7 +188,11 @@
 			if (&bpq->axdev == dev)
 				result = 1;
 
-			unregister_netdev(&bpq->axdev);
+			/* We should be locked, call 
+			 * unregister_netdevice directly 
+			 */
+
+			unregister_netdevice(&bpq->axdev);
 			kfree(bpq);
 		}
 
@@ -531,7 +537,9 @@
 	dev->name = buf;
 	dev->init = bpq_dev_init;
 
-	if (register_netdev(dev) != 0) {
+	/* We should be locked, call register_netdevice() directly. */
+
+	if (register_netdevice(dev) != 0) {
 		kfree(bpq);
                 return -EIO;
         }
diff -u --recursive --new-file v2.1.84/linux/drivers/net/hamradio/scc.c linux/drivers/net/hamradio/scc.c
--- v2.1.84/linux/drivers/net/hamradio/scc.c	Fri Dec 19 10:56:30 1997
+++ linux/drivers/net/hamradio/scc.c	Mon Feb  2 15:18:16 1998
@@ -1,4 +1,4 @@
-#define RCS_ID "$Id: scc.c,v 1.71 1997/11/29 19:59:20 jreuter Exp jreuter $"
+#define RCS_ID "$Id: scc.c,v 1.73 1998/01/29 17:38:51 jreuter Exp jreuter $"
 
 #define VERSION "3.0"
 #define BANNER  "Z8530 SCC driver version "VERSION".dl1bke (experimental) by DL1BKE\n"
@@ -6,6 +6,9 @@
 /*
  * Please use z8530drv-utils-3.0 with this version.
  *            ------------------
+ *
+ * You can find a subset of the documentation in 
+ * linux/Documentation/networking/z8530drv.txt.
  */
 
 /*
@@ -16,7 +19,7 @@
 
    ********************************************************************
 
-	Copyright (c) 1993, 1997 Joerg Reuter DL1BKE
+	Copyright (c) 1993, 1998 Joerg Reuter DL1BKE
 
 	portions (c) 1993 Guido ten Dolle PE1NNZ
 
@@ -89,7 +92,8 @@
    970108	- Fixed the remaining problems.
    970402	- Hopefully fixed the problems with the new *_timer()
    		  routines, added calibration code.
-   971012	- made SCC_DELAY a CONFIG option, added CONFIG_SCC_TRXECHO
+   971012	- Made SCC_DELAY a CONFIG option, added CONFIG_SCC_TRXECHO
+   980129	- Small fix to avoid lock-up on initialization
 
    Thanks to all who contributed to this driver with ideas and bug
    reports!
@@ -195,7 +199,7 @@
 static void scc_isr(int irq, void *dev_id, struct pt_regs *regs);
 static void scc_init_timer(struct scc_channel *scc);
 
-static int scc_net_setup(struct scc_channel *scc, unsigned char *name);
+static int scc_net_setup(struct scc_channel *scc, unsigned char *name, int addev);
 static int scc_net_init(struct device *dev);
 static int scc_net_open(struct device *dev);
 static int scc_net_close(struct device *dev);
@@ -1529,7 +1533,7 @@
  * Allocate device structure, err, instance, and register driver
  */
 
-static int scc_net_setup(struct scc_channel *scc, unsigned char *name)
+static int scc_net_setup(struct scc_channel *scc, unsigned char *name, int addev)
 {
 	unsigned char *buf;
 	struct device *dev;
@@ -1553,11 +1557,11 @@
 	dev->name = buf;
 	dev->init = scc_net_init;
 
-	if (register_netdev(dev) != 0)
+	if ((addev? register_netdevice(dev) : register_netdev(dev)) != 0)
 	{
 		kfree(dev);
-		return -EIO;
-	}
+                return -EIO;
+        }
 
 	return 0;
 }
@@ -1868,7 +1872,7 @@
 					request_region(SCC_Info[2*Nchips+chan].ctrl, 1, "scc ctrl");
 					request_region(SCC_Info[2*Nchips+chan].data, 1, "scc data");
 					if (Nchips+chan != 0)
-						scc_net_setup(&SCC_Info[2*Nchips+chan], device_name);
+						scc_net_setup(&SCC_Info[2*Nchips+chan], device_name, 1);
 				}
 			}
 			
@@ -2178,7 +2182,7 @@
 
 	sprintf(devname,"%s0", SCC_DriverName);
 	
-	result = scc_net_setup(SCC_Info, devname);
+	result = scc_net_setup(SCC_Info, devname, 0);
 	if (result)
 	{
 		printk(KERN_ERR "z8530drv: cannot initialize module\n");
@@ -2203,7 +2207,7 @@
 	result = scc_init();
 
 	if (result == 0)
-		printk(KERN_INFO "Copyright 1993,1997 Joerg Reuter DL1BKE (jreuter@poboxes.com)\n");
+		printk(KERN_INFO "Copyright 1993,1998 Joerg Reuter DL1BKE (jreuter@poboxes.com)\n");
 		
 	return result;
 }
diff -u --recursive --new-file v2.1.84/linux/drivers/scsi/Config.in linux/drivers/scsi/Config.in
--- v2.1.84/linux/drivers/scsi/Config.in	Sun Dec 21 17:04:48 1997
+++ linux/drivers/scsi/Config.in	Mon Feb  2 14:51:31 1998
@@ -84,10 +84,11 @@
   fi
 fi
 if [ "$CONFIG_MCA" = "y" ]; then
-   dep_tristate 'IBMMCA SCSI support' CONFIG_SCSI_IBMMCA $CONFIG_SCSI
-   if [ "$CONFIG_SCSI_IBMMCA" != "n" ]; then
-      bool '  reset SCSI-devices while booting' CONFIG_SCSI_IBMMCA_DEV_RESET
-   fi
+  bool 'IBMMCA SCSI support' CONFIG_SCSI_IBMMCA
+  if [ "$CONFIG_SCSI_IBMMCA" = "y" ]; then
+     bool '  Standard SCSI-order' CONFIG_IBMMCA_SCSI_ORDER_STANDARD
+     bool '  Reset SCSI-devices at boottime' CONFIG_IBMMCA_SCSI_DEV_RESET
+  fi
 fi
 if [ "$CONFIG_PARPORT" != "n" ]; then
   dep_tristate 'IOMEGA Parallel Port ZIP drive SCSI support' CONFIG_SCSI_PPA $CONFIG_SCSI $CONFIG_PARPORT
diff -u --recursive --new-file v2.1.84/linux/drivers/scsi/ibmmca.c linux/drivers/scsi/ibmmca.c
--- v2.1.84/linux/drivers/scsi/ibmmca.c	Sun Nov 30 11:34:27 1997
+++ linux/drivers/scsi/ibmmca.c	Mon Feb  2 14:51:31 1998
@@ -199,10 +199,11 @@
    5) Magneto-Optical drives and medium-changers are also recognized, now.
       Therefore, we have a completely gapfree recognition of all SCSI-
       device-types, that are known by Linux up to kernel 2.1.31.
-   6) The flag CONFIG_SCSI_IBMMCA_DEV_RESET has been inserted. If it is set
-      within the configuration, each connected SCSI-device will get a reset
-      command during boottime. This can be necessary for some special
-      SCSI-devices.  (See also the new Config.in file.)
+   6) The flag SCSI_IBMMCA_DEV_RESET has been inserted. If it is set within
+      the configuration, each connected SCSI-device will get a reset command
+      during boottime. This can be necessary for some special SCSI-devices.
+      This flag should be included in Config.in.
+      (See also the new Config.in file.)
    Probable next improvement: bad disk handler.
    - Michael Lang
  
@@ -210,8 +211,64 @@
    1) Some debugging and speed optimization applied.
    - Michael Lang
 
+   Dec 15, 1997
+    - chrisb@truespectra.com
+    - made the front panel display thingy optional, specified from the
+    command-line via ibmmcascsi=display.  Along the lines of the /LED
+    option for the OS/2 driver.
+    - fixed small bug in the LED display that would hang some machines.
+    - reversed ordering of the drives (using the
+    IBMMCA_SCSI_ORDER_STANDARD define).  This is necessary for two main
+    reasons:
+	- users who've already installed Linux won't be screwed.  Keep
+	in mind that not everyone is a kernel hacker.
+	- be consistent with the BIOS ordering of the drives.  In the
+	BIOS, id 6 is C:, id 0 might be D:.  With this scheme, they'd be
+	backwards.  This confuses the crap out of those heathens who've
+	got a impure Linux installation (which, <wince>, I'm one of).
+    This whole problem arises because IBM is actually non-standard with
+    the id to BIOS mappings.  You'll find, in fdomain.c, a similar
+    comment about a few FD BIOS revisions.  The Linux (and apparently
+    industry) standard is that C: maps to scsi id (0,0).  Let's stick
+    with that standard.
+    - Since this is technically a branch of my own, I changed the
+    version number to 3.0e-cpb.
+
+   Jan 17, 1998: (v3.0f)
+   1) Addition of some statistical info for /proc in proc_info.
+   2) Taking care of the SCSI-assignment problem, dealed by Chris at Dec 15
+      1997. In fact, IBM is right, concerning the assignment of SCSI-devices 
+      to driveletters. It is conform to the ANSI-definition of the SCSI-
+      standard to assign drive C: to SCSI-id 6, because it is the highest
+      hardware priority after the hostadapter (that has still today by
+      default everywhere id 7). Also realtime-operating systems that I use, 
+      like LynxOS and OS9, which are quite industrial systems use top-down
+      numbering of the harddisks, that is also starting at id 6. Now, one
+      sits a bit between two chairs. On one hand side, using the define
+      IBMMCA_SCSI_ORDER_STANDARD makes Linux assigning disks conform to
+      the IBM- and ANSI-SCSI-standard and keeps this driver downward
+      compatible to older releases, on the other hand side, people is quite
+      habituated in believing that C: is assigned to (0,0) and much other
+      SCSI-BIOS do so. Therefore, I moved the IBMMCA_SCSI_ORDER_STANDARD 
+      define out of the driver and put it into Config.in as subitem of 
+      'IBM SCSI support'. A help, added to Documentation/Configure.help 
+      explains the differences between saying 'y' or 'n' to the user, when 
+      IBMMCA_SCSI_ORDER_STANDARD prompts, so the ordinary user is enabled to 
+      choose the way of assignment, depending on his own situation and gusto.
+   3) Adapted SCSI_IBMMCA_DEV_RESET to the local naming convention, so it is
+      now called IBMMCA_SCSI_DEV_RESET.
+   4) Optimization of proc_info and its subroutines.
+   5) Added more in-source-comments and extended the driver description by
+      some explanation about the SCSI-device-assignment problem.
+   - Michael Lang
+   
+   Jan 18, 1998: (v3.0g)
+   1) Correcting names to be absolutely conform to the later 2.1.x releases.
+      This is necessary for 
+            IBMMCA_SCSI_DEV_RESET -> CONFIG_IBMMCA_SCSI_DEV_RESET
+            IBMMCA_SCSI_ORDER_STANDARD -> CONFIG_IBMMCA_SCSI_ORDER_STANDARD
+   - Michael Lang
 
- 
 	TODO:
  
 	- It seems that the handling of bad disks is really bad -
@@ -252,7 +309,12 @@
 /*--------------------------------------------------------------------*/
 
 /* current version of this driver-source: */
-#define IBMMCA_SCSI_DRIVER_VERSION "3.0d"
+#define IBMMCA_SCSI_DRIVER_VERSION "3.0f"
+
+/* use standard Linux ordering, where C: maps to (0,0), unlike the IBM
+standard which seems to like C: => (6,0) */
+/* #define IBMMCA_SCSI_ORDER_STANDARD is defined/undefined in Config.in
+ * now, while configuring the kernel. */
 
 /*
    Driver Description
@@ -341,8 +403,23 @@
    If your boot-partition is not coming up, also edit the /etc/lilo.conf-file
    in a Linux session booted on old kernel and run lilo before reboot. Check
    lilo.conf anyway to get boot on other partitions with foreign OSes right
-   again.
-
+   again. 
+ 
+   The problem is, that Linux does not assign the SCSI-devices in the
+   way as described in the ANSI-SCSI-standard. Linux assigns /dev/sda to 
+   the device with at minimum id 0. But the first drive should be at id 6,
+   because for historical reasons, drive at id 6 has, by hardware, the highest
+   priority and a drive at id 0 the lowest. IBM was one of the rare producers,
+   where the BIOS assigns drives belonging to the ANSI-SCSI-standard. Most 
+   other producers' BIOS does not (I think even Adaptec-BIOS). The 
+   IBMMCA_SCSI_ORDER_STANDARD flag helps to be able to choose the preferred 
+   way of SCSI-device-assignment. Defining this flag would result in Linux 
+   determining the devices in the same order as DOS and OS/2 does on your 
+   MCA-machine. This is also standard on most industrial computers. Leaving 
+   this flag undefined will get your devices ordered in the default way of 
+   Linux. See also the remarks of Chris Beauregard from Dec 15, 1997 and
+   the followups.
+   
    (C) Regular Processing 
    Only three functions get involved: ibmmca_queuecommand(), issue_cmd(),
    and interrupt_handler().
@@ -443,7 +520,7 @@
 
 /* basic I/O-port of first adapter */
 #define IM_IO_PORT   0x3540
-/* maximum number of hosts that can be find */
+/* maximum number of hosts that can be found */
 #define IM_N_IO_PORT 8
 
 /*requests going into the upper nibble of the Attention register */
@@ -589,16 +666,19 @@
    interest, debugging or just for having fun. The left number gives the
    host-adapter number and the right shows the accessed SCSI-ID. */
 
+/* use_display is set by the ibmmcascsi=display command line arg */
+static int use_display = 0;
 #define PS2_DISK_LED_ON(ad,id) {\
-	if( machine_id == 0xf8 ) { outb((char)(id+48), MOD95_LED_PORT ); \
+	if( use_display ) { outb((char)(id+48), MOD95_LED_PORT ); \
         outb((char)(ad+48), MOD95_LED_PORT+1); } \
 	else outb(inb(PS2_SYS_CTR) | 0xc0, PS2_SYS_CTR); \
 }
 
+/* bug fixed, Dec 15, 1997, where | was replaced by & here */
 #define PS2_DISK_LED_OFF() {\
-	if( machine_id == 0xf8 ) { outb( ' ', MOD95_LED_PORT ); \
+	if( use_display ) { outb( ' ', MOD95_LED_PORT ); \
         outb(' ', MOD95_LED_PORT+1); } \
-	else outb(inb(PS2_SYS_CTR) | 0x3f, PS2_SYS_CTR); \
+	else outb(inb(PS2_SYS_CTR) & 0x3f, PS2_SYS_CTR); \
 }
 
 /*--------------------------------------------------------------------*/
@@ -609,6 +689,8 @@
     unsigned short mca_id;
     char *description;
   };
+
+/* List of possible IBM-SCSI-adapters */
 struct subsys_list_struct subsys_list[] =
 {
   {0x8efc, "IBM Fast SCSI-2 Adapter"},
@@ -632,14 +714,14 @@
 /*local data for a logical device */
 struct logical_device
   {
-    struct im_scb scb;
+    struct im_scb scb; /* SCSI-subsystem-control-block structure */
     struct im_tsb tsb;
     struct im_sge sge[16];
     Scsi_Cmnd *cmd;  /* SCSI-command that is currently in progress */
      
     int device_type; /* type of the SCSI-device. See include/scsi/scsi.h
-		        for interpreation of the possible values */
-    int block_length;
+		        for interpretation of the possible values */
+    int block_length;/* blocksize of a particular logical SCSI-device */
   };
 
 /* statistics of the driver during operations (for proc_info) */
@@ -649,6 +731,8 @@
       int ldn_access[MAX_LOG_DEV+1];         /* total accesses on a ldn */
       int ldn_read_access[MAX_LOG_DEV+1];    /* total read-access on a ldn */
       int ldn_write_access[MAX_LOG_DEV+1];   /* total write-access on a ldn */
+      int ldn_inquiry_access[MAX_LOG_DEV+1]; /* total inquiries on a ldn */
+      int ldn_modeselect_access[MAX_LOG_DEV+1]; /* total mode selects on ldn */
       int total_accesses;                    /* total accesses on all ldns */
       int total_interrupts;                  /* total interrupts (should be
 						same as total_accesses) */
@@ -663,26 +747,28 @@
 /* data structure for each host adapter */
 struct ibmmca_hostdata
 {
-  /* array of logical devices */
-    struct logical_device _ld[MAX_LOG_DEV];
-  /* array to convert (pun, lun) into logical device number */
+  /* array of logical devices: */
+    struct logical_device _ld[MAX_LOG_DEV];   
+  /* array to convert (pun, lun) into logical device number: */
     unsigned char _get_ldn[8][8];
   /*array that contains the information about the physical SCSI-devices
-       attached to this host adapter */
+   attached to this host adapter: */
     unsigned char _get_scsi[8][8];
-  /* used only when checking logical devices */
+  /* used only when checking logical devices: */
     int _local_checking_phase_flag;
+  /* report received interrupt: */
     int _got_interrupt;
+  /* report termination-status of SCSI-command: */
     int _stat_result;
-  /* reset status (used only when doing reset) */
+  /* reset status (used only when doing reset): */
     int _reset_status;
-  /* code of the last SCSI command (needed for panic info) */
+  /* code of the last SCSI command (needed for panic info): */
     int _last_scsi_command;
-  /* counter that points on next reassignable ldn for dynamical remapping */
-  /* The default value is 7, that is the first reassignable number in
-     the list on startup. */
+  /* Counter that points on the next reassignable ldn for dynamical 
+   remapping. The default value is 7, that is the first reassignable 
+   number in the list at boottime: */
     int _next_ldn;
-  /* Statistics for this IBM-SCSI-host */
+  /* Statistics-structure for this IBM-SCSI-host: */
     struct Driver_Statistics _IBM_DS;
 };
 
@@ -701,21 +787,21 @@
 #define IBM_DS (HOSTDATA(shpnt)->_IBM_DS)
 
 /* Define a arbitrary number as subsystem-marker-type. This number is, as 
-   described in the SCSI-Standard, not occupied by other device-types. */
+   described in the ANSI-SCSI-standard, not occupied by other device-types. */
 #define TYPE_IBM_SCSI_ADAPTER   0x2F
 
 /* Define 0xFF for no device type, because this type is not defined within
-   the SCSI-standard, therefore, it can be used and should not cause any
+   the ANSI-SCSI-standard, therefore, it can be used and should not cause any
    harm. */
 #define TYPE_NO_DEVICE          0xFF
 
-/* define medium-changer. If this is not defined previously, define 
-   this type here. */
+/* define medium-changer. If this is not defined previously, e.g. Linux
+   2.0.x, define this type here. */
 #ifndef TYPE_MEDIUM_CHANGER
 #define TYPE_MEDIUM_CHANGER     0x08
 #endif
 
-/* define operations for immediate_assign */
+/* define possible operations for the immediate_assign command */
 #define SET_LDN        0
 #define REMOVE_LDN     1
 
@@ -732,7 +818,7 @@
 static int scsi_id[IM_MAX_HOSTS] = { 7, 7, 7, 7, 7, 7, 7, 7 };
 
 /* fill module-parameters only, when this define is present.
-   (that is kernel >=2.1.0) */
+   (that is kernel version 2.1.x) */
 #ifdef MODULE_PARM
 MODULE_PARM(io_port, "1-" __MODULE_STRING(IM_MAX_HOSTS) "i");
 MODULE_PARM(scsi_id, "1-" __MODULE_STRING(IM_MAX_HOSTS) "i"); 
@@ -1036,24 +1122,19 @@
    return("-");
 }
 
-/* type-interpreter for logical devices 
-   (A bit stupid, but it was necessary to get the '-' and the Hex-codes
-   into one type.) */
+/* interpreter for logical device numbers (ldn) */
 static char *ti_l(int value)
 {
-   switch (value)
-     {
-	case 0:  return("0"); break; case 1:  return("1"); break;
-	case 2:  return("2"); break; case 3:  return("3"); break;
-	case 4:  return("4"); break; case 5:  return("5"); break;
-	case 6:  return("6"); break; case 7:  return("7"); break;
-	case 8:  return("8"); break; case 9:  return("9"); break;
-	case 10: return("a"); break; case 11: return("b"); break;
-        case 12: return("c"); break; case 13: return("d"); break;
-	case 14: return("e"); break; case 15: return("f"); break;
-	default: return("-"); break;
-     }
-   return("-");
+   const char hex[16] = ("0123456789abcdef");
+   static char answer[2];
+
+   answer[1] = (char)(0x0);
+   if (value<=MAX_LOG_DEV)
+     answer[0] = hex[value];
+   else
+     answer[0] = '-';
+   
+   return (char *)&answer;
 }
 
 /* 
@@ -1093,7 +1174,7 @@
   memset (get_ldn, TYPE_NO_DEVICE, sizeof get_ldn); /* this is essential ! */
   memset (get_scsi, TYPE_NO_DEVICE, sizeof get_scsi); /* this is essential ! */
 
-  for (lun=0; lun<=7; lun++) /* mark the adapter at its pun on all luns*/
+  for (lun=0; lun<8; lun++) /* mark the adapter at its pun on all luns*/
     {
       get_scsi[subsystem_pun][lun] = TYPE_IBM_SCSI_ADAPTER; 
       get_ldn[subsystem_pun][lun] = MAX_LOG_DEV; /* make sure, the subsystem
@@ -1111,13 +1192,13 @@
       immediate_assign(shpnt,0,0,ldn,REMOVE_LDN); /* remove ldn (wherever)*/
     }
 
-  lun = 0;
+  lun = 0; /* default lun is 0 */
 
   /* STEP 2: */
   printk("\nIBM MCA SCSI: Probing SCSI-devices.");
-  for (id=0; id<=7; id++)
+  for (id=0; id<8; id++)
 #ifdef CONFIG_SCSI_MULTI_LUN
-    for (lun=0; lun<=7; lun++)
+    for (lun=0; lun<8; lun++)
 #endif
       {
 #ifdef IM_DEBUG_PROBE
@@ -1137,16 +1218,16 @@
 	  }
       }
   
-  /* STEP 3: */
+  /* STEP 3: */   
   printk("\nIBM MCA SCSI: Mapping SCSI-devices.");
    
   ldn = 0;
   lun = 0;
 
 #ifdef CONFIG_SCSI_MULTI_LUN   
-  for (lun=0; lun<=7 && ldn<MAX_LOG_DEV; lun++)
+  for (lun=0; lun<8 && ldn<MAX_LOG_DEV; lun++)
 #endif
-    for (id=0; id<=7 && ldn<MAX_LOG_DEV; id++)
+    for (id=0; id<8 && ldn<MAX_LOG_DEV; id++)
       {
 #ifdef IM_DEBUG_PROBE
 	printk(".");
@@ -1163,7 +1244,7 @@
 		if (device_exists (shpnt, ldn, &ld[ldn].block_length,
 				   &ld[ldn].device_type))
 		  {
-#ifdef CONFIG_SCSI_IBMMCA_DEV_RESET
+#ifdef CONFIG_IBMMCA_SCSI_DEV_RESET
 		    int ticks;
 		    printk("(resetting)");
 		    ticks = IM_RESET_DELAY*HZ;
@@ -1211,8 +1292,8 @@
    /* STEP 4: */
    
    /* map remaining ldns to non-existing devices */
-   for (lun=1; lun<=7 && ldn<MAX_LOG_DEV; lun++)
-     for (id=0; id<=7 && ldn<MAX_LOG_DEV; id++)
+   for (lun=1; lun<8 && ldn<MAX_LOG_DEV; lun++)
+     for (id=0; id<8 && ldn<MAX_LOG_DEV; id++)
      {
 	if (get_scsi[id][lun] == TYPE_NO_LUN ||
 	    get_scsi[id][lun] == TYPE_NO_DEVICE)
@@ -1228,24 +1309,29 @@
      }	
 	
    printk("\n");
-
+#ifdef CONFIG_IBMMCA_SCSI_ORDER_STANDARD
+   printk("IBM MCA SCSI: SCSI-access-order: IBM/ANSI.\n");
+#else
+   printk("IBM MCA SCSI: SCSI-access-order: Linux.\n");
+#endif
+   
 #ifdef IM_DEBUG_PROBE
    /* Show the physical and logical mapping during boot. */
    printk("IBM MCA SCSI: Determined SCSI-device-mapping:\n");
    printk("    Physical SCSI-Device Map               Logical SCSI-Device Map\n");
    printk("ID\\LUN  0  1  2  3  4  5  6  7       ID\\LUN  0  1  2  3  4  5  6  7\n");
-   for (id=0; id<=7; id++)
+   for (id=0; id<8; id++)
      {
-       printk("%2d     %2s %2s %2s %2s %2s %2s %2s %2s",
-	      id, ti_p(get_scsi[id][0]), ti_p(get_scsi[id][1]), 
-	      ti_p(get_scsi[id][2]), ti_p(get_scsi[id][3]), 
-	      ti_p(get_scsi[id][4]), ti_p(get_scsi[id][5]), 
-	      ti_p(get_scsi[id][6]), ti_p(get_scsi[id][7]));
-       printk("       %2d     %2s %2s %2s %2s %2s %2s %2s %2s\n",
-	      id, ti_l(get_ldn[id][0]), ti_l(get_ldn[id][1]), 
-	      ti_l(get_ldn[id][2]), ti_l(get_ldn[id][3]), 
-	      ti_l(get_ldn[id][4]), ti_l(get_ldn[id][5]),
-	      ti_l(get_ldn[id][6]), ti_l(get_ldn[id][7]));
+        printk("%2d     %2s %2s %2s %2s %2s %2s %2s %2s",
+	       id, ti_p(get_scsi[id][0]), ti_p(get_scsi[id][1]), 
+	       ti_p(get_scsi[id][2]), ti_p(get_scsi[id][3]), 
+	       ti_p(get_scsi[id][4]), ti_p(get_scsi[id][5]), 
+	       ti_p(get_scsi[id][6]), ti_p(get_scsi[id][7]));
+
+	printk("       %2d     ",id);
+	for (lun=0; lun<8; lun++)
+	  printk("%2s ",ti_l(get_ldn[id][lun]));
+	printk("\n");
      }
 #endif
 
@@ -1270,6 +1356,8 @@
   memset (IBM_DS.ldn_access, 0x0, sizeof (IBM_DS.ldn_access));
   memset (IBM_DS.ldn_read_access, 0x0, sizeof (IBM_DS.ldn_read_access));
   memset (IBM_DS.ldn_write_access, 0x0, sizeof (IBM_DS.ldn_write_access));
+  memset (IBM_DS.ldn_inquiry_access, 0x0, sizeof (IBM_DS.ldn_inquiry_access));
+  memset (IBM_DS.ldn_modeselect_access, 0x0, sizeof (IBM_DS.ldn_modeselect_access));
   memset (IBM_DS.ldn_assignments, 0x0, sizeof (IBM_DS.ldn_assignments));
    
   return;
@@ -1412,10 +1500,14 @@
 void 
 ibmmca_scsi_setup (char *str, int *ints)
 {
-   int i;
-
-   for (i = 0; i < IM_MAX_HOSTS && i < ints[0]; i++)
-      io_port[i] = ints[i+1];
+   if( str && !strcmp( str, "display" ) ) {
+   	use_display = 1;
+   } else if( ints ) {
+	   int i;
+	   for (i = 0; i < IM_MAX_HOSTS && i < ints[0]; i++) {
+	      io_port[i] = ints[i+1];
+	   }
+   }
 }
 
 #endif
@@ -1597,9 +1689,16 @@
   int current_ldn;
   int id,lun;
 
+  /* use industry standard ordering of the IDs */
+#ifdef CONFIG_IBMMCA_SCSI_ORDER_STANDARD
+  int target = 6 - cmd->target;
+#else
+  int target = cmd->target;
+#endif
+
   /*if (target,lun) is NO LUN or not existing at all, return error */
-  if ((get_scsi[cmd->target][cmd->lun] == TYPE_NO_LUN)||
-      (get_scsi[cmd->target][cmd->lun] == TYPE_NO_DEVICE))
+  if ((get_scsi[target][cmd->lun] == TYPE_NO_LUN)||
+      (get_scsi[target][cmd->lun] == TYPE_NO_DEVICE))
      {
 	cmd->result = DID_NO_CONNECT << 16;
 	done (cmd);
@@ -1607,7 +1706,7 @@
      }
    
   /*if (target,lun) unassigned, do further checks... */
-  ldn = get_ldn[cmd->target][cmd->lun];
+  ldn = get_ldn[target][cmd->lun];
   if (ldn >= MAX_LOG_DEV) /* on invalid ldn do special stuff */
     {
       if (ldn > MAX_LOG_DEV) /* dynamical remapping if ldn unassigned */
@@ -1623,7 +1722,7 @@
 		      printk("IBM MCA SCSI: Cannot assign SCSI-device dynamically!\n");
 		      printk("              On ldn 7-14 SCSI-commands everywhere in progress.\n");
 		      printk("              Reporting DID_NO_CONNECT for device (%d,%d).\n",
-			     cmd->target, cmd->lun);
+			     target, cmd->lun);
 		      cmd->result = DID_NO_CONNECT << 16;/* return no connect*/
 		      done (cmd);
 		      return 0;
@@ -1631,8 +1730,8 @@
 	      }
 
 	    /* unmap non-processing ldn */
-	    for (id=0; id<=7; id ++)
-	      for (lun=0; lun<=7; lun++)
+	    for (id=0; id<8; id ++)
+	      for (lun=0; lun<8; lun++)
 	      {
 		 if (get_ldn[id][lun] == next_ldn)
 		   {
@@ -1645,9 +1744,9 @@
 	    /* unassign found ldn (pun,lun does not matter for remove) */
 	    immediate_assign(shpnt,0,0,next_ldn,REMOVE_LDN);
 	    /* assign found ldn to aimed pun,lun */
-	    immediate_assign(shpnt,cmd->target,cmd->lun,next_ldn,SET_LDN);
+	    immediate_assign(shpnt,target,cmd->lun,next_ldn,SET_LDN);
 	    /* map found ldn to pun,lun */
-	    get_ldn[cmd->target][cmd->lun] = next_ldn;
+	    get_ldn[target][cmd->lun] = next_ldn;
             /* change ldn to the right value, that is now next_ldn */
 	    ldn = next_ldn;
 	    /* set reduced interrupt_handler-mode for checking */
@@ -1668,19 +1767,19 @@
 	         /* panic here, because a device, found at boottime has 
 		    vanished */
 	         panic("IBM MCA SCSI: ldn=0x%x, SCSI-device on (%d,%d) vanished!\n",
-		       ldn, cmd->target, cmd->lun);
+		       ldn, target, cmd->lun);
 	    
 	    /* set back to normal interrupt_handling */
 	    local_checking_phase_flag = 0;
 	    
 	    /* Information on syslog terminal */
 	    printk("IBM MCA SCSI: ldn=0x%x dynamically reassigned to (%d,%d).\n",
-		   ldn, cmd->target, cmd->lun);
+		   ldn, target, cmd->lun);
 	    
 	    /* increase next_ldn for next dynamical assignment */ 
 	    next_ldn ++;
 	    if (next_ldn>=MAX_LOG_DEV) next_ldn = 7;
-	 }
+	 }       
       else
 	 {  /* wall against Linux accesses to the subsystem adapter */	 
             cmd->result = DID_NO_CONNECT << 16;
@@ -1729,7 +1828,7 @@
   printk("issue scsi cmd=%02x to ldn=%d\n", scsi_cmd, ldn);
 #endif
 
-  /* for specific device debugging: */
+  /* for specific device-type debugging: */
 #ifdef IM_DEBUG_CMD_SPEC_DEV
   if (ld[ldn].device_type==IM_DEBUG_CMD_DEVICE)
      printk("(SCSI-device-type=0x%x) issue scsi cmd=%02x to ldn=%d\n", 
@@ -1794,7 +1893,7 @@
 	     }
            scb->u2.blk.length = ld[ldn].block_length;
 	   if (++disk_rw_in_progress == 1)
-	      PS2_DISK_LED_ON (shpnt->host_no, cmd->target);
+	      PS2_DISK_LED_ON (shpnt->host_no, target);
 	  break;
 	    
 	  /* for other devices, enter here. Other types are not known by
@@ -1830,11 +1929,12 @@
 	   /* Read/write on this non-disk devices is also displayworthy, 
 	      so flash-up the LED/display. */
 	   if (++disk_rw_in_progress == 1)
-	      PS2_DISK_LED_ON (shpnt->host_no, cmd->target);
+	      PS2_DISK_LED_ON (shpnt->host_no, target);
 	 break;
 	 }
       break;
     case INQUIRY:
+      IBM_DS.ldn_inquiry_access[ldn]++;
       scb->command = IM_DEVICE_INQUIRY_CMD;
       scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT;
       break;
@@ -1856,6 +1956,7 @@
     /* Commands that need write-only-mode (system -> device): */
     case MODE_SELECT:
     case MODE_SELECT_10:
+      IBM_DS.ldn_modeselect_access[ldn]++;
       scb->command = IM_OTHER_SCSI_CMD_CMD;      
       scb->enable |= IM_SUPRESS_EXCEPTION_SHORT; /*Select needs WRITE-enabled*/
       scb->u1.scsi_cmd_length = cmd->cmd_len;
@@ -1892,10 +1993,16 @@
   unsigned int ldn;
   void (*saved_done) (Scsi_Cmnd *);
 
+#ifdef CONFIG_IBMMCA_SCSI_ORDER_STANDARD
+  int target = 6 - cmd->target;
+#else
+  int target = cmd->target;
+#endif
+
   /*get logical device number, and disable system interrupts */
   printk ("IBM MCA SCSI: sending abort to device id=%d lun=%d.\n",
-	  cmd->target, cmd->lun);
-  ldn = get_ldn[cmd->target][cmd->lun];
+	  target, cmd->lun);
+  ldn = get_ldn[target][cmd->lun];
   cli ();
 
   /*if cmd for this ldn has already finished, no need to abort */
@@ -2027,12 +2134,32 @@
    return(a);
 }
 
+static int ldn_access_total_inquiry(struct Scsi_Host *shpnt)
+{
+   int a = 0;
+   int i;
+   
+   for (i=0; i<=MAX_LOG_DEV; i++)
+     a+=IBM_DS.ldn_inquiry_access[i];
+   return(a);
+}
+
+static int ldn_access_total_modeselect(struct Scsi_Host *shpnt)
+{
+   int a = 0;
+   int i;
+   
+   for (i=0; i<=MAX_LOG_DEV; i++)
+     a+=IBM_DS.ldn_modeselect_access[i];
+   return(a);
+}
+
 /* routine to display info in the proc-fs-structure (a deluxe feature) */
 int ibmmca_proc_info (char *buffer, char **start, off_t offset, int length,
 		      int hostno, int inout)
 {
    int len=0;
-   int i,id;
+   int i,id,lun;
    struct Scsi_Host *shpnt;
 
    for (i = 0; hosts[i] && hosts[i]->host_no != hostno; i++);
@@ -2047,6 +2174,11 @@
    len += sprintf(buffer+len, "\n             IBM-SCSI-Subsystem-Linux-Driver, Version %s\n\n\n",
 		  IBMMCA_SCSI_DRIVER_VERSION);
    len += sprintf(buffer+len, " SCSI Access-Statistics:\n");
+#ifdef CONFIG_IBMMCA_SCSI_ORDER_STANDARD
+   len += sprintf(buffer+len, "               ANSI-SCSI-standard order.: Yes\n");
+#else
+   len += sprintf(buffer+len, "               ANSI-SCSI-standard order.: No\n");
+#endif
 #ifdef CONFIG_SCSI_MULTI_LUN
    len += sprintf(buffer+len, "               Multiple LUN probing.....: Yes\n");
 #else
@@ -2064,8 +2196,14 @@
 		  IBM_DS.total_accesses);
    len += sprintf(buffer+len, "                 Total SCSI READ/WRITE..: %d\n",
 		  ldn_access_total_read_write(shpnt));
+   len += sprintf(buffer+len, "                 Total SCSI Inquiries...: %d\n",
+		  ldn_access_total_inquiry(shpnt));
+   len += sprintf(buffer+len, "                 Total SCSI Modeselects.: %d\n",
+		  ldn_access_total_modeselect(shpnt));
    len += sprintf(buffer+len, "                 Total SCSI other cmds..: %d\n\n",
-		  IBM_DS.total_accesses - ldn_access_total_read_write(shpnt));
+		  IBM_DS.total_accesses - ldn_access_total_read_write(shpnt)
+		  - ldn_access_total_modeselect(shpnt)
+		  - ldn_access_total_inquiry(shpnt));
    
    len += sprintf(buffer+len, " Logical-Device-Number (LDN) Access-Statistics:\n");
    len += sprintf(buffer+len, "         LDN | Accesses [%%] |   READ    |   WRITE   | ASSIGNMENTS\n");
@@ -2096,11 +2234,11 @@
 	       ti_p(get_scsi[id][2]), ti_p(get_scsi[id][3]), 
 	       ti_p(get_scsi[id][4]), ti_p(get_scsi[id][5]), 
 	       ti_p(get_scsi[id][6]), ti_p(get_scsi[id][7]));
-	len += sprintf(buffer+len, "       %2d     %2s %2s %2s %2s %2s %2s %2s %2s\n",
-	       id, ti_l(get_ldn[id][0]), ti_l(get_ldn[id][1]), 
-	       ti_l(get_ldn[id][2]), ti_l(get_ldn[id][3]), 
-	       ti_l(get_ldn[id][4]), ti_l(get_ldn[id][5]),
-	       ti_l(get_ldn[id][6]), ti_l(get_ldn[id][7]));
+	
+	len += sprintf(buffer+len, "       %2d     ",id);
+	for (lun=0; lun<8; lun++)
+	  len += sprintf(buffer+len,"%2s ",ti_l(get_ldn[id][lun]));
+	len += sprintf(buffer+len,"\n");
      }
    
    len += sprintf(buffer+len, "(A = IBM-Subsystem, D = Harddisk, T = Tapedrive, P = Processor, W = WORM,\n");
@@ -2125,3 +2263,6 @@
 #endif
 
 /*--------------------------------------------------------------------*/
+
+
+
diff -u --recursive --new-file v2.1.84/linux/drivers/scsi/ibmmca.h linux/drivers/scsi/ibmmca.h
--- v2.1.84/linux/drivers/scsi/ibmmca.h	Sun Dec 21 17:04:49 1997
+++ linux/drivers/scsi/ibmmca.h	Mon Feb  2 14:51:31 1998
@@ -19,22 +19,30 @@
 extern struct proc_dir_entry proc_scsi_ibmmca;
 
 /*initialization for Scsi_host_template type */
-#define IBMMCA {						      \
-          proc_dir:       &proc_scsi_ibmmca,    /*proc_dir*/          \
-	  proc_info:	  ibmmca_proc_info,     /*proc info fn*/      \
-          name:           "IBMMCA",             /*name*/              \
-          detect:         ibmmca_detect,        /*detect fn*/         \
-          release:        ibmmca_release,       /*release fn*/        \
-          command:        ibmmca_command,       /*command fn*/        \
-          queuecommand:   ibmmca_queuecommand,  /*queuecommand fn*/   \
-          abort:          ibmmca_abort,         /*abort fn*/          \
-          reset:          ibmmca_reset,         /*reset fn*/          \
-          bios_param:     ibmmca_biosparam,     /*bios fn*/           \
-          can_queue:      16,                   /*can_queue*/         \
-          this_id:        7,                    /*set by detect*/     \
-          sg_tablesize:   16,                   /*sg_tablesize*/      \
-          cmd_per_lun:    1,                    /*cmd_per_lun*/       \
-          use_clustering: ENABLE_CLUSTERING     /*use_clustering*/    \
+#define IBMMCA {                                      \
+          NULL,                 /*next*/              \
+          NULL,                 /*usage_count*/       \
+          &proc_scsi_ibmmca,    /*proc_dir*/          \
+          ibmmca_proc_info,     /*proc info fn*/      \
+          "IBMMCA",             /*name*/              \
+          ibmmca_detect,        /*detect fn*/         \
+          ibmmca_release,       /*release fn*/        \
+          NULL,                 /*info fn*/           \
+          ibmmca_command,       /*command fn*/        \
+          ibmmca_queuecommand,  /*queuecommand fn*/   \
+          ibmmca_abort,         /*abort fn*/          \
+          ibmmca_reset,         /*reset fn*/          \
+          NULL,                 /*slave_attach fn*/   \
+          ibmmca_biosparam,     /*bios fn*/           \
+          16,                   /*can_queue*/         \
+          7,                    /*set by detect*/     \
+          16,                   /*sg_tablesize*/      \
+          1,                    /*cmd_per_lun*/       \
+          0,                    /*present*/           \
+          0,                    /*unchecked_isa_dma*/ \
+          ENABLE_CLUSTERING     /*use_clustering*/    \
         }
 
 #endif /* _IBMMCA_H */
+
+
diff -u --recursive --new-file v2.1.84/linux/fs/autofs/dirhash.c linux/fs/autofs/dirhash.c
--- v2.1.84/linux/fs/autofs/dirhash.c	Mon Jul  7 12:45:57 1997
+++ linux/fs/autofs/dirhash.c	Mon Feb  2 10:45:49 1998
@@ -2,7 +2,7 @@
  *
  * linux/fs/autofs/dirhash.c
  *
- *  Copyright 1997 Transmeta Corporation -- All Rights Reserved
+ *  Copyright 1997-1998 Transmeta Corporation -- All Rights Reserved
  *
  * This file is part of the Linux kernel and is made available under
  * the terms of the GNU General Public License, version 2, or at your
@@ -84,11 +84,15 @@
 	ent->next = *dhnp;
 	ent->back = dhnp;
 	*dhnp = ent;
+	if ( ent->next )
+		ent->next->back = &(ent->next);
 }
 
 void autofs_hash_delete(struct autofs_dir_ent *ent)
 {
 	*(ent->back) = ent->next;
+	if ( ent->next )
+		ent->next->back = ent->back;
 
 	autofs_delete_usage(ent);
 
diff -u --recursive --new-file v2.1.84/linux/fs/dcache.c linux/fs/dcache.c
--- v2.1.84/linux/fs/dcache.c	Fri Jan 23 18:10:32 1998
+++ linux/fs/dcache.c	Tue Feb  3 15:14:56 1998
@@ -758,6 +758,30 @@
 }
 
 /*
+ * Test whether new_dentry is a subdirectory of old_dentry.
+ *
+ * Trivially implemented using the dcache structure
+ */
+int is_subdir(struct dentry * new_dentry, struct dentry * old_dentry)
+{
+	int result;
+
+	result = 0;
+	for (;;) {
+		if (new_dentry != old_dentry) {
+			struct dentry * parent = new_dentry->d_parent;
+			if (parent == new_dentry)
+				break;
+			new_dentry = parent;
+			continue;
+		}
+		result = 1;
+		break;
+	}
+	return result;
+}
+
+/*
  * Check whether a dentry already exists for the given name,
  * and return the inode number if it has an inode.
  *
diff -u --recursive --new-file v2.1.84/linux/fs/proc/root.c linux/fs/proc/root.c
--- v2.1.84/linux/fs/proc/root.c	Fri Jan 30 15:50:57 1998
+++ linux/fs/proc/root.c	Mon Feb  2 13:31:51 1998
@@ -621,13 +621,6 @@
 	S_IFREG | S_IRUGO, 1, 0, 0,
 	0, &proc_array_inode_operations
 };
-#ifdef CONFIG_OMIRR
-static struct proc_dir_entry proc_root_omirr = {
-	PROC_OMIRR, 5, "omirr",
-	S_IFREG | S_IRUSR, 1, 0, 0,
-	0, &proc_omirr_inode_operations
-};
-#endif
 #ifdef __powerpc__
 static struct proc_dir_entry proc_root_ppc_htab = {
 	PROC_PPC_HTAB, 8, "ppc_htab",
diff -u --recursive --new-file v2.1.84/linux/fs/sysv/CHANGES linux/fs/sysv/CHANGES
--- v2.1.84/linux/fs/sysv/CHANGES	Fri Jan 30 11:28:09 1998
+++ linux/fs/sysv/CHANGES	Mon Feb  2 13:03:14 1998
@@ -7,3 +7,10 @@
 		      in detected_[xenix,sysv4,sysv2,coherent]. Thanks
 		      to Andrzej Krzysztofowicz <ankry@mif.pg.gda.pl>
 		      for identifying the problem.
+
+Tue Jan 27 1998   Krzysztof G. Baranowski <kgb@manjak.knm.org.pl>
+        *    inode.c: added 2048-byte block support to SystemV FS.
+		      Merged detected_bs[512,1024,2048] into one function:
+		      void detected_bs (u_char type, struct super_block *sb).
+		      Thanks to Andrzej Krzysztofowicz <ankry@mif.pg.gda.pl>
+		      for the patch.
diff -u --recursive --new-file v2.1.84/linux/fs/sysv/INTRO linux/fs/sysv/INTRO
--- v2.1.84/linux/fs/sysv/INTRO	Sat Nov  5 03:32:13 1994
+++ linux/fs/sysv/INTRO	Mon Feb  2 13:03:14 1998
@@ -18,7 +18,7 @@
 * Size of a block or zone (data allocation unit on disk)
   - Minix FS     1024
   - Xenix FS     1024 (also 512 ??)
-  - SystemV FS   1024 (also 512)
+  - SystemV FS   1024 (also 512 and 2048)
   - Coherent FS   512
 
 * General layout: all have one boot block, one super block and
@@ -180,4 +180,3 @@
 
 
 Bruno Haible  <haible@ma2s2.mathematik.uni-karlsruhe.de>
-
diff -u --recursive --new-file v2.1.84/linux/fs/sysv/inode.c linux/fs/sysv/inode.c
--- v2.1.84/linux/fs/sysv/inode.c	Fri Jan 30 11:28:09 1998
+++ linux/fs/sysv/inode.c	Mon Feb  2 13:03:14 1998
@@ -34,6 +34,27 @@
 
 #include <asm/uaccess.h>
 
+#if 0
+void sysv_print_inode(struct inode * inode)
+{
+        printk("ino %lu  mode 0%6.6o  lk %d  uid %d  gid %d"
+               "  sz %lu  blks %lu  cnt %u\n",
+               inode->i_ino, inode->i_mode, inode->i_nlink, inode->i_uid,
+               inode->i_gid, inode->i_size, inode->i_blocks, inode->i_count);
+        printk("  db <0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx"
+               " 0x%lx 0x%lx>\n",
+                inode->u.sysv_i.i_data[0], inode->u.sysv_i.i_data[1],
+                inode->u.sysv_i.i_data[2], inode->u.sysv_i.i_data[3],
+                inode->u.sysv_i.i_data[4], inode->u.sysv_i.i_data[5],
+                inode->u.sysv_i.i_data[6], inode->u.sysv_i.i_data[7],
+                inode->u.sysv_i.i_data[8], inode->u.sysv_i.i_data[9]);
+        printk("  ib <0x%lx 0x%lx 0x%lx>\n",
+                inode->u.sysv_i.i_data[10],
+                inode->u.sysv_i.i_data[11],
+                inode->u.sysv_i.i_data[12]);
+}
+#endif
+
 void sysv_put_inode(struct inode *inode)
 {
 	if (inode->i_nlink)
@@ -65,58 +86,35 @@
  * the time stamp is not < 01-01-1980.
  */
 
-static void detected_bs512 (struct super_block *sb)
+static void detected_bs (u_char type, struct super_block *sb)
 {
-	sb->sv_block_size = 512;
-	sb->sv_block_size_1 = 512-1;
-	sb->sv_block_size_bits = 9;
-	sb->sv_block_size_ratio = 2;
-	sb->sv_block_size_ratio_bits = 1;
-	sb->sv_inodes_per_block = 512/64;
-	sb->sv_inodes_per_block_1 = 512/64-1;
-	sb->sv_inodes_per_block_bits = 9-6;
+	u_char n_bits = type+8;
+	int bsize = 1 << n_bits;
+	int bsize_4 = bsize >> 2;
+	
+	sb->sv_block_size = bsize;
+	sb->sv_block_size_1 = bsize-1;
+	sb->sv_block_size_bits = n_bits;
+	sb->sv_block_size_dec_bits = (bsize==512) ? 1 : 0;
+	sb->sv_block_size_inc_bits = (bsize==2048) ? 1 : 0;
+	sb->sv_inodes_per_block = bsize >> 6;
+	sb->sv_inodes_per_block_1 = (bsize >> 6)-1;
+	sb->sv_inodes_per_block_bits = n_bits-6;
 	sb->sv_toobig_block = 10 +
-	  (sb->sv_ind_per_block = 512/4) +
-	  (sb->sv_ind_per_block_2 = (512/4)*(512/4)) +
-	  (sb->sv_ind_per_block_3 = (512/4)*(512/4)*(512/4));
-	sb->sv_ind_per_block_1 = 512/4-1;
-	sb->sv_ind_per_block_2_1 = (512/4)*(512/4)-1;
+	  (sb->sv_ind_per_block = bsize_4) +
+	  (sb->sv_ind_per_block_2 = bsize_4*bsize_4) +
+	  (sb->sv_ind_per_block_3 = bsize_4*bsize_4*bsize_4);
+	sb->sv_ind_per_block_1 = bsize_4-1;
+	sb->sv_ind_per_block_2_1 = bsize_4*bsize_4-1;
 	sb->sv_ind_per_block_2_bits = 2 *
-	  (sb->sv_ind_per_block_bits = 9-2);
-	sb->sv_ind_per_block_block_size_1 = (512/4)*512-1;
-	sb->sv_ind_per_block_block_size_bits = (9-2)+9;
-	sb->sv_ind_per_block_2_block_size_1 = (512/4)*(512/4)*512-1;
-	sb->sv_ind_per_block_2_block_size_bits = (9-2)+(9-2)+9;
-	sb->sv_ind0_size = 10 * 512;
-	sb->sv_ind1_size = (10 + (512/4))* 512;
-	sb->sv_ind2_size = (10 + (512/4) + (512/4)*(512/4)) * 512;
-}
-
-static void detected_bs1024 (struct super_block *sb)
-{
-	sb->sv_block_size = 1024;
-	sb->sv_block_size_1 = 1024-1;
-	sb->sv_block_size_bits = 10;
-	sb->sv_block_size_ratio = 1;
-	sb->sv_block_size_ratio_bits = 0;
-	sb->sv_inodes_per_block = 1024/64;
-	sb->sv_inodes_per_block_1 = 1024/64-1;
-	sb->sv_inodes_per_block_bits = 10-6;
-	sb->sv_toobig_block = 10 +
-	  (sb->sv_ind_per_block = 1024/4) +
-	  (sb->sv_ind_per_block_2 = (1024/4)*(1024/4)) +
-	  (sb->sv_ind_per_block_3 = (1024/4)*(1024/4)*(1024/4));
-	sb->sv_ind_per_block_1 = 1024/4-1;
-	sb->sv_ind_per_block_2_1 = (1024/4)*(1024/4)-1;
-	sb->sv_ind_per_block_2_bits = 2 *
-	  (sb->sv_ind_per_block_bits = 10-2);
-	sb->sv_ind_per_block_block_size_1 = (1024/4)*1024-1;
-	sb->sv_ind_per_block_block_size_bits = (10-2)+10;
-	sb->sv_ind_per_block_2_block_size_1 = (1024/4)*(1024/4)*1024-1;
-	sb->sv_ind_per_block_2_block_size_bits = (10-2)+(10-2)+10;
-	sb->sv_ind0_size = 10 * 1024;
-	sb->sv_ind1_size = (10 + (1024/4))* 1024;
-	sb->sv_ind2_size = (10 + (1024/4) + (1024/4)*(1024/4)) * 1024;
+	  (sb->sv_ind_per_block_bits = n_bits-2);
+	sb->sv_ind_per_block_block_size_1 = bsize_4*bsize-1;
+	sb->sv_ind_per_block_block_size_bits = 2*n_bits-2;
+	sb->sv_ind_per_block_2_block_size_1 = bsize_4*bsize_4*bsize-1;
+	sb->sv_ind_per_block_2_block_size_bits = 3*n_bits-4;
+	sb->sv_ind0_size = 10 * bsize;
+	sb->sv_ind1_size = (10 + bsize_4)* bsize;
+	sb->sv_ind2_size = (10 + bsize_4 + bsize_4*bsize_4) * bsize;
 }
 
 static const char* detect_xenix (struct super_block *sb, struct buffer_head *bh)
@@ -126,11 +124,9 @@
 	sbd = (struct xenix_super_block *) bh->b_data;
 	if (sbd->s_magic != 0x2b5544)
 		return NULL;
-	switch (sbd->s_type) {
-		case 1: detected_bs512(sb); break;
-		case 2: detected_bs1024(sb); break;
-		default: return NULL;
-	}
+	if (sbd->s_type > 2 || sbd->s_type < 1)
+		return NULL;
+	detected_bs(sbd->s_type, sb);
 	sb->sv_type = FSTYPE_XENIX;
 	return "Xenix";
 }
@@ -139,8 +135,8 @@
 	struct xenix_super_block * sbd1;
 	struct xenix_super_block * sbd2;
 
-	if (sb->sv_block_size == BLOCK_SIZE)
-		/* block size = 1024, so bh1 = bh2 */
+	if (sb->sv_block_size >= BLOCK_SIZE)
+		/* block size >= 1024, so bh1 = bh2 */
 		sbd1 = sbd2 = (struct xenix_super_block *) bh1->b_data;
 	else {
 		/* block size = 512, so bh1 != bh2 */
@@ -184,11 +180,9 @@
 		return NULL;
 	if (sbd->s_time < 315532800) /* this is likely to happen on SystemV2 FS */
 		return NULL;
-	switch (sbd->s_type) {
-		case 1: detected_bs512(sb); break;
-		case 2: detected_bs1024(sb); break;
-		default: return NULL;
-	}
+	if (sbd->s_type > 3 || sbd->s_type < 1)
+		return NULL;
+	detected_bs(sbd->s_type, sb);
 	sb->sv_type = FSTYPE_SYSV4;
 	return "SystemV";
 }
@@ -196,7 +190,7 @@
 {
 	struct sysv4_super_block * sbd;
 
-	if (sb->sv_block_size == BLOCK_SIZE)
+	if (sb->sv_block_size >= BLOCK_SIZE)
 		sbd = (struct sysv4_super_block *) (bh->b_data + BLOCK_SIZE/2);
 	else {
 		sbd = (struct sysv4_super_block *) bh->b_data;
@@ -241,11 +235,9 @@
 		return NULL;
 	if (sbd->s_time < 315532800) /* this is likely to happen on SystemV4 FS */
 		return NULL;
-	switch (sbd->s_type) {
-		case 1: detected_bs512(sb); break;
-		case 2: detected_bs1024(sb); break;
-		default: return NULL;
-	}
+	if (sbd->s_type > 3 || sbd->s_type < 1)
+		return NULL;
+	detected_bs(sbd->s_type, sb);
 	sb->sv_type = FSTYPE_SYSV2;
 	return "SystemV Release 2";
 }
@@ -253,7 +245,7 @@
 {
 	struct sysv2_super_block * sbd;
 
-	if (sb->sv_block_size == BLOCK_SIZE)
+	if (sb->sv_block_size >= BLOCK_SIZE)
 		sbd = (struct sysv2_super_block *) (bh->b_data + BLOCK_SIZE/2);
 	else {
 		sbd = (struct sysv2_super_block *) bh->b_data;
@@ -297,7 +289,7 @@
 	if ((memcmp(sbd->s_fname,"noname",6) && memcmp(sbd->s_fname,"xxxxx ",6))
 	    || (memcmp(sbd->s_fpack,"nopack",6) && memcmp(sbd->s_fpack,"xxxxx\n",6)))
 		return NULL;
-	detected_bs512(sb);
+	detected_bs(1, sb);
 	sb->sv_type = FSTYPE_COH;
 	return "Coherent";
 }
@@ -342,7 +334,8 @@
 	const char *found;
 	kdev_t dev = sb->s_dev;
 	struct inode *root_inode;
-
+	unsigned long blocknr;
+	
 	if (1024 != sizeof (struct xenix_super_block))
 		panic("Xenix FS: bad super-block size");
 	if ((512 != sizeof (struct sysv4_super_block))
@@ -376,22 +369,29 @@
 	}
 	/* Try to recognize SystemV superblock */
 	/* Offset by 1 track, i.e. most probably 9, 15, or 18 kilobytes. */
+	/* 2kB blocks with offset of 9 and 15 kilobytes are not supported. */
+	/* Maybe we should also check the device geometry ? */
 	{	static int offsets[] = { 9, 15, 18, };
 		int i;
 		for (i = 0; i < sizeof(offsets)/sizeof(offsets[0]); i++)
 			if ((bh = bread(dev, offsets[i], BLOCK_SIZE)) != NULL) {
 				/* Try to recognize SystemV superblock */
 				if ((found = detect_sysv4(sb,bh)) != NULL) {
-					sb->sv_block_base = offsets[i] << sb->sv_block_size_ratio_bits;
+					if (sb->sv_block_size>BLOCK_SIZE && (offsets[i] % 2))
+						goto bad_shift;
+					sb->sv_block_base = (offsets[i] << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits;
 					goto ok;
 				}
 				if ((found = detect_sysv2(sb,bh)) != NULL) {
-					sb->sv_block_base = offsets[i] << sb->sv_block_size_ratio_bits;
+					if (sb->sv_block_size>BLOCK_SIZE && (offsets[i] % 2))
+						goto bad_shift;
+					sb->sv_block_base = (offsets[i] << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits;
 					goto ok;
 				}
 				brelse(bh);
 			}
 	}
+	bad_shift:
 	sb->s_dev = 0;
 	unlock_super(sb);
 	if (!silent)
@@ -402,7 +402,14 @@
 	return NULL;
 
 	ok:
-	if (sb->sv_block_size == BLOCK_SIZE) {
+	if (sb->sv_block_size >= BLOCK_SIZE) {
+		if (sb->sv_block_size != BLOCK_SIZE) {
+			brelse(bh);
+			set_blocksize(dev, sb->sv_block_size);
+			blocknr = (bh->b_blocknr << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits;
+			if ((bh = bread(dev, blocknr, sb->sv_block_size)) == NULL)
+				goto bad_superblock;
+		}
 		switch (sb->sv_type) {
 			case FSTYPE_XENIX:
 				if (!detected_xenix(sb,bh,bh))
@@ -416,19 +423,21 @@
 				if (!detected_sysv2(sb,bh))
 					goto bad_superblock;
 				break;
-			default:
-			bad_superblock:
-				brelse(bh);
-				sb->s_dev = 0;
-				unlock_super(sb);
-				printk("SysV FS: cannot read superblock in 1024 byte mode\n");
-				goto failed;
+			default: goto bad_superblock;
+		goto superblock_ok;
+		bad_superblock:
+			brelse(bh);
+			sb->s_dev = 0;
+			unlock_super(sb);
+			printk("SysV FS: cannot read superblock in %d byte mode\n", sb->sv_block_size);
+			goto failed;
+		superblock_ok:
 		}
 	} else {
-		/* Switch to another block size. Unfortunately, we have to
-		   release the 1 KB block bh and read it in two parts again. */
+		/* Switch to 512 block size. Unfortunately, we have to
+		   release the block bh and read it again. */
 		struct buffer_head *bh1, *bh2;
-		unsigned long blocknr = bh->b_blocknr << sb->sv_block_size_ratio_bits;
+		unsigned long blocknr = (bh->b_blocknr << sb->sv_block_size_dec_bits) >> sb->sv_block_size_inc_bits;
 
 		brelse(bh);
 		set_blocksize(dev,sb->sv_block_size);
diff -u --recursive --new-file v2.1.84/linux/fs/sysv/namei.c linux/fs/sysv/namei.c
--- v2.1.84/linux/fs/sysv/namei.c	Fri Jan 30 11:28:09 1998
+++ linux/fs/sysv/namei.c	Mon Feb  2 13:03:49 1998
@@ -9,7 +9,6 @@
  *
  *  sysv/namei.c
  *  Copyright (C) 1993  Bruno Haible
- *
  */
 
 
diff -u --recursive --new-file v2.1.84/linux/include/asm-alpha/hardirq.h linux/include/asm-alpha/hardirq.h
--- v2.1.84/linux/include/asm-alpha/hardirq.h	Mon Apr 14 16:28:18 1997
+++ linux/include/asm-alpha/hardirq.h	Mon Feb  2 13:41:06 1998
@@ -4,7 +4,6 @@
 #include <linux/tasks.h>
 
 extern unsigned int local_irq_count[NR_CPUS];
-#define in_interrupt()	(local_irq_count[smp_processor_id()] != 0)
 
 #ifndef __SMP__
 
diff -u --recursive --new-file v2.1.84/linux/include/asm-alpha/softirq.h linux/include/asm-alpha/softirq.h
--- v2.1.84/linux/include/asm-alpha/softirq.h	Fri Jan 30 11:28:09 1998
+++ linux/include/asm-alpha/softirq.h	Mon Feb  2 13:41:06 1998
@@ -5,7 +5,7 @@
  * is entirely private to an implementation, it should not be
  * referenced at all outside of this file.
  */
-extern atomic_t __alpha_bh_counter;
+extern unsigned int local_bh_count[NR_CPUS];
 
 #define get_active_bhs()	(bh_mask & bh_active)
 
@@ -43,51 +43,49 @@
 }
 
 /*
- * These use a mask count to correctly handle
- * nested disable/enable calls
- */
-extern inline void disable_bh(int nr)
-{
-	bh_mask &= ~(1 << nr);
-	bh_mask_count[nr]++;
-}
-
-extern inline void enable_bh(int nr)
-{
-	if (!--bh_mask_count[nr])
-		bh_mask |= 1 << nr;
-}
-
-/*
  * start_bh_atomic/end_bh_atomic also nest
  * naturally by using a counter
  */
 extern inline void start_bh_atomic(void)
 {
-#ifdef __SMP__
-	atomic_inc(&__alpha_bh_counter);
-	synchronize_irq();
-#else
-	atomic_inc(&__alpha_bh_counter);
-#endif
+	local_bh_count[smp_processor_id()]++;
+	barrier();
 }
 
 extern inline void end_bh_atomic(void)
 {
-	atomic_dec(&__alpha_bh_counter);
+	barrier();
+	local_bh_count[smp_processor_id()]--;
 }
 
 #ifndef __SMP__
 
 /* These are for the irq's testing the lock */
-#define softirq_trylock(cpu)	(atomic_read(&__alpha_bh_counter) ? \
-				0 : \
-				((atomic_set(&__alpha_bh_counter,1)),1))
-#define softirq_endlock(cpu)	(atomic_set(&__alpha_bh_counter, 0))
+#define softirq_trylock(cpu) \
+  (local_bh_count[cpu] ? 0 : (local_bh_count[cpu] = 1))
+#define softirq_endlock(cpu) \
+  (local_bh_count[cpu] = 0)
 
 #else
 
 #error FIXME
 
 #endif /* __SMP__ */
+
+/*
+ * These use a mask count to correctly handle
+ * nested disable/enable calls
+ */
+extern inline void disable_bh(int nr)
+{
+	bh_mask &= ~(1 << nr);
+	bh_mask_count[nr]++;
+}
+
+extern inline void enable_bh(int nr)
+{
+	if (!--bh_mask_count[nr])
+		bh_mask |= 1 << nr;
+}
+
 #endif /* _ALPHA_SOFTIRQ_H */
diff -u --recursive --new-file v2.1.84/linux/include/linux/fs.h linux/include/linux/fs.h
--- v2.1.84/linux/include/linux/fs.h	Tue Feb  3 18:26:29 1998
+++ linux/include/linux/fs.h	Tue Feb  3 15:33:30 1998
@@ -728,6 +728,9 @@
 extern struct dentry * open_namei(const char * pathname, int flag, int mode);
 extern struct dentry * do_mknod(const char * filename, int mode, dev_t dev);
 extern int do_pipe(int *);
+
+/* fs/dcache.c -- generic fs support functions */
+extern int is_subdir(struct dentry *, struct dentry *);
 extern ino_t find_inode_number(struct dentry *, struct qstr *);
 
 /*
diff -u --recursive --new-file v2.1.84/linux/include/linux/proc_fs.h linux/include/linux/proc_fs.h
--- v2.1.84/linux/include/linux/proc_fs.h	Fri Jan 30 11:28:10 1998
+++ linux/include/linux/proc_fs.h	Tue Feb  3 15:33:32 1998
@@ -48,7 +48,6 @@
 	PROC_HARDWARE,
 	PROC_SLABINFO,
 	PROC_PARPORT,
-	PROC_OMIRR, /* whether enabled or not */
 	PROC_PPC_HTAB,
 	PROC_SOUND
 };
diff -u --recursive --new-file v2.1.84/linux/include/linux/sysv_fs_sb.h linux/include/linux/sysv_fs_sb.h
--- v2.1.84/linux/include/linux/sysv_fs_sb.h	Tue Jan 10 07:02:11 1995
+++ linux/include/linux/sysv_fs_sb.h	Mon Feb  2 13:03:55 1998
@@ -15,8 +15,8 @@
 	unsigned int   s_block_size;	/* zone size, = 512 or = 1024 */
 	unsigned int   s_block_size_1;	/* block_size - 1 */
 	unsigned int   s_block_size_bits;	/* log2(block_size) */
-	unsigned int   s_block_size_ratio;	/* BLOCK_SIZE / block_size */
-	unsigned int   s_block_size_ratio_bits;	/* log2(block_size_ratio) */
+	unsigned int   s_block_size_inc_bits;	/* log2(block_size/BLOCK_SIZE) if >0 */
+	unsigned int   s_block_size_dec_bits;	/* log2(BLOCK_SIZE/block_size) if >0 */
 	char	       s_convert;	/* flag whether byte ordering requires conversion */
 	char	       s_kludge_symlinks; /* flag whether symlinks have a kludgey mode */
 	char	       s_truncate;	/* if 1: names > SYSV_NAMELEN chars are truncated */
@@ -66,15 +66,15 @@
 	unsigned long  s_ndatazones;	/* total number of data zones */
 	unsigned long  s_nzones;	/* same as s_sbd->s_fsize */
 };
-/* The fields s_block_size_ratio, s_ind_per_block_2_1, s_toobig_block are currently unused. */
+/* The fields s_ind_per_block_2_1, s_toobig_block are currently unused. */
 
 /* sv_ == u.sysv_sb.s_ */
 #define sv_type					u.sysv_sb.s_type
 #define sv_block_size				u.sysv_sb.s_block_size
 #define sv_block_size_1				u.sysv_sb.s_block_size_1
 #define sv_block_size_bits			u.sysv_sb.s_block_size_bits
-#define sv_block_size_ratio			u.sysv_sb.s_block_size_ratio
-#define sv_block_size_ratio_bits		u.sysv_sb.s_block_size_ratio_bits
+#define sv_block_size_inc_bits			u.sysv_sb.s_block_size_inc_bits
+#define sv_block_size_dec_bits			u.sysv_sb.s_block_size_dec_bits
 #define sv_convert				u.sysv_sb.s_convert
 #define sv_kludge_symlinks			u.sysv_sb.s_kludge_symlinks
 #define sv_truncate				u.sysv_sb.s_truncate
diff -u --recursive --new-file v2.1.84/linux/include/linux/timer.h linux/include/linux/timer.h
--- v2.1.84/linux/include/linux/timer.h	Sun Jan 18 14:26:20 1998
+++ linux/include/linux/timer.h	Mon Feb  2 13:21:38 1998
@@ -2,58 +2,26 @@
 #define _LINUX_TIMER_H
 
 /*
- * DON'T CHANGE THESE!! Most of them are hardcoded into some assembly language
- * as well as being defined here.
- */
-
-/*
- * The timers are:
- *
- * BLANK_TIMER		console screen-saver timer
- *
- * BEEP_TIMER		console beep timer
- *
- * RS_TIMER		timer for the RS-232 ports
- *
- * SWAP_TIMER		timer for the background pageout daemon
- * 
- * HD_TIMER		harddisk timer
- *
- * HD_TIMER2		(atdisk2 patches)
- *
- * FLOPPY_TIMER		floppy disk timer (not used right now)
- * 
- * NET_TIMER		tcp/ip timeout timer
- *
- * COPRO_TIMER		387 timeout for buggy hardware..
- *
- * QIC02_TAPE_TIMER	timer for QIC-02 tape driver (it's not hardcoded)
- *
- * MCD_TIMER		Mitsumi CD-ROM Timer
- *
- * GSCD_TIMER		Goldstar CD-ROM Timer
+ * Old-style timers. Please don't use for any new code.
  *
+ * Numbering of these timers should be consecutive to minimize
+ * processing delays. [MJ]
  */
 
-#define BLANK_TIMER	0
-#define BEEP_TIMER	1
-#define RS_TIMER	2
-#define SWAP_TIMER	3
-
-#define HD_TIMER	16
-#define FLOPPY_TIMER	17
-#define NET_TIMER	19
-#define SOUND_TIMER	20
-#define COPRO_TIMER	21
-
-#define QIC02_TAPE_TIMER	22	/* hhb */
-#define MCD_TIMER	23
-
-#define HD_TIMER2	24
-#define GSCD_TIMER	25
-#define COMTROL_TIMER	26
+#define BLANK_TIMER	0	/* Console screen-saver */
+#define BEEP_TIMER	1	/* Console beep */
+#define RS_TIMER	2	/* RS-232 ports */
+#define SWAP_TIMER	3	/* Background pageout */
+#define BACKGR_TIMER    4	/* io_request background I/O */
+#define HD_TIMER	5	/* Old IDE driver */
+#define FLOPPY_TIMER	6	/* Floppy */
+#define QIC02_TAPE_TIMER 7	/* QIC 02 tape */
+#define MCD_TIMER	8	/* Mitsumi CDROM */
+#define GSCD_TIMER	9	/* Goldstar CDROM */
+#define COMTROL_TIMER	10	/* Comtrol serial */
+#define DIGI_TIMER	11	/* Digi serial */
 
-#define DIGI_TIMER	29
+#define COPRO_TIMER	31	/* 387 timeout for buggy hardware (boot only) */
 
 struct timer_struct {
 	unsigned long expires;
diff -u --recursive --new-file v2.1.84/linux/init/main.c linux/init/main.c
--- v2.1.84/linux/init/main.c	Fri Jan 30 11:28:10 1998
+++ linux/init/main.c	Mon Feb  2 13:07:47 1998
@@ -282,6 +282,10 @@
 extern void ipc_init(void);
 #endif
 
+#ifdef CONFIG_MD_BOOT
+extern void md_setup(char *str,int *ints) __init;
+#endif
+
 #ifdef __sparc__
 extern int serial_console;
 #endif
@@ -378,6 +382,9 @@
 #ifdef CONFIG_BLK_DEV_FD
 	{ "fd",      0x0200 },
 #endif
+#ifdef CONFIG_MD_BOOT
+	{ "md",      0x0900 },	     
+#endif     
 #ifdef CONFIG_BLK_DEV_XD
 	{ "xda",     0x0d00 },
 	{ "xdb",     0x0d40 },
@@ -419,7 +426,7 @@
 	{ NULL, 0 }
 };
 
-__initfunc(static void root_dev_setup(char *line, int *num))
+__initfunc(dev_t name_to_dev_t(char *line))
 {
 	int base = 0;
 	if (strncmp(line,"/dev/",5) == 0) {
@@ -435,7 +442,12 @@
 			dev++;
 		} while (dev->name);
 	}
-	ROOT_DEV = to_kdev_t(base + simple_strtoul(line,NULL,base?10:16));
+	return to_kdev_t(base + simple_strtoul(line,NULL,base?10:16));
+}
+
+__initfunc(static void root_dev_setup(char *line, int *num))
+{
+	ROOT_DEV = name_to_dev_t(line);
 }
 
 /*
@@ -713,6 +725,9 @@
 #endif
 #ifdef CONFIG_FTAPE
 	{ "ftape=", ftape_setup},
+#endif
+#ifdef CONFIG_MD_BOOT
+	{ "md=", md_setup},
 #endif
 	{ 0, 0 }
 };
diff -u --recursive --new-file v2.1.84/linux/kernel/ksyms.c linux/kernel/ksyms.c
--- v2.1.84/linux/kernel/ksyms.c	Fri Jan 30 11:28:10 1998
+++ linux/kernel/ksyms.c	Tue Feb  3 15:14:56 1998
@@ -143,6 +143,7 @@
 EXPORT_SYMBOL(vmtruncate);
 
 /* filesystem internal functions */
+EXPORT_SYMBOL(update_atime);
 EXPORT_SYMBOL(get_super);
 EXPORT_SYMBOL(getname);
 EXPORT_SYMBOL(putname);
@@ -203,6 +204,7 @@
 EXPORT_SYMBOL(shrink_dcache_sb);
 EXPORT_SYMBOL(shrink_dcache_parent);
 EXPORT_SYMBOL(find_inode_number);
+EXPORT_SYMBOL(is_subdir);
 
 #if !defined(CONFIG_NFSD) && defined(CONFIG_NFSD_MODULE)
 EXPORT_SYMBOL(do_nfsservctl);
diff -u --recursive --new-file v2.1.84/linux/net/ax25/Config.in linux/net/ax25/Config.in
--- v2.1.84/linux/net/ax25/Config.in	Wed Dec 31 16:00:00 1969
+++ linux/net/ax25/Config.in	Mon Feb  2 15:18:16 1998
@@ -0,0 +1,32 @@
+#
+# Amateur Radio protocols and AX.25 device configuration
+#
+# 19971130	Now in an own category to make correct compilation of the 
+#		AX.25 stuff easier...
+#		Joerg Reuter DL1BKE <jreuter@poboxes.com>
+# 19980129	Moved to net/ax25/Config.in, sourcing device drivers.
+
+mainmenu_option next_comment
+comment 'Amateur Radio support'
+bool 'Amateur Radio support' CONFIG_HAMRADIO
+
+if [ "$CONFIG_HAMRADIO" != "n" ] ; then
+  if [ "$CONFIG_NET" != "n" ] ; then
+    comment 'Packet Radio protocols'
+    tristate 'Amateur Radio AX.25 Level 2 protocol' CONFIG_AX25
+    if [ "$CONFIG_AX25" != "n" ]; then
+      bool '   AX.25 DAMA Slave support' CONFIG_AX25_DAMA_SLAVE
+#     bool '   AX.25 DAMA Master support' CONFIG_AX25_DAMA_MASTER
+      dep_tristate '   Amateur Radio NET/ROM protocol' CONFIG_NETROM $CONFIG_AX25
+      dep_tristate '   Amateur Radio X.25 PLP (Rose)' CONFIG_ROSE $CONFIG_AX25
+    fi
+
+    if [ "$CONFIG_AX25" != "n" ]; then
+      source drivers/net/hamradio/Config.in
+    fi
+  fi
+
+  source drivers/char/hfmodem/Config.in
+fi
+
+endmenu
diff -u --recursive --new-file v2.1.84/linux/net/core/dev.c linux/net/core/dev.c
--- v2.1.84/linux/net/core/dev.c	Tue Jan 20 16:45:08 1998
+++ linux/net/core/dev.c	Mon Feb  2 13:16:46 1998
@@ -49,6 +49,7 @@
  *	    Thomas Bogendoerfer :	Return ENODEV for dev_open, if there
  *					is no device open function.
  *		Andi Kleen	:	Fix error reporting for SIOCGIFCONF
+ *		Régis Duchesne	:	Fix the argument check in dev_ioctl()
  *
  */
 
@@ -1534,7 +1535,6 @@
 	return -EINVAL;
 }
 
-
 /*
  *	This function handles all "interface"-type I/O control requests. The actual
  *	'doing' part of this is dev_ifsioc above.
@@ -1566,25 +1566,19 @@
 		return dev_ifname((struct ifreq *)arg);
 	}
 
+	/*
+	 *	Fetch the interface name from the info block. 
+	 */
+
 	if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
 		return -EFAULT;
-
 	ifr.ifr_name[IFNAMSIZ-1] = 0;
-
 #ifdef CONFIG_NET_ALIAS
 	colon = strchr(ifr.ifr_name, ':');
 	if (colon)
 		*colon = 0;
 #endif
 
-	/*
-	 *	See which interface the caller is talking about. 
-	 */
-	 
-#ifdef CONFIG_KERNELD
-	dev_load(ifr.ifr_name);
-#endif	
-
 	switch(cmd) 
 	{
 		/*
@@ -1602,6 +1596,9 @@
 		case SIOCGIFMAP:
 		case SIOCGIFINDEX:
 		case SIOCGIFTXQLEN:
+#ifdef CONFIG_KERNELD
+			dev_load(ifr.ifr_name);
+#endif	
 			ret = dev_ifsioc(&ifr, cmd);
 			if (!ret) {
 #ifdef CONFIG_NET_ALIAS
@@ -1632,6 +1629,9 @@
 		case SIOCSIFTXQLEN:
 			if (!suser())
 				return -EPERM;
+#ifdef CONFIG_KERNELD
+			dev_load(ifr.ifr_name);
+#endif	
 			rtnl_lock();
 			ret = dev_ifsioc(&ifr, cmd);
 			rtnl_unlock();
@@ -1652,6 +1652,9 @@
 		default:
 			if (cmd >= SIOCDEVPRIVATE &&
 			    cmd <= SIOCDEVPRIVATE + 15) {
+#ifdef CONFIG_KERNELD
+				dev_load(ifr.ifr_name);
+#endif	
 				rtnl_lock();
 				ret = dev_ifsioc(&ifr, cmd);
 				rtnl_unlock();
@@ -1664,8 +1667,15 @@
 				if (IW_IS_SET(cmd)) {
 					if (!suser())
 						return -EPERM;
+#ifdef CONFIG_KERNELD
+					dev_load(ifr.ifr_name);
+#endif	
 					rtnl_lock();
 				}
+#ifdef CONFIG_KERNELD
+				else
+					dev_load(ifr.ifr_name);
+#endif	
 				ret = dev_ifsioc(&ifr, cmd);
 				if (IW_IS_SET(cmd))
 					rtnl_unlock();
diff -u --recursive --new-file v2.1.84/linux/net/core/scm.c linux/net/core/scm.c
--- v2.1.84/linux/net/core/scm.c	Sun Nov 30 14:00:39 1997
+++ linux/net/core/scm.c	Mon Feb  2 15:12:22 1998
@@ -17,6 +17,7 @@
 #include <linux/major.h>
 #include <linux/stat.h>
 #include <linux/socket.h>
+#include <linux/file.h>
 #include <linux/fcntl.h>
 #include <linux/net.h>
 #include <linux/interrupt.h>
@@ -44,6 +45,7 @@
 
 static __inline__ int scm_check_creds(struct ucred *creds)
 {
+	/* N.B. The test for suser should follow the credential check */
 	if (suser())
 		return 0;
 	if (creds->pid != current->pid ||
@@ -58,11 +60,10 @@
 
 static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp)
 {
-	int num;
+	int *fdp = (int*)CMSG_DATA(cmsg);
 	struct scm_fp_list *fpl = *fplp;
 	struct file **fpp;
-	int *fdp = (int*)CMSG_DATA(cmsg);
-	int i;
+	int i, num;
 
 	num = (cmsg->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr)))/sizeof(int);
 
@@ -86,41 +87,33 @@
 		return -EINVAL;
 	
 	/*
-	 *	Verify the descriptors.
+	 *	Verify the descriptors and increment the usage count.
 	 */
 	 
 	for (i=0; i< num; i++)
 	{
-		int fd;
-		
-		fd = fdp[i];
-		if (fd < 0 || fd >= NR_OPEN)
-			return -EBADF;
-		if (current->files->fd[fd]==NULL)
+		int fd = fdp[i];
+		struct file *file;
+
+		if (fd < 0 || !(file = fget(fd)))
 			return -EBADF;
-		fpp[i] = current->files->fd[fd];
+		*fpp++ = file;
+		fpl->count++;
 	}
-	
-        /* add another reference to these files */
-	for (i=0; i< num; i++, fpp++)
-		(*fpp)->f_count++;
-	fpl->count += num;
-	
 	return num;
 }
 
 void __scm_destroy(struct scm_cookie *scm)
 {
-	int i;
 	struct scm_fp_list *fpl = scm->fp;
+	int i;
 
-	if (!fpl)
-		return;
-
-	for (i=fpl->count-1; i>=0; i--)
-		close_fp(fpl->fp[i]);
-
-	kfree(fpl);
+	if (fpl) {
+		scm->fp = NULL;
+		for (i=fpl->count-1; i>=0; i--)
+			close_fp(fpl->fp[i]);
+		kfree(fpl);
+	}
 }
 
 
@@ -223,14 +216,17 @@
 	cmhdr.cmsg_level = level;
 	cmhdr.cmsg_type = type;
 	cmhdr.cmsg_len = cmlen;
-	err = copy_to_user(cm, &cmhdr, sizeof cmhdr); 
-	if (!err)
-		err = copy_to_user(CMSG_DATA(cm), data, cmlen - sizeof(struct cmsghdr));
-	if (!err) {
-		cmlen = CMSG_SPACE(len);
-		msg->msg_control += cmlen;
-		msg->msg_controllen -= cmlen;
-	}
+
+	err = -EFAULT;
+	if (copy_to_user(cm, &cmhdr, sizeof cmhdr))
+		goto out; 
+	if (copy_to_user(CMSG_DATA(cm), data, cmlen - sizeof(struct cmsghdr)))
+		goto out;
+	cmlen = CMSG_SPACE(len);
+	msg->msg_control += cmlen;
+	msg->msg_controllen -= cmlen;
+	err = 0;
+out:
 	return err;
 }
 
@@ -240,21 +236,28 @@
 
 	int fdmax = (msg->msg_controllen - sizeof(struct cmsghdr))/sizeof(int);
 	int fdnum = scm->fp->count;
-	int *cmfptr;
-	int err = 0;
-	int i;
 	struct file **fp = scm->fp->fp;
+	int *cmfptr;
+	int err = 0, i;
 
 	if (fdnum < fdmax)
 		fdmax = fdnum;
 
 	for (i=0, cmfptr=(int*)CMSG_DATA(cm); i<fdmax; i++, cmfptr++)
 	{
-		int new_fd = get_unused_fd();
-		if (new_fd < 0)
+		int new_fd;
+		err = get_unused_fd();
+		if (err < 0)
 			break;
-		current->files->fd[new_fd] = fp[i];
+		new_fd = err;
 		err = put_user(new_fd, cmfptr);
+		if (err) {
+			put_unused_fd(new_fd);
+			break;
+		}
+		/* Bump the usage count and install the file. */
+		fp[i]->f_count++;
+		current->files->fd[new_fd] = fp[i];
 	}
 
 	if (i > 0)
@@ -272,38 +275,30 @@
 			msg->msg_controllen -= cmlen;
 		}
 	}
-
-	if (err)
-		i = 0;
+	if (i < fdnum)
+		msg->msg_flags |= MSG_CTRUNC;
 
 	/*
-	 *	Dump those that don't fit.
+	 * All of the files that fit in the message have had their
+	 * usage counts incremented, so we just free the list.
 	 */
-	for ( ; i < fdnum; i++)	{
-		msg->msg_flags |= MSG_CTRUNC;
-		close_fp(fp[i]);
-	}
-
-	kfree (scm->fp);
-	scm->fp = NULL;
+	__scm_destroy(scm);
 }
 
 struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl)
 {
-	int i;
 	struct scm_fp_list *new_fpl;
+	int i;
 
 	if (!fpl)
 		return NULL;
 
-	new_fpl = kmalloc(fpl->count*sizeof(int) + sizeof(*fpl), GFP_KERNEL);
-	if (!new_fpl)
-		return NULL;
-
-	memcpy(new_fpl, fpl, fpl->count*sizeof(int) + sizeof(*fpl));
-
-	for (i=fpl->count-1; i>=0; i--)
-		fpl->fp[i]->f_count++;
+	new_fpl = kmalloc(sizeof(*fpl), GFP_KERNEL);
+	if (new_fpl) {
+		memcpy(new_fpl, fpl, sizeof(*fpl));
 
+		for (i=fpl->count-1; i>=0; i--)
+			fpl->fp[i]->f_count++;
+	}
 	return new_fpl;
 }
diff -u --recursive --new-file v2.1.84/linux/net/ipv4/ipconfig.c linux/net/ipv4/ipconfig.c
--- v2.1.84/linux/net/ipv4/ipconfig.c	Tue Jan 20 12:11:57 1998
+++ linux/net/ipv4/ipconfig.c	Mon Feb  2 13:31:51 1998
@@ -767,7 +767,7 @@
 /*
  *  Process BOOTP extension.
  */
-__initfunc(static void ic_do_bootp_ext(struct bootp_pkt *b, u8 *ext))
+__initfunc(static void ic_do_bootp_ext(u8 *ext))
 {
 #ifdef IPCONFIG_DEBUG
 	u8 *c;
@@ -864,7 +864,7 @@
 				opt = ext;
 				ext += ext[1] + 2;
 				if (ext <= end)
-					ic_do_bootp_ext(b, opt);
+					ic_do_bootp_ext(opt);
 			}
 		}
 	}
diff -u --recursive --new-file v2.1.84/linux/scripts/checkconfig.pl linux/scripts/checkconfig.pl
--- v2.1.84/linux/scripts/checkconfig.pl	Mon Jan  5 01:41:01 1998
+++ linux/scripts/checkconfig.pl	Mon Feb  2 13:43:59 1998
@@ -1,9 +1,12 @@
 #! /usr/bin/perl
 #
 # checkconfig: find uses of CONFIG_* names without matching definitions.
+# Copyright abandoned, 1998, Michael Elizabeth Chastain <mailto:mec@shout.net>.
 
 use integer;
 
+$| = 1;
+
 foreach $file (@ARGV)
 {
     # Open this file.
@@ -24,15 +27,15 @@
 	# Pick up definitions.
 	if ( m/^#/o )
 	{
-	    $iLinuxConfig      = $. if m/^#\s*include\s+<linux\/config\.h>/o;
-	    $configList{uc $1} = 1  if m/^#\s*include\s+<config\/(\S*)\.h>/o;
+	    $iLinuxConfig      = $. if m/^#\s*include\s*<linux\/config\.h>/o;
+	    $configList{uc $1} = 1  if m/^#\s*include\s*<config\/(\S*)\.h>/o;
 	    $configList{$1}    = 1  if m/^#\s*define\s+CONFIG_(\w*)/o;
 	    $configList{$1}    = 1  if m/^#\s*undef\s+CONFIG_(\w*)/o;
 	}
 
 	# Look for usages.
 	next unless m/CONFIG_/o;
-	WORD: while ( m/\bCONFIG_(\w*)/og )
+	WORD: while ( m/\bCONFIG_(\w+)/og )
 	{
 	    $fUseConfig = 1;
 	    last LINE if $iLinuxConfig;
