diff -u --recursive --new-file v1.3.69/linux/CREDITS linux/CREDITS
--- v1.3.69/linux/CREDITS	Wed Feb 28 11:49:57 1996
+++ linux/CREDITS	Thu Feb 29 09:52:26 1996
@@ -348,8 +348,8 @@
 E: nigel@nrg.org
 E: nigel@sgi.com
 D: Interrupt-driven printer driver
-S: 765 N Rengstorff Ave, Apartment 7
-S: Mountain View, California 94043-2420
+S: 120 Alley Way
+S: Mountain View, California 94040
 S: USA
 
 N: Jacques Gelinas
@@ -610,7 +610,7 @@
 S: Germany
 
 N: Mark Lord
-E: mlord@bnr.ca
+E: mlord@pobox.com
 D: Author of IDE driver (ide.c), hd.c support
 D: Triton Bus Master IDE driver
 D: Hard Disk Parameter (hdparm) utility
@@ -1039,6 +1039,14 @@
 S: 3 Ballow Crescent
 S: MacGregor A.C.T
 S: 2615 Australia
+
+N: Winfried Trümper
+E: truemper@MI.Uni-Koeln.DE
+D: German HOWTO, Enhanced German HOWTO, Crash-Kurs Linux (German)
+D: 1- or 5-days tutorials on Linux twice a year (free of charge)
+D: Linux-Workshop Köln (aka LUUG cologne, germany)
+S: Tacitusstr. 6
+S: D-50968 Köln
 
 N: Theodore Ts'o
 E: tytso@mit.edu
diff -u --recursive --new-file v1.3.69/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- v1.3.69/linux/Documentation/Configure.help	Wed Feb 28 11:49:58 1996
+++ linux/Documentation/Configure.help	Fri Mar  1 09:20:02 1996
@@ -66,16 +66,17 @@
   
 RAM disk support
 CONFIG_BLK_DEV_RAM
-  Enabling this option will allow you to use a portion of your RAM memory 
-  as a block device, so that you can make filesystems on it, read and
-  write to it and do all the other things that normal block devices can do.
-  It is usually used to load and store a copy of a minimal root file
-  system off of a floppy into RAM during the initial install of Linux.
-  Note that the kernel command line option "ramdisk=XX" is now obsolete.
-  For details, read Documentation/ramdisk.txt. If you want to compile this 
-  as a module ( = code which can be inserted in and removed from the 
-  running kernel whenever you want), say M and read Documentation/modules.txt.
-  Most normal users won't need the RAM disk functionality, and can thus say 
+  Enabling this option will allow you to use a portion of your RAM
+  memory as a block device, so that you can make filesystems on it,
+  read and write to it and do all the other things that normal block
+  devices (such as harddrives) can do.  It is usually used to load and
+  store a copy of a minimal root file system off of a floppy into RAM
+  during the initial install of Linux.  Note that the kernel command
+  line option "ramdisk=XX" is now obsolete.  For details, read
+  Documentation/ramdisk.txt. If you want to compile this as a module (
+  = code which can be inserted in and removed from the running kernel
+  whenever you want), say M and read Documentation/modules.txt.  Most
+  normal users won't need the RAM disk functionality, and can thus say
   N here.
 
 Loop device support
@@ -85,61 +86,69 @@
   burning the CD, or want to use floppy images without first writing
   them to floppy.
   This option also allows one to mount a filesystem with encryption.
+  To use these features, you will need the program losetup, available
+  via ftp (user: anonymous) from sunsite.unc.edu in the package 
+  lo.X.Y.tar.gz.
+  Note that this loop device has nothing to do with the loopback
+  device used for network connections from the machine to itself.
   Most users will answer N here.
 
 Enhanced IDE/MFM/RLL disk/cdrom/tape support
 CONFIG_BLK_DEV_IDE 
   This will use the full-featured IDE driver to control up to four IDE
-  interfaces, for a combination of up to eight IDE disk/cdrom/tape drives.
-  Useful information about large (>540MB) IDE disks, soundcard IDE ports,
-  and other topics, is all contained in drivers/block/README.ide.
-  If you have one or more IDE drives, say Y here.
-  If your system has no IDE drives, or if memory requirements are really tight,
-  you could say N here, and select the Old harddisk driver instead to save
-  about 13kB of memory in the kernel.  
-  To fine-tune IDE drive/interface parameters for improved performance,
+  interfaces, for a combination of up to eight IDE disk/cdrom/tape
+  drives.  Useful information about large (>540MB) IDE disks,
+  soundcard IDE ports, and other topics, is all contained in
+  drivers/block/README.ide.  If you have one or more IDE drives, say Y
+  here.  If your system has no IDE drives, or if memory requirements
+  are really tight, you could say N here, and select the Old harddisk
+  driver instead to save about 13kB of memory in the kernel.  To
+  fine-tune IDE drive/interface parameters for improved performance,
   look for the hdparm package at
   sunsite.unc.edu:/pub/Linux/kernel/patches/diskdrives/
 
 Old harddisk (MFM/RLL/IDE) driver
 CONFIG_BLK_DEV_HD_ONLY
   There are two drivers for MFM/RLL/IDE disks.  Most people use the
-  newer enhanced driver, but the old one is still around for two reasons.
-  Some older systems have strange timing problems and seem to work only
-  with the old driver (which itself does not work with some newer systems).
-  The other reason is that the old driver is smaller, since it lacks the
-  enhanced functionality of the new one.  This makes it a good choice
-  for systems with very tight memory restrictions, or for systems with
-  only older MFM/RLL/ESDI drives.  Choosing the old driver can save 13kB
-  or so of kernel memory.  If you are unsure, then just choose the
-  Enhanced IDE/MFM/RLL driver instead of this one.
+  newer enhanced driver, but the old one is still around for two
+  reasons.  Some older systems have strange timing problems and seem
+  to work only with the old driver (which itself does not work with
+  some newer systems).  The other reason is that the old driver is
+  smaller, since it lacks the enhanced functionality of the new one.
+  This makes it a good choice for systems with very tight memory
+  restrictions, or for systems with only older MFM/RLL/ESDI drives.
+  Choosing the old driver can save 13kB or so of kernel memory.  If
+  you are unsure, then just choose the Enhanced IDE/MFM/RLL driver
+  instead of this one.
 
 Use old disk-only driver on primary interface
 CONFIG_BLK_DEV_HD_IDE
-  There are two drivers for MFM/RLL/IDE disks.  Most people use just the
-  new enhanced driver by itself.  This option installs the old harddisk
-  driver to control the primary IDE/disk interface in the system,
-  leaving the new enhanced IDE driver take care of only the 2nd/3rd/4th
-  IDE interfaces.  Choosing this option may be useful for older systems
-  which have MFM/RLL/ESDI controller+drives at the primary port address
-  (0x1f0), along with IDE drives at the secondary/3rd/4th port addresses.
-  Normally, just say N here.
+  There are two drivers for MFM/RLL/IDE disks.  Most people use just
+  the new enhanced driver by itself.  This option installs the old
+  harddisk driver to control the primary IDE/disk interface in the
+  system, leaving the new enhanced IDE driver take care of only the
+  2nd/3rd/4th IDE interfaces.  Choosing this option may be useful for
+  older systems which have MFM/RLL/ESDI controller+drives at the
+  primary port address (0x1f0), along with IDE drives at the
+  secondary/3rd/4th port addresses.  Normally, just say N here; you
+  will then use the new driver for all 4 interfaces.
   
 Include IDE/ATAPI CDROM support
 CONFIG_BLK_DEV_IDECD
-  If you have a CDROM drive using the ATAPI protocol, say Y.
-  ATAPI is a new protocol used by IDE CDROM and TAPE drives,
-  similar to the SCSI protocol.  Most new CDROM drives use ATAPI,
-  including the NEC-260, Mitsumi FX400, Sony 55E, and just about 
-  all non-SCSI double(2X), quad(4X), and six(6X) speed drives.
-  At boot time, the TAPE drive will be identified along with other IDE devices,
-  as "hdb" or "hdc", or something similar.
-  If this is your only CDROM drive, you can say N to all other CDROM options,
-  but be sure to say Y to the ISO9660 filesystem.  Read the CDROM-HOWTO,
-  available via ftp (user: anonymous) in sunsite.unc.edu:/pub/Linux/docs/HOWTO.
-  Note that older versions of lilo (the linux boot loader) cannot properly
-  deal with IDE/ATAPI CDROMs, so install lilo-16 or higher, available
-  from sunsite.unc.edu:/pub/Linux/system/Linux-boot/lilo.
+  If you have a CDROM drive using the ATAPI protocol, say Y.  ATAPI is
+  a new protocol used by IDE CDROM and TAPE drives, similar to the
+  SCSI protocol.  Most new CDROM drives use ATAPI, including the
+  NEC-260, Mitsumi FX400, Sony 55E, and just about all non-SCSI
+  double(2X), quad(4X), and six(6X) speed drives.  At boot time, the
+  TAPE drive will be identified along with other IDE devices, as "hdb"
+  or "hdc", or something similar.
+  If this is your only CDROM drive, you can say N to all other CDROM
+  options, but be sure to say Y to the ISO9660 filesystem.  Read the
+  CDROM-HOWTO, available via ftp (user: anonymous) in
+  sunsite.unc.edu:/pub/Linux/docs/HOWTO.  Note that older versions of
+  lilo (the linux boot loader) cannot properly deal with IDE/ATAPI
+  CDROMs, so install lilo-16 or higher, available from
+  sunsite.unc.edu:/pub/Linux/system/Linux-boot/lilo.
 
 Include IDE/ATAPI TAPE support
 CONFIG_BLK_DEV_IDETAPE
@@ -188,34 +197,34 @@
   chipsets.  Most of these also require special kernel boot parameters
   to actually turn on the support at runtime.
 
-DTC-2278 chipset support
+DTC-2278 support
 CONFIG_BLK_DEV_DTC2278
   This driver is enabled at runtime using the "ide0=dtc2278" kernel
   boot parameter.  It enables support for the secondary IDE interface
   of the DTC-2278 card, and permits faster I/O speeds to be set as
   well.  See the README.ide and dtc2278.c files for more info.
 
-Holtek HT6560B chipset support
+Holtek HT6560B support
 CONFIG_BLK_DEV_HT6560B
   This driver is enabled at runtime using the "ide0=ht6560b" kernel
   boot parameter.  It enables support for the secondary IDE interface
   of the Holtek card, and permits faster I/O speeds to be set as well.
   See the README.ide and ht6560b.c files for more info.
 
-QDI QD6580 chipset support
+QDI QD6580 support
 CONFIG_BLK_DEV_QD6580
   This driver is enabled at runtime using the "ide0=qd6580" kernel
   boot parameter.  It permits faster I/O speeds to be set.
   See the README.ide and qd6580.c files for more info.
 
-UMC 8672 chipset support
+UMC 8672 support
 CONFIG_BLK_DEV_UMC8672
   This driver is enabled at runtime using the "ide0=umc8672" kernel
   boot parameter.  It enables support for the secondary IDE interface
   of the UMC-8672, and permits faster I/O speeds to be set as well.
   See the README.ide and umc8672.c files for more info.
 
-ALI M1439/M1445 chipset support
+ALI M1439/M1445 support
 CONFIG_BLK_DEV_ALI14XX
   This driver is enabled at runtime using the "ide0=ali14xx" kernel
   boot parameter.  It enables support for the secondary IDE interface
@@ -548,7 +557,7 @@
   If your compiler is mipsel-linux-gcc or mipsel-linuxelf-gcc (as
   opposed to mips-linux-gcc or mips-linuxelf-gcc), say Y here,
   otherwise N. Most MIPS machines use little-endian code, but it might
-  be necessary to run older Mips sytems, such as the Sony News and
+  be necessary to run older Mips systems, such as the Sony News and
   MIPS RC3xxx in big endian mode.
 
 Enable loadable module support
@@ -650,6 +659,7 @@
   drivers/net/README.multicast. For most people, it's safe to say N.
 
 IP: optimize as router not host
+CONFIG_IP_ROUTER
   Some Linux network drivers use a technique called copy and checksum
   to optimize host performance. For a machine which is forwarding most
   packets to another host this is however a loss. This parameter turns
@@ -848,12 +858,12 @@
   sunsite.unc.edu:/pub/Linux/docs/HOWTO). In order to do the former,
   you'll also have to say Y to "NCP filesystem support", below. To
   turn your Linux box into a fully featured Netware file server and
-  IPX router, say Y here and fetch lwared from
-  sunsite.unc.edu:/pub/Linux/system/Network/daemons/. For more
-  information, read the IPX-HOWTO in
-  sunsite.unc.edu:/pub/Linux/docs/howto. The IPX driver would enlarge
-  your kernel by about 5 kB. Unless you want to integrate your Linux
-  box with a local Novell network, say N.
+  IPX router, say Y here and fetch either lwared from
+  sunsite.unc.edu:/pub/Linux/system/Network/daemons/ or mars_nwe from
+  linux01.gwdg.de:/pub/ncpfs. For more information, read the IPX-HOWTO
+  in sunsite.unc.edu:/pub/Linux/docs/howto. The IPX driver would
+  enlarge your kernel by about 5 kB. Unless you want to integrate your
+  Linux box with a local Novell network, say N.
 
 Full internal IPX network
 CONFIG_IPX_INTERN
@@ -1759,14 +1769,9 @@
 CONFIG_NI52
   If you have a network (ethernet) card of this type, say Y and read
   the Ethernet-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. This driver is also available
-  as a module ( = code which can be inserted in and removed from the
-  running kernel whenever you want). If you want to compile it as a
-  module, say M here and read Documentation/modules.txt as well as
-  Documentation/networking/net-modules.txt. If you plan to use more
-  than one network card under linux, read the
-  Multiple-Ethernet-mini-HOWTO, available from
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO/mini.
+  sunsite.unc.edu:/pub/Linux/docs/HOWTO. If you plan to use more than
+  one network card under linux, read the Multiple-Ethernet-mini-HOWTO,
+  available from sunsite.unc.edu:/pub/Linux/docs/HOWTO/mini.
 
 NI6510 support
 CONFIG_NI65
@@ -2261,27 +2266,28 @@
 msdos fs support
 CONFIG_MSDOS_FS
   This allows you to mount MSDOS partitions of your harddrive (unless
-  they are compressed; the only way to access compressed MSDOS
-  partitions under Linux is with the DOS emulator DOSEMU, described in
-  the DOSEMU-HOWTO, available via ftp (user: anonymous) at
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO. If you intend to use dosemu
-  with a non-compressed MSDOS partition, say Y here) and MSDOS
-  floppies. This means that file access becomes transparent, i.e. the
-  MSDOS files look and behave just like all other Unix files.  Another
-  way to read and write MSDOS floppies from within Linux (but not
-  transparently) is with the mtools ("man mtools") program suite,
+  they are compressed; to access compressed MSDOS partitions under
+  Linux, you can either use the DOS emulator DOSEMU, described in the
+  DOSEMU-HOWTO, available via ftp (user: anonymous) at
+  sunsite.unc.edu:/pub/Linux/docs/HOWTO, or try dmsdosfs in
+  sunsite.unc.edu:/pub/Linux/system/Filesystems/dosfs. If you intend
+  to use dosemu with a non-compressed MSDOS partition, say Y here) and
+  MSDOS floppies. This means that file access becomes transparent,
+  i.e. the MSDOS files look and behave just like all other Unix files.
+  Another way to read and write MSDOS floppies from within Linux (but
+  not transparently) is with the mtools ("man mtools") program suite,
   which doesn't require the msdos filesystem support.  If you want to
   use umsdos, the Unix-like filesystem on top of DOS, which allows you
   to run Linux from within a DOS partition without repartitioning,
-  you'll have to say Y or M here. If your have Windows'95 or Windows NT 
-  installed on your MSDOS partitions, you should use the VFAT 
-  filesystem instead, or you will not be able to see the long filenames 
-  generated by Windows'95 / Windows NT. This option will enlarge your 
-  kernel by about 7 kB. If unsure, say Y.  If you want to compile this 
-  as a module however ( = code which can be inserted in and removed from 
-  the running kernel whenever you want), say M here and read 
-  Documentation/modules.txt. Note that the filesystem of your root 
-  partition cannot be a module.
+  you'll have to say Y or M here. If your have Windows'95 or Windows
+  NT installed on your MSDOS partitions, you should use the VFAT
+  filesystem instead, or you will not be able to see the long
+  filenames generated by Windows'95 / Windows NT. This option will
+  enlarge your kernel by about 7 kB. If unsure, say Y.  If you want to
+  compile this as a module however ( = code which can be inserted in
+  and removed from the running kernel whenever you want), say M here
+  and read Documentation/modules.txt. Note that the filesystem of your
+  root partition cannot be a module.
 
 vfat fs support
 CONFIG_VFAT_FS
@@ -2320,9 +2326,9 @@
   This is a virtual filesystem providing information about the status
   of the system. "Virtual" means that it doesn't take any space on
   your harddisk: the files are created on the fly when you access
-  them. Also, you cannot read the files with less or more: you need to
-  use cat. The filesystem is explained in the Kernel Hacker's Guide,
-  available via ftp (user: anonymous) in
+  them. Also, you cannot read the files with less: you need to use
+  more or cat. The filesystem is explained in the Kernel Hacker's
+  Guide, available via ftp (user: anonymous) in
   sunsite.unc.edu:/pub/Linux/docs/LDP and also on the proc(8) manpage
   ("man 8 proc").  This option will enlarge your kernel by about 18
   kB. It's totally cool; for example, "cat /proc/interrupts" gives
@@ -2445,12 +2451,12 @@
   used by NetWare clients to talk to file servers. It is to IPX what
   nfs is to tcp/ip, if that helps. Enabling this option allows you to
   mount NetWare file server volumes and to access them just like any
-  other Unix directory. To actually mount the filesystem, you need a
-  special mount program, as described in the IPX-HOWTO on
-  sunsite.unc.edu:/pub/Linux/docs/howto.  If you want to compile this
-  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.
+  other Unix directory. For details, please read the file
+  Documentation/filesystems/ncpfs.txt in the kernel source and the
+  IPX-HOWTO on sunsite.unc.edu:/pub/Linux/docs/howto.  If you want to
+  compile this 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.
 
 Standard/generic serial support
 CONFIG_SERIAL
@@ -2492,7 +2498,8 @@
   running kernel whenever you want), say M here and read
   Documentation/modules.txt.
 
-CONFIG_ISTALLION n
+Stallion EC8/64, ONboard, Brumby support
+CONFIG_ISTALLION
   If you have an EasyConnection 8/64, ONboard, Brumby or Stallion
   serial multiport card, say Y here. Make sure to read
   drivers/char/README.stallion. To compile it as a module ( = code
@@ -2585,20 +2592,6 @@
   plugging in a COM port (9 or 25 pins) which is supported
   automatically.
 
-Selection (cut and paste for virtual consoles)
-CONFIG_SELECTION
-  This allows you to use your mouse for moving text on a Linux console
-  or even between several virtual consoles. Read about it with "man
-  selection". You also need it to run gpm ("general purpose mouse")
-  which is a superset of selection. This is explained in the
-  Busmouse-HOWTO, available via ftp (user: anonymous) in
-  sunsite.unc.edu:/pub/Linux/docs/HOWTO, although selection works fine
-  with serial mice, too. Most people say Y unless they run mainly the
-  X Window System, which has its own cut-and-paste mechanism. Enabling
-  this option enlarges your kernel by about 1 kB. Newer kernels
-  contain this code by default and don't have this config option
-  anymore. 
-
 QIC-02 tape support
 CONFIG_QIC02_TAPE
   If you have a non-SCSI tape drive like that, say Y.
@@ -2652,45 +2645,58 @@
 Enable APM features
 CONFIG_APM_DO_ENABLE
   Enable APM features at boot time.  From page 36 of the APM BIOS
-  specification: "When disabled, the APM BIOS does not automatically power
-  manage devices, enter the Standby State, enter the Suspend State, or take
-  power saving steps in response to CPU Idle calls."  This driver will make
-  CPU Idle calls when Linux is idle (unless this feature is turned off --
-  see below).  This should always save battery power, but more complicated
-  APM features will be dependent on your BIOS implementation.  You may need
-  to turn this option off if your computer hangs at boot time when using
-  APM support, or if it beeps continuously instead of suspending.  Turn
-  this off if you have a NEC UltraLite Versa 33/C or a Toshiba T400CDT.
-  This is off by default since most machines do fine without this feature.
+  specification: "When disabled, the APM BIOS does not automatically
+  power manage devices, enter the Standby State, enter the Suspend
+  State, or take power saving steps in response to CPU Idle calls."
+  This driver will make CPU Idle calls when Linux is idle (unless this
+  feature is turned off -- see below).  This should always save
+  battery power, but more complicated APM features will be dependent
+  on your BIOS implementation.  You may need to turn this option off
+  if your computer hangs at boot time when using APM support, or if it
+  beeps continuously instead of suspending.  Turn this off if you have
+  a NEC UltraLite Versa 33/C or a Toshiba T400CDT.  This is off by
+  default since most machines do fine without this feature.
 
 Watchdog Timer Support 
 CONFIG_WATCHDOG
   If you enable this option and create a character special file
   /dev/watchdog with major number 10 and minor number 130 using mknod
-  ("man mknod"), you will get a software watchdog, i.e.: subsequently
-  opening the file and failing to write to it for longer than 1 minute
-  will result in rebooting the machine. This could be useful for a
+  ("man mknod"), you will get a watchdog, i.e.: subsequently opening
+  the file and failing to write to it for longer than 1 minute will
+  result in rebooting the machine. This could be useful for a
   networked machine that needs to come back online as fast as possible
-  after a lock-up. For details, read Documentation/watchdog.txt in the
-  kernel source. If unsure, say N.
+  after a lock-up. There's a watchdog implementation entirely in
+  software (which sometimes fail to reboot the machine) and a driver
+  for hardware watchdog boards, which are more robust and can also
+  keep track of the temperature inside your computer. For details,
+  read Documentation/watchdog.txt in the kernel source. If unsure, say
+  N.
 
 Disable watchdog shutdown on close
 CONFIG_WATCHDOG_NOWAYOUT
   The default watchdog behaviour is to stop the timer if the process
-  managing it closes the file. Its always remotely possible that this
-  process might get killed. In NOWAYOUT mode you cannot stop the watchdog
-  once its begun.
+  managing it closes the file /dev/watchdog. It's always remotely
+  possible that this process might get killed. If you enable this
+  option, the watchdog cannot be stopped once it has been started.
 
 WDT Watchdog timer
 CONFIG_WDT
-  Drivers for the WDT watchdog timer cards. These are hardware timer boards
-  that physically pull the power on and off to recover crashed machines.
-  Brutal but _very_ effective.
+  If you have a WDT500P or WDT501P watchdog board, say Y here,
+  otherwise N. It is not possible to probe for this board, which means
+  that you have to set the IO port and IRQ it uses in the kernel
+  source at the top of drivers/char/wdt.c. If you want to compile this
+  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.
 
 WDT501 features
 CONFIG_WDT_501
-  Enable the onboard thermometer and voltage monitors on the extended (501)
-  card.
+  Saying Y here and creating a character special file /dev/temperature
+  with major number 10 and minor number 131 ("man mknod") will give
+  you a thermometer inside your computer: reading from
+  /dev/temperature yields one byte, the temperature in degrees
+  Fahrenheit. This works only if you have a WDT501P watchdog board
+  installed.
 
 Fan Tachometer
 CONFIG_WDT_501_FAN
@@ -2698,26 +2704,27 @@
   tachometer actually set up.
 
 Software Watchdog
-CONFIG_SOFT_WATDHDOG
-  A software monitoring watchdog. This will fail to reboot your system from
-  some situations that the hardware watchdog will recover from. Equally its
-  a lot cheaper to install.
+CONFIG_SOFT_WATCHDOG
+  A software monitoring watchdog. This will fail to reboot your system
+  from some situations that the hardware watchdog will recover
+  from. Equally it's a lot cheaper to install.
 
 Do CPU IDLE calls
 CONFIG_APM_CPU_IDLE
-  Enable calls to APM CPU Idle/CPU Busy inside the kernel's idle loop.  On
-  some machines, this can activate improved power savings, such as a slowed
-  CPU clock rate, when the machine is idle.  These idle call is made after
-  the idle loop has run for some length of time (e.g., 333 mS).  On some
-  machines, this will cause a hang at boot time or whenever the CPU becomes
-  idle.  (On machines with more than one CPU, this option does nothing.)
+  Enable calls to APM CPU Idle/CPU Busy inside the kernel's idle loop.
+  On some machines, this can activate improved power savings, such as
+  a slowed CPU clock rate, when the machine is idle.  These idle call
+  is made after the idle loop has run for some length of time (e.g.,
+  333 mS).  On some machines, this will cause a hang at boot time or
+  whenever the CPU becomes idle.  (On machines with more than one CPU,
+  this option does nothing.)
 
 Black display
 CONFIG_APM_DISPLAY_BLANK
-  Enable console blanking using the APM.  Some laptops can use this to turn
-  off the LCD backlight when the VC screen blanker blanks the screen.  Note
-  that this is only used by the VC screen blanker, and won't turn off the
-  backlight when using X11.
+  Enable console blanking using the APM.  Some laptops can use this to
+  turn off the LCD backlight when the VC screen blanker blanks the
+  screen.  Note that this is only used by the VC screen blanker, and
+  won't turn off the backlight when using X11.
 
 Sound card support
 CONFIG_SOUND
@@ -2762,48 +2769,50 @@
 
 ISDN subsystem
 CONFIG_ISDN
-  This allows you to use an ISDN-card for networking connections and as
-  dialin/out device. The isdn-tty's have a builtin AT-compatible modem
-  emulator. Network devices support autodial, channel-bundling, callback
-  and caller-authentication without having a daemon running. A reduced T.70
-  protocol is supported with tty's suitable for german BTX. Currently Cards
-  by Teles and compatibles and ICN are supported. On D-Channel, the protocols
-  EDSS1 and 1TR6 are supported. See Documentation/isdn/README for more
-  information.
+  This allows you to use an ISDN-card for networking connections and
+  as dialin/out device. The isdn-tty's have a built in AT-compatible
+  modem emulator. Network devices support autodial, channel-bundling,
+  callback and caller-authentication without having a daemon
+  running. A reduced T.70 protocol is supported with tty's suitable
+  for German BTX. Currently Cards by Teles and compatibles and ICN are
+  supported. On D-Channel, the protocols EDSS1 and 1TR6 are
+  supported. See Documentation/isdn/README for more information.
 
 Support synchronous PPP
 CONFIG_ISDN_PPP
-  This enables synchronous PPP via ISDN. This protocol is used by Cisco
-  or Sun for example. You will need a special version of pppd (called ipppd)
-  for using this feature. See Documentation/isdn/README.syncppp for more
-  information.
+  This enables synchronous PPP via ISDN. This protocol is used by
+  Cisco or Sun for example. You will need a special version of pppd
+  (called ipppd) for using this feature. See
+  Documentation/isdn/README.syncppp for more information.
 
-Sypport generic MP (RFC 1717)
+Support generic MP (RFC 1717)
 CONFIG_ISDN_MPP
-  With synchronous PPP enabled, it is possible to increase throughput by
-  bundling several ISDN-connections, using this protocol. See
+  With synchronous PPP enabled, it is possible to increase throughput
+  by bundling several ISDN-connections, using this protocol. See
   Documentation/isdn/README.syncppp for more information.
 
 Use VJ-compression with synchronous PPP
 CONFIG_ISDN_PPP_VJ
-  This enables Van Jacobson headercompression for synchronous PPP.
+  This enables Van Jacobson header compression for synchronous PPP.
 
 ICN B1 and B2 support
 CONFIG_ISDN_DRV_ICN
-  This enables support for two kinds of ISDN-cards made by a german company
-  called ICN. 1B is the standard version for a single ISDN line with two
-  B-channels, 2B supports two ISDN lines. For running this card, additional
-  firmware is necessary, which has to be downloaded into the card using
-  a utility which is distributed separately.
-  See Documentation/isdn/README and README.icn for more information.
+  This enables support for two kinds of ISDN-cards made by a German
+  company called ICN. 1B is the standard version for a single ISDN
+  line with two B-channels, 2B supports two ISDN lines. For running
+  this card, additional firmware is necessary, which has to be
+  downloaded into the card using a utility which is distributed
+  separately.  See Documentation/isdn/README and README.icn for more
+  information.
 
 Teles, NICCY1016PC, Creatix support
 CONFIG_ISDN_DRV_TELES
-  This enables support for the Teles ISDN-cards S0-16.0, S0-16.3, S0-8 and
-  many compatibles. By default, the driver is configured to support
-  a 16.0-type using EDSS1-protocol. See Documentation/isdn/README
-  on how to configure it using 16.3, a different D-channel protocol, or
-  non-standard irq/port/shmem settings.
+  This enables support for the Teles ISDN-cards S0-16.0, S0-16.3, S0-8
+  and many compatibles. By default, the driver is configured to
+  support a 16.0-type using EDSS1-protocol. See
+  Documentation/isdn/README on how to configure it using 16.3, a
+  different D-channel protocol, or non-standard irq/port/shmem
+  settings.
 
 # need an empty line after last entry, for sed script in Configure.
 
@@ -2862,6 +2871,8 @@
 # LocalWords:  wdt hdb hdc bugfix SiS vlb Acculogic CSA DTC dtc Holtek ht QDI
 # LocalWords:  QD qd UMC umc ALI ali lena fnet fr homepage azstarnet axplinux
 # LocalWords:  Avanti XL AlphaStations Jensen DECpc AXPpci UDB Cabriolet MCA RC
-# LocalWords:  AlphaPC uwaterloo cpbeaure mca AOUT OUTput PPro sipx gwdg
+# LocalWords:  AlphaPC uwaterloo cpbeaure mca AOUT OUTput PPro sipx gwdg lo nwe
 # LocalWords:  Keepalive linefill RELCOM keepalive analogue CDR conf CDI INIT
-# LocalWords:  OPTi isp irq noisp VFAT vfat NTFS
+# LocalWords:  OPTi isp irq noisp VFAT vfat NTFS losetup dmsdosfs dosfs ISDN MP
+# LocalWords:  NOWAYOUT behaviour dialin isdn callback BTX Teles ICN EDSS Cisco
+# LocalWords:  ipppd syncppp RFC MPP VJ downloaded icn NICCY Creatix shmem
diff -u --recursive --new-file v1.3.69/linux/Documentation/devices.tex linux/Documentation/devices.tex
--- v1.3.69/linux/Documentation/devices.tex	Tue Feb 20 14:37:22 1996
+++ linux/Documentation/devices.tex	Wed Feb 28 08:44:02 1996
@@ -42,7 +42,7 @@
 %
 \title{{\bf Linux Allocated Devices}}
 \author{Maintained by H. Peter Anvin $<$hpa@storm.net$>$}
-\date{Last revised: February 17, 1996}
+\date{Last revised: February 24, 1996}
 \maketitle
 %
 \noindent
@@ -88,6 +88,7 @@
 \major{ 5}{}{char }{Alternate TTY devices}
 \major{ 6}{}{char }{Parallel printer devices}
 \major{ 7}{}{char }{Virtual console access devices}
+\major{  }{}{block}{Loopback devices}
 \major{ 8}{}{block}{SCSI disk devices}
 \major{ 9}{}{char }{SCSI tape devices}
 \major{  }{}{block}{Metadisk (RAID) devices}
@@ -147,8 +148,9 @@
 \major{37}{}{char }{IDE tape}
 \major{  }{}{block}{Zorro II ramdisk}
 \major{38}{}{char }{Myricom PCI Myrinet board}
-\major{39}{--40}{}{Unallocated}
-\major{41}{}{char}{Yet Another Micro Monitor}
+\major{39}{}{char }{ML-16P experimental I/O board}
+\major{40}{}{}{Unallocated}
+\major{41}{}{char }{Yet Another Micro Monitor}
 \major{42}{}{}{Demo/sample use}
 \major{43}{}{char }{isdn4linux virtual modem}
 \major{44}{}{char }{isdn4linux virtual modem -- alternate devices}
@@ -350,6 +352,17 @@
 \noindent
 NOTE: These devices permit both read and write access.
 
+\major{  }{}{block}{Loopback devices}
+	\minor{0}{/dev/loop0}{First loopback device}
+	\minor{1}{/dev/loop1}{Second loopback device}
+	\minordots
+\end{devicelist}
+
+\noindent
+The loopback devices are used to mount filesystems not associated with
+block devices.  The binding to the loopback devices is usually handled
+by mount(1).
+
 \begin{devicelist}
 \major{ 8}{}{block}{SCSI disk devices}
 	\minor{0}{/dev/sda}{First SCSI disk whole disk}
@@ -870,7 +883,28 @@
 networking device.
 
 \begin{devicelist}
-\major{39}{--40}{}{Unallocated}
+\major{39}{}{char }{ML-16P experimental I/O board}
+	\minor{0}{/dev/ml16pa-a0}{First card, first analog channel}
+	\minor{1}{/dev/ml16pa-a1}{First card, second analog channel}
+	\minordots
+	\minor{15}{/dev/ml16pa-a15}{First card, 16th analog channel}
+	\minor{16}{/dev/ml16pa-d}{First card, digital lines}
+	\minor{17}{/dev/ml16pa-c0}{First card, first counter/timer}
+	\minor{18}{/dev/ml16pa-c1}{First card, second counter/timer}
+	\minor{19}{/dev/ml16pa-c2}{First card, third counter/timer}
+	\minor{32}{/dev/ml16pb-a0}{Second card, first analog channel}
+	\minor{33}{/dev/ml16pb-a1}{Second card, second analog channel}
+	\minordots
+	\minor{47}{/dev/ml16pb-a15}{Second card, 16th analog channel}
+	\minor{48}{/dev/ml16pb-d}{Second card, digital lines}
+	\minor{49}{/dev/ml16pb-c0}{Second card, first counter/timer}
+	\minor{50}{/dev/ml16pb-c1}{Second card, second counter/timer}
+	\minor{51}{/dev/ml16pb-c2}{Second card, third counter/timer}
+	\minordots
+\end{devicelist}
+
+\begin{devicelist}
+\major{40}{}{}{Unallocated}
 \end{devicelist}
 
 \begin{devicelist}
diff -u --recursive --new-file v1.3.69/linux/Documentation/devices.txt linux/Documentation/devices.txt
--- v1.3.69/linux/Documentation/devices.txt	Tue Feb 20 14:37:22 1996
+++ linux/Documentation/devices.txt	Wed Feb 28 08:44:10 1996
@@ -2,7 +2,7 @@
 
 	     Maintained by H. Peter Anvin <hpa@storm.net>
 
-		   Last revised: February 17, 1996
+		   Last revised: February 24, 1996
 
 This list is the successor to Rick Miller's Linux Device List, which
 he stopped maintaining when he got busy with other things in 1993.  It
@@ -187,6 +187,15 @@
 	
 		NOTE: These devices permit both read and write access.
 
+    block	Loopback devices
+		  0 = /dev/loop0	First loopback device
+		  1 = /dev/loop1	Second loopback device
+		      ...
+
+		The loopback devices are used to mount filesystems not
+		associated with block devices.  The binding to the
+		loopback devices is usually handled by mount(1).
+
   8 block	SCSI disk devices
     		  0 = /dev/sda		First SCSI disk whole disk
 		 16 = /dev/sdb		Second SCSI disk whole disk
@@ -589,7 +598,25 @@
 		and "user level packet I/O."  This board is also
 		accessible as a standard networking "eth" device.
 
- 39-40		UNALLOCATED
+ 39 char	ML-16P experimental I/O board
+		  0 = /dev/ml16pa-a0	First card, first analog channel
+		  1 = /dev/ml16pa-a1	First card, second analog channel
+		      ...
+		 15 = /dev/ml16pa-a15	First card, 16th analog channel
+		 16 = /dev/ml16pa-d	First card, digital lines
+		 17 = /dev/ml16pa-c0	First card, first counter/timer
+		 18 = /dev/ml16pa-c1	First card, second counter/timer
+		 19 = /dev/ml16pa-c2	First card, third counter/timer
+		 32 = /dev/ml16pb-a0	Second card, first analog channel
+		 33 = /dev/ml16pb-a1	Second card, second analog channel
+		      ...
+		 47 = /dev/ml16pb-a15	Second card, 16th analog channel
+		 48 = /dev/ml16pb-d	Second card, digital lines
+		 49 = /dev/ml16pb-c0	Second card, first counter/timer
+		 50 = /dev/ml16pb-c1	Second card, second counter/timer
+		 51 = /dev/ml16pb-c2	Second card, third counter/timer
+
+ 40		UNALLOCATED
 
  41		Yet Another Micro Monitor
 		  0 = /dev/yamm		Yet Another Micro Monitor
diff -u --recursive --new-file v1.3.69/linux/Documentation/isdn/README.teles linux/Documentation/isdn/README.teles
--- v1.3.69/linux/Documentation/isdn/README.teles	Wed Feb 28 11:49:59 1996
+++ linux/Documentation/isdn/README.teles	Wed Feb 28 08:32:54 1996
@@ -27,7 +27,7 @@
 
 Remember, that according to the new strategy for accessing Low-level-drivers
 from within isdn4linux you should also define a driver-id while doing
-insmod: Simply append id=<SomeString> to the insmod-commandline. This
+insmod: Simply append teles_id=<SomeString> to the insmod-commandline. This
 string MUST NOT start with a digit or a small 'x'!
 
 At this point you can run a 'cat /dev/isdnctrl0' and view debugging 
diff -u --recursive --new-file v1.3.69/linux/MAINTAINERS linux/MAINTAINERS
--- v1.3.69/linux/MAINTAINERS	Wed Feb 28 11:49:59 1996
+++ linux/MAINTAINERS	Fri Mar  1 07:22:49 1996
@@ -55,7 +55,7 @@
 	Odd Fixes:	It has a maintainer but they don't have time to do
 			much other than throw the odd patch in. See below..
 	Orphan:		No current maintainer [but maybe you could take the 
-			role as you write your new driver].
+			role as you write your new code].
 	Obsolete:	Ex code. Something tagged obsolete generally means
 			its been replaced by a better system and you should
 			be using that.
@@ -82,6 +82,12 @@
 P:	Alan Cox [for the moment]
 M:	net-patches@lxorguk.ukuu.org.uk
 L:	linux-ipx@vger.rutgers.edu [will change]
+S:	Maintained
+
+ISDN SUBSYSTEM
+P:	Fritz Elfert
+M:	fritz@wuemaus.franken.de
+L:	isdn4linux@hub-wue.franken.de
 S:	Maintained
 
 NETROM NETWORK LAYER
diff -u --recursive --new-file v1.3.69/linux/Makefile linux/Makefile
--- v1.3.69/linux/Makefile	Wed Feb 28 11:49:59 1996
+++ linux/Makefile	Wed Feb 28 08:05:31 1996
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 3
-SUBLEVEL = 69
+SUBLEVEL = 70
 
 ARCH = i386
 
diff -u --recursive --new-file v1.3.69/linux/Rules.make linux/Rules.make
--- v1.3.69/linux/Rules.make	Sat Feb 17 16:02:44 1996
+++ linux/Rules.make	Wed Feb 28 08:44:10 1996
@@ -101,7 +101,7 @@
 #
 ALL_MOBJS = $(MX_OBJS) $(M_OBJS)
 ifneq "$(strip $(ALL_MOBJS))" ""
-PDWN=$(shell /bin/sh $(TOPDIR)/scripts/pathdown.sh)
+PDWN=$(shell $(CONFIG_SHELL) $(TOPDIR)/scripts/pathdown.sh)
 endif
 modules: $(ALL_MOBJS) dummy
 ifdef MOD_SUB_DIRS
diff -u --recursive --new-file v1.3.69/linux/arch/alpha/config.in linux/arch/alpha/config.in
--- v1.3.69/linux/arch/alpha/config.in	Sat Feb 17 16:02:44 1996
+++ linux/arch/alpha/config.in	Wed Feb 28 11:49:20 1996
@@ -33,6 +33,7 @@
 	 EB66		CONFIG_ALPHA_EB66		\
 	 EB66+		CONFIG_ALPHA_EB66P		\
 	 EB64+		CONFIG_ALPHA_EB64P		\
+	 EB164		CONFIG_ALPHA_EB164		\
 	 Jensen		CONFIG_ALPHA_JENSEN		\
 	 Noname		CONFIG_ALPHA_NONAME		\
 	 Platform2000	CONFIG_ALPHA_P2K" Cabriolet
@@ -48,6 +49,12 @@
 	bool 'Using SRM as bootloader' CONFIG_ALPHA_SRM
 	define_bool CONFIG_PCI y
 	define_bool CONFIG_ALPHA_APECS y
+fi
+if [ "$CONFIG_ALPHA_EB164" = "y" ]
+then
+	define_bool CONFIG_PCI y
+	define_bool CONFIG_ALPHA_EV5 y
+	define_bool CONFIG_ALPHA_ALCOR y
 fi
 # This needs to be defined for all EV4 and EV45 CPUs:
 define_bool CONFIG_ALPHA_NEED_ROUNDING_EMULATION y
diff -u --recursive --new-file v1.3.69/linux/arch/alpha/defconfig linux/arch/alpha/defconfig
--- v1.3.69/linux/arch/alpha/defconfig	Wed Feb 28 11:49:59 1996
+++ linux/arch/alpha/defconfig	Wed Feb 28 15:48:17 1996
@@ -13,16 +13,17 @@
 #
 CONFIG_NATIVE=y
 # CONFIG_ALPHA_AVANTI is not set
-# CONFIG_ALPHA_JENSEN is not set
-# CONFIG_ALPHA_NONAME is not set
 # CONFIG_ALPHA_CABRIOLET is not set
-# CONFIG_ALPHA_P2K is not set
 # CONFIG_ALPHA_EB66 is not set
 # CONFIG_ALPHA_EB66P is not set
-CONFIG_ALPHA_EB64P=y
-# CONFIG_ALPHA_SRM is not set
+# CONFIG_ALPHA_EB64P is not set
+CONFIG_ALPHA_EB164=y
+# CONFIG_ALPHA_JENSEN is not set
+# CONFIG_ALPHA_NONAME is not set
+# CONFIG_ALPHA_P2K is not set
 CONFIG_PCI=y
-CONFIG_ALPHA_APECS=y
+CONFIG_ALPHA_EV5=y
+CONFIG_ALPHA_ALCOR=y
 CONFIG_ALPHA_NEED_ROUNDING_EMULATION=y
 # CONFIG_SERIAL_ECHO is not set
 # CONFIG_TGA_CONSOLE is not set
@@ -33,24 +34,19 @@
 # CONFIG_BINFMT_ELF is not set
 
 #
-# Block devices
+# Floppy, IDE, and other block devices
 #
 CONFIG_BLK_DEV_FD=y
-# CONFIG_BLK_DEV_RAM is not set
-CONFIG_ST506=y
+# CONFIG_BLK_DEV_IDE is not set
 
 #
 # Please see drivers/block/README.ide for help/info on IDE drives
 #
-# CONFIG_BLK_DEV_HD is not set
-CONFIG_BLK_DEV_IDE=y
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_RZ1000 is not set
-# CONFIG_BLK_DEV_CMD640 is not set
-# CONFIG_BLK_DEV_TRITON is not set
-# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_BLK_DEV_HD_ONLY is not set
+CONFIG_BLK_DEV_RAM=y
+# CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_XD is not set
+# CONFIG_BLK_DEV_MD is not set
 
 #
 # Networking options
diff -u --recursive --new-file v1.3.69/linux/arch/alpha/kernel/Makefile linux/arch/alpha/kernel/Makefile
--- v1.3.69/linux/arch/alpha/kernel/Makefile	Fri Jan 26 01:37:05 1996
+++ linux/arch/alpha/kernel/Makefile	Wed Feb 28 11:38:00 1996
@@ -16,7 +16,7 @@
 
 O_TARGET := kernel.o
 O_OBJS   := entry.o traps.o process.o osf_sys.o irq.o signal.o setup.o \
-	    bios32.o ptrace.o time.o apecs.o lca.o ksyms.o
+	    bios32.o ptrace.o time.o apecs.o lca.o alcor.o ksyms.o
 
 all: kernel.o head.o
 
diff -u --recursive --new-file v1.3.69/linux/arch/alpha/kernel/alcor.c linux/arch/alpha/kernel/alcor.c
--- v1.3.69/linux/arch/alpha/kernel/alcor.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/alpha/kernel/alcor.c	Wed Feb 28 15:48:17 1996
@@ -0,0 +1,472 @@
+/*
+ * Code common to all ALCOR chips.
+ *
+ * Written by David A Rusling (david.rusling@reo.mts.dec.com).
+ * December 1995.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/bios32.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/hwrpb.h>
+#include <asm/ptrace.h>
+#include <asm/mmu_context.h>
+
+extern struct hwrpb_struct *hwrpb;
+extern asmlinkage void wrmces(unsigned long mces);
+extern int alpha_sys_type;
+/*
+ * BIOS32-style PCI interface:
+ */
+
+#ifdef CONFIG_ALPHA_ALCOR
+
+#ifdef DEBUG 
+# define DBG(args)	printk args
+#else
+# define DBG(args)
+#endif
+
+#define vulp	volatile unsigned long *
+#define vuip	volatile unsigned int  *
+
+static volatile unsigned int ALCOR_mcheck_expected = 0;
+static volatile unsigned int ALCOR_mcheck_taken = 0;
+static unsigned long ALCOR_jd, ALCOR_jd1, ALCOR_jd2;
+
+
+/*
+ * Given a bus, device, and function number, compute resulting
+ * configuration space address and setup the ALCOR_HAXR2 register
+ * accordingly.  It is therefore not safe to have concurrent
+ * invocations to configuration space access routines, but there
+ * really shouldn't be any need for this.
+ *
+ * Type 0:
+ *
+ *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
+ *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | | |D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|0|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ *	31:11	Device select bit.
+ * 	10:8	Function number
+ * 	 7:2	Register number
+ *
+ * Type 1:
+ *
+ *  3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
+ *  3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ *	31:24	reserved
+ *	23:16	bus number (8 bits = 128 possible buses)
+ *	15:11	Device number (5 bits)
+ *	10:8	function number
+ *	 7:2	register number
+ *  
+ * Notes:
+ *	The function number selects which function of a multi-function device 
+ *	(e.g., scsi and ethernet).
+ * 
+ *	The register selects a DWORD (32 bit) register offset.  Hence it
+ *	doesn't get shifted by 2 bits as we want to "drop" the bottom two
+ *	bits.
+ */
+static int mk_conf_addr(unsigned char bus, unsigned char device_fn,
+			unsigned char where, unsigned long *pci_addr,
+			unsigned char *type1)
+{
+	unsigned long addr;
+
+	DBG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, pci_addr=0x%p, type1=0x%p)\n",
+	     bus, device_fn, where, pci_addr, type1));
+
+	if (bus == 0) {
+		int device = device_fn >> 3;
+
+		/* type 0 configuration cycle: */
+
+		if (device > 20) {
+			DBG(("mk_conf_addr: device (%d) > 20, returning -1\n", device));
+			return -1;
+		}
+
+		*type1 = 0;
+		addr = (device_fn << 8) | (where);
+	} else {
+		/* type 1 configuration cycle: */
+		*type1 = 1;
+		addr = (bus << 16) | (device_fn << 8) | (where);
+	}
+	*pci_addr = addr;
+	DBG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
+	return 0;
+}
+
+
+static unsigned int conf_read(unsigned long addr, unsigned char type1)
+{
+	unsigned long flags;
+	unsigned int stat0, value;
+	unsigned int cia_cfg = 0; /* to keep gcc quiet */
+
+	save_flags(flags);	/* avoid getting hit by machine check */
+	cli();
+
+	DBG(("conf_read(addr=0x%lx, type1=%d)\n", addr, type1));
+
+	/* reset status register to avoid losing errors: */
+	stat0 = *((volatile unsigned int *)ALCOR_IOC_CIA_ERR);
+	*((volatile unsigned int *)ALCOR_IOC_CIA_ERR) = stat0;
+	mb();
+	DBG(("conf_read: ALCOR CIA ERR was 0x%x\n", stat0));
+	/* if Type1 access, must set CIA CFG */
+	if (type1) {
+		cia_cfg = *((unsigned int *)ALCOR_IOC_CFG);
+		mb();
+		*((unsigned int *)ALCOR_IOC_CFG) = cia_cfg | 1;
+		DBG(("conf_read: TYPE1 access\n"));
+	}
+
+	draina();
+	ALCOR_mcheck_expected = 1;
+	ALCOR_mcheck_taken = 0;
+	mb();
+	/* access configuration space: */
+	value = *((volatile unsigned int *)addr);
+	mb();
+	mb();
+	if (ALCOR_mcheck_taken) {
+		ALCOR_mcheck_taken = 0;
+		value = 0xffffffffU;
+		mb();
+	}
+	ALCOR_mcheck_expected = 0;
+	mb();
+	/*
+	 * david.rusling@reo.mts.dec.com.  This code is needed for the
+	 * EB64+ as it does not generate a machine check (why I don't
+	 * know).  When we build kernels for one particular platform
+	 * then we can make this conditional on the type.
+	 */
+#if 1
+	draina();
+
+	/* now look for any errors */
+	stat0 = *((unsigned int *)ALCOR_IOC_CIA_ERR);
+	DBG(("conf_read: ALCOR CIA ERR after read 0x%x\n", stat0));
+	if (stat0 & 0x8280U) { /* is any error bit set? */
+		/* if not NDEV, print status */
+		if (!(stat0 & 0x0080)) {
+			printk("ALCOR.c:conf_read: got stat0=%x\n", stat0);
+		}
+
+		/* reset error status: */
+		*((volatile unsigned long *)ALCOR_IOC_CIA_ERR) = stat0;
+		mb();
+		wrmces(0x7);			/* reset machine check */
+		value = 0xffffffff;
+	}
+#endif
+
+	/* if Type1 access, must reset IOC CFG so normal IO space ops work */
+	if (type1) {
+		*((unsigned int *)ALCOR_IOC_CFG) = cia_cfg & ~1;
+		mb();
+	}
+
+	DBG(("conf_read(): finished\n"));
+
+	restore_flags(flags);
+	return value;
+}
+
+
+static void conf_write(unsigned long addr, unsigned int value, unsigned char type1)
+{
+	unsigned long flags;
+	unsigned int stat0;
+	unsigned int cia_cfg = 0; /* to keep gcc quiet */
+
+	save_flags(flags);	/* avoid getting hit by machine check */
+	cli();
+
+	/* reset status register to avoid losing errors: */
+	stat0 = *((volatile unsigned int *)ALCOR_IOC_CIA_ERR);
+	*((volatile unsigned int *)ALCOR_IOC_CIA_ERR) = stat0;
+	mb();
+	DBG(("conf_write: ALCOR CIA ERR was 0x%x\n", stat0));
+	/* if Type1 access, must set CIA CFG */
+	if (type1) {
+		cia_cfg = *((unsigned int *)ALCOR_IOC_CFG);
+		mb();
+		*((unsigned int *)ALCOR_IOC_CFG) = cia_cfg | 1;
+		DBG(("conf_read: TYPE1 access\n"));
+	}
+
+	draina();
+	ALCOR_mcheck_expected = 1;
+	mb();
+	/* access configuration space: */
+	*((volatile unsigned int *)addr) = value;
+	mb();
+	mb();
+	ALCOR_mcheck_expected = 0;
+	mb();
+	/*
+	 * david.rusling@reo.mts.dec.com.  This code is needed for the
+	 * EB64+ as it does not generate a machine check (why I don't
+	 * know).  When we build kernels for one particular platform
+	 * then we can make this conditional on the type.
+	 */
+#if 1
+	draina();
+
+	/* now look for any errors */
+	stat0 = *((unsigned int *)ALCOR_IOC_CIA_ERR);
+	DBG(("conf_write: ALCOR CIA ERR after write 0x%x\n", stat0));
+	if (stat0 & 0x8280U) { /* is any error bit set? */
+		/* if not NDEV, print status */
+		if (!(stat0 & 0x0080)) {
+			printk("ALCOR.c:conf_read: got stat0=%x\n", stat0);
+		}
+
+		/* reset error status: */
+		*((volatile unsigned long *)ALCOR_IOC_CIA_ERR) = stat0;
+		mb();
+		wrmces(0x7);			/* reset machine check */
+		value = 0xffffffff;
+	}
+#endif
+
+	/* if Type1 access, must reset IOC CFG so normal IO space ops work */
+	if (type1) {
+		*((unsigned int *)ALCOR_IOC_CFG) = cia_cfg & ~1;
+		mb();
+	}
+
+	DBG(("conf_write(): finished\n"));
+	restore_flags(flags);
+}
+
+
+int pcibios_read_config_byte (unsigned char bus, unsigned char device_fn,
+			      unsigned char where, unsigned char *value)
+{
+	unsigned long addr = ALCOR_CONF;
+	unsigned long pci_addr;
+	unsigned char type1;
+
+	*value = 0xff;
+
+	if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
+		return PCIBIOS_SUCCESSFUL;
+	}
+
+	addr |= (pci_addr << 5) + 0x00;
+
+	*value = conf_read(addr, type1) >> ((where & 3) * 8);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+int pcibios_read_config_word (unsigned char bus, unsigned char device_fn,
+			      unsigned char where, unsigned short *value)
+{
+	unsigned long addr = ALCOR_CONF;
+	unsigned long pci_addr;
+	unsigned char type1;
+
+	*value = 0xffff;
+
+	if (where & 0x1) {
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	}
+
+	if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) {
+		return PCIBIOS_SUCCESSFUL;
+	}
+
+	addr |= (pci_addr << 5) + 0x08;
+
+	*value = conf_read(addr, type1) >> ((where & 3) * 8);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+int pcibios_read_config_dword (unsigned char bus, unsigned char device_fn,
+			       unsigned char where, unsigned int *value)
+{
+	unsigned long addr = ALCOR_CONF;
+	unsigned long pci_addr;
+	unsigned char type1;
+
+	*value = 0xffffffff;
+	if (where & 0x3) {
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	}
+
+	if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) {
+		return PCIBIOS_SUCCESSFUL;
+	}
+	addr |= (pci_addr << 5) + 0x18;
+	*value = conf_read(addr, type1);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+int pcibios_write_config_byte (unsigned char bus, unsigned char device_fn,
+			       unsigned char where, unsigned char value)
+{
+	unsigned long addr = ALCOR_CONF;
+	unsigned long pci_addr;
+	unsigned char type1;
+
+	if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
+		return PCIBIOS_SUCCESSFUL;
+	}
+	addr |= (pci_addr << 5) + 0x00;
+	conf_write(addr, value << ((where & 3) * 8), type1);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+int pcibios_write_config_word (unsigned char bus, unsigned char device_fn,
+			       unsigned char where, unsigned short value)
+{
+	unsigned long addr = ALCOR_CONF;
+	unsigned long pci_addr;
+	unsigned char type1;
+
+	if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
+		return PCIBIOS_SUCCESSFUL;
+	}
+	addr |= (pci_addr << 5) + 0x08;
+	conf_write(addr, value << ((where & 3) * 8), type1);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+int pcibios_write_config_dword (unsigned char bus, unsigned char device_fn,
+				unsigned char where, unsigned int value)
+{
+	unsigned long addr = ALCOR_CONF;
+	unsigned long pci_addr;
+	unsigned char type1;
+
+	if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1) < 0) {
+		return PCIBIOS_SUCCESSFUL;
+	}
+	addr |= (pci_addr << 5) + 0x18;
+	conf_write(addr, value << ((where & 3) * 8), type1);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+unsigned long alcor_init(unsigned long mem_start, unsigned long mem_end)
+{
+        unsigned int cia_err ;
+
+        /* 
+	 * Set up error reporting.
+	 */
+	cia_err = *(vuip)ALCOR_IOC_CIA_ERR ;
+	cia_err |= (0x1 << 7) ;   /* master abort */
+	*(vuip)ALCOR_IOC_CIA_ERR = cia_err ;
+	mb() ;
+
+	/*
+	 * Set up the PCI->physical memory translation windows.
+	 * For now, windows 1,2 and 3 are disabled.  In the future, we may
+	 * want to use them to do scatter/gather DMA.  Window 0
+	 * goes at 1 GB and is 1 GB large.
+	 */
+
+	*(vuip)ALCOR_IOC_PCI_W0_BASE = 1U | (ALCOR_DMA_WIN_BASE & 0xfff00000U);
+ 	*(vuip)ALCOR_IOC_PCI_W0_MASK = (ALCOR_DMA_WIN_SIZE - 1) & 0xfff00000U;
+	*(vuip)ALCOR_IOC_PCI_T0_BASE = 0;
+
+	*(vuip)ALCOR_IOC_PCI_W1_BASE = 0x0 ;
+	*(vuip)ALCOR_IOC_PCI_W2_BASE = 0x0 ;
+	*(vuip)ALCOR_IOC_PCI_W3_BASE = 0x0 ;
+
+	/*
+	 * check ASN in HWRPB for validity, report if bad
+	 */
+	if (hwrpb->max_asn != MAX_ASN) {
+		printk("alcor_init: max ASN from HWRPB is bad (0x%lx)\n",
+			hwrpb->max_asn);
+		hwrpb->max_asn = MAX_ASN;
+	}
+
+	return mem_start;
+}
+
+int ALCOR_pci_clr_err(void)
+{
+	ALCOR_jd = *((unsigned int *)ALCOR_IOC_CIA_ERR);
+	DBG(("ALCOR_pci_clr_err: ALCOR CIA ERR after read 0x%x\n", ALCOR_jd));
+	*((unsigned long *)ALCOR_IOC_CIA_ERR) = 0x0080;
+	mb();
+	return 0;
+}
+
+void alcor_machine_check(unsigned long vector, unsigned long la_ptr,
+			 struct pt_regs * regs)
+{
+#if 1
+        printk("ALCOR machine check\n") ;
+#else
+	struct el_common *mchk_header;
+	struct el_ALCOR_sysdata_mcheck *mchk_sysdata;
+
+	mchk_header = (struct el_common *)la_ptr;
+
+	mchk_sysdata = 
+	  (struct el_ALCOR_sysdata_mcheck *)(la_ptr + mchk_header->sys_offset);
+
+	DBG(("ALCOR_machine_check: vector=0x%lx la_ptr=0x%lx\n", vector, la_ptr));
+	DBG(("                     pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
+	     regs->pc, mchk_header->size, mchk_header->proc_offset, mchk_header->sys_offset));
+	DBG(("ALCOR_machine_check: expected %d DCSR 0x%lx PEAR 0x%lx\n",
+	     ALCOR_mcheck_expected, mchk_sysdata->epic_dcsr, mchk_sysdata->epic_pear));
+#ifdef DEBUG
+	{
+	    unsigned long *ptr;
+	    int i;
+
+	    ptr = (unsigned long *)la_ptr;
+	    for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
+		printk(" +%lx %lx %lx\n", i*sizeof(long), ptr[i], ptr[i+1]);
+	    }
+	}
+#endif /* DEBUG */
+	/*
+	 * Check if machine check is due to a badaddr() and if so,
+	 * ignore the machine check.
+	 */
+	if (ALCOR_mcheck_expected && (mchk_sysdata->epic_dcsr && 0x0c00UL)) {
+		ALCOR_mcheck_expected = 0;
+		ALCOR_mcheck_taken = 1;
+		mb();
+		mb();
+		ALCOR_pci_clr_err();
+		wrmces(0x7);
+		mb();
+		draina();
+	}
+#endif
+}
+
+#endif /* CONFIG_ALPHA_ALCOR */
diff -u --recursive --new-file v1.3.69/linux/arch/alpha/kernel/bios32.c linux/arch/alpha/kernel/bios32.c
--- v1.3.69/linux/arch/alpha/kernel/bios32.c	Sat Feb 17 16:02:44 1996
+++ linux/arch/alpha/kernel/bios32.c	Thu Feb 29 08:35:24 1996
@@ -76,7 +76,6 @@
  */
 #define PCI_MODIFY		1
 
-
 extern struct hwrpb_struct *hwrpb;
 
 
@@ -656,7 +655,7 @@
 	/*
 	 * Go through all devices, fixing up irqs as we see fit:
 	 */
-	level_bits = 0;
+	level_bits = inb(0x4d0) | (inb(0x4d1) << 8);
 	for (dev = pci_devices; dev; dev = dev->next) {
 		dev->irq = 0;
 		if (dev->bus->number != 0) {
@@ -678,6 +677,7 @@
 		if (pirq < 0) {
 			continue;
 		}
+
 		/*
 		 * if its a VGA, enable its BIOS ROM at C0000
 		 */
diff -u --recursive --new-file v1.3.69/linux/arch/alpha/kernel/irq.c linux/arch/alpha/kernel/irq.c
--- v1.3.69/linux/arch/alpha/kernel/irq.c	Sat Feb 17 16:02:44 1996
+++ linux/arch/alpha/kernel/irq.c	Fri Mar  1 07:50:38 1996
@@ -17,6 +17,7 @@
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
+#include <linux/malloc.h>
 #include <linux/random.h>
 
 #include <asm/system.h>
@@ -116,27 +117,27 @@
 /*
  * Initial irq handlers.
  */
-struct irqaction {
-	void (*handler)(int, struct pt_regs *);
-	unsigned long flags;
-	unsigned long mask;
-	const char *name;
-};
-
-static struct irqaction irq_action[NR_IRQS];
+static struct irqaction *irq_action[NR_IRQS];
 
 int get_irq_list(char *buf)
 {
 	int i, len = 0;
-	struct irqaction * action = irq_action;
+	struct irqaction * action;
 
-	for (i = 0 ; i < NR_IRQS ; i++, action++) {
-		if (!action->handler)
-			continue;
-		len += sprintf(buf+len, "%2d: %8d %c %s\n",
+	for (i = 0 ; i < NR_IRQS ; i++) {
+	        action = *(i + irq_action);
+		if (!action) 
+		        continue;
+		len += sprintf(buf+len, "%2d: %8d %c %s",
 			i, kstat.interrupts[i],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
 			action->name);
+		for (action=action->next; action; action = action->next) {
+			len += sprintf(buf+len, ",%s %s",
+				(action->flags & SA_INTERRUPT) ? " +" : "",
+				action->name);
+		}
+		len += sprintf(buf+len, "\n");
 	}
 	return len;
 }
@@ -218,10 +219,13 @@
 	}
 }
 
-int request_irq(unsigned int irq, void (*handler)(int, struct pt_regs *),
-	unsigned long irqflags, const char * devname)
+int request_irq(unsigned int irq, 
+		void (*handler)(int, void *, struct pt_regs *),
+		unsigned long irqflags, 
+		const char * devname,
+		void *dev_id)
 {
-	struct irqaction * action;
+	struct irqaction *action, *tmp = NULL;
 	unsigned long flags;
 
 	if (irq >= NR_IRQS)
@@ -229,28 +233,53 @@
 	/* don't accept requests for irq #0 */
 	if (!irq)
 		return -EINVAL;
-	action = irq + irq_action;
-	if (action->handler)
-		return -EBUSY;
 	if (!handler)
-		return -EINVAL;
+	    return -EINVAL;
+	action = *(irq + irq_action);
+	if (action) {
+	    if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) {
+		for (tmp = action; tmp->next; tmp = tmp->next);
+	    } else {
+		return -EBUSY;
+	    }
+	    if ((action->flags & SA_INTERRUPT) ^ (irqflags & SA_INTERRUPT)) {
+	      printk("Attempt to mix fast and slow interrupts on IRQ%d denied\n", irq);
+	      return -EBUSY;
+	    }   
+	}
 	save_flags(flags);
 	cli();
+	action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+	if (!action) { 
+	    restore_flags(flags);
+	    return -ENOMEM;
+	}
+	
 	action->handler = handler;
 	action->flags = irqflags;
 	action->mask = 0;
 	action->name = devname;
-	enable_irq(irq);
-	if (irq >= 8 && irq < 16) {
+	action->next = NULL;
+	action->dev_id = dev_id;
+
+	if (tmp) {
+	    tmp->next = action;
+	} else {
+	    *(irq + irq_action) = action;
+	    enable_irq(irq);
+	    if (irq >= 8 && irq < 16) {
 		enable_irq(2);	/* ensure cascade is enabled too */
+	    }
 	}
+
 	restore_flags(flags);
 	return 0;
 }
 
-void free_irq(unsigned int irq)
+void free_irq(unsigned int irq, void *dev_id)
 {
-	struct irqaction * action = irq + irq_action;
+	struct irqaction * action = *(irq + irq_action);
+	struct irqaction * tmp = NULL;
 	unsigned long flags;
 
 	if (irq >= NR_IRQS) {
@@ -261,13 +290,32 @@
 		printk("Trying to free free IRQ%d\n", irq);
 		return;
 	}
+	if (dev_id) {
+	    for (; action; action = action->next) {
+	        if (action->dev_id == dev_id) break;
+		tmp = action;
+	    }
+	    if (!action) {
+		printk("Trying to free free shared IRQ%d\n",irq);
+		return;
+	    }
+	} else if (action->flags & SA_SHIRQ) {
+	    printk("Trying to free shared IRQ%d with NULL device ID\n", irq);
+	    return;
+	}
 	save_flags(flags);
 	cli();
-	mask_irq(irq);
-	action->handler = NULL;
-	action->flags = 0;
-	action->mask = 0;
-	action->name = NULL;
+	if (action && tmp) {
+	    tmp->next = action->next;
+	} else {
+	    *(irq + irq_action) = action->next;
+	}
+	kfree_s(action, sizeof(struct irqaction));
+
+	if (!(*(irq + irq_action))) {
+	    mask_irq(irq);
+	}
+
 	restore_flags(flags);
 }
 
@@ -277,16 +325,20 @@
 	printk("61=%02x, 461=%02x\n", inb(0x61), inb(0x461));
 }
 
-static void unexpected_irq(int irq, struct pt_regs * regs)
+static void unexpected_irq(int irq, void *dev_id, struct pt_regs * regs)
 {
+	struct irqaction *action;
 	int i;
 
 	printk("IO device interrupt, irq = %d\n", irq);
 	printk("PC = %016lx PS=%04lx\n", regs->pc, regs->ps);
 	printk("Expecting: ");
 	for (i = 0; i < 16; i++)
-		if (irq_action[i].handler)
-			printk("[%s:%d] ", irq_action[i].name, i);
+	        if ((action = *(i + irq_action)))
+		        while (action->handler) {
+			        printk("[%s:%d] ", action->name, i);
+				action = action->next;
+			}
 	printk("\n");
 #if defined(CONFIG_ALPHA_JENSEN)
 	printk("64=%02x, 60=%02x, 3fa=%02x 2fa=%02x\n",
@@ -298,16 +350,19 @@
 #endif
 }
 
-static inline void handle_irq(int irq, struct pt_regs * regs)
+static inline void handle_irq(int irq, void *dev_id, struct pt_regs * regs)
 {
-	struct irqaction * action = irq + irq_action;
+	struct irqaction * action = *(irq + irq_action);
 
 	kstat.interrupts[irq]++;
-	if (!action->handler) {
-		unexpected_irq(irq, regs);
-		return;
+	if (!action) {
+	    unexpected_irq(irq, action->dev_id, regs);
+	    return;
+	}
+	while (action) {
+	    action->handler(irq, action->dev_id, regs);
+	    action = action->next;
 	}
-	action->handler(irq, regs);
 }
 
 static inline void device_interrupt(int irq, int ack, struct pt_regs * regs)
@@ -320,12 +375,15 @@
 	}
 
 	kstat.interrupts[irq]++;
-	action = irq_action + irq;
+	action = *(irq_action + irq);
 	if (action->flags & SA_SAMPLE_RANDOM)
 		add_interrupt_randomness(irq);
 	/* quick interrupts get executed with no extra overhead */
 	if (action->flags & SA_INTERRUPT) {
-		action->handler(irq, regs);
+	        while (action) {
+		        action->handler(irq, action->dev_id, regs);
+		        action = action->next;
+	        }
 		ack_irq(ack);
 		return;
 	}
@@ -340,9 +398,12 @@
 	 */
 	mask_irq(ack);
 	ack_irq(ack);
-	if (!action->handler)
+	if (!action)
 		return;
-	action->handler(irq, regs);
+	while (action) {
+	    action->handler(irq, action->dev_id, regs);
+	    action = action->next;
+	}
 	unmask_irq(ack);
 }
 
@@ -356,6 +417,8 @@
 #	define IACK_SC	APECS_IACK_SC
 #elif defined(CONFIG_ALPHA_LCA)
 #	define IACK_SC	LCA_IACK_SC
+#elif defined(CONFIG_ALPHA_ALCOR)
+#	define IACK_SC	ALCOR_IACK_SC
 #else
     	/*
 	 * This is bogus but necessary to get it to compile
@@ -367,6 +430,7 @@
 #endif
 	int j;
 
+#if 1
 	/*
 	 * Generate a PCI interrupt acknowledge cycle.  The PIC will
 	 * respond with the interrupt vector of the highest priority
@@ -383,7 +447,7 @@
 	    }
 	}
 	device_interrupt(j, j, regs);
-#if 0
+#else
 	unsigned long pic;
 
 	/*
@@ -424,6 +488,10 @@
 	/* read the interrupt summary registers */
 	pld = inb(0x804) | (inb(0x805) << 8) | (inb(0x806) << 16);
 
+#if 0
+	printk("[0x%04X/0x%04X]", pld, inb(0x20) | (inb(0xA0) << 8));
+#endif
+
 	/*
 	 * Now for every possible bit set, work through them and call
 	 * the appropriate interrupt handler.
@@ -495,6 +563,11 @@
 static inline void srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
 {
 	int irq, ack;
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+
 
 	ack = irq = (vector - 0x800) >> 4;
 
@@ -517,6 +590,8 @@
 #endif /* CONFIG_ALPHA_JENSEN */
 
 	device_interrupt(irq, ack, regs);
+
+	restore_flags(flags) ;
 }
 
 #if NR_IRQS > 64
@@ -528,12 +603,14 @@
  */
 unsigned long probe_irq_on(void)
 {
+	struct irqaction * action;
 	unsigned long irqs = 0, irqmask;
 	unsigned long delay;
 	unsigned int i;
 
 	for (i = NR_IRQS - 1; i > 0; i--) {
-		if (!irq_action[i].handler) {
+	        action = *(i + irq_action);
+		if (!action->handler) {
 			enable_irq(i);
 			irqs |= (1 << i);
 		}
@@ -598,6 +675,10 @@
 	extern void apecs_machine_check(unsigned long vector, unsigned long la,
 					struct pt_regs * regs);
 	apecs_machine_check(vector, la, regs);
+#elif defined(CONFIG_ALPHA_ALCOR)
+	extern void alcor_machine_check(unsigned long vector, unsigned long la,
+					struct pt_regs * regs);
+	alcor_machine_check(vector, la, regs);
 #else
 	printk("Machine check\n");
 #endif
diff -u --recursive --new-file v1.3.69/linux/arch/alpha/kernel/setup.c linux/arch/alpha/kernel/setup.c
--- v1.3.69/linux/arch/alpha/kernel/setup.c	Sat Feb 17 16:02:45 1996
+++ linux/arch/alpha/kernel/setup.c	Wed Feb 28 11:36:37 1996
@@ -139,6 +139,8 @@
 	*memory_start_p = lca_init(*memory_start_p, *memory_end_p);
 #elif defined(CONFIG_ALPHA_APECS)
 	*memory_start_p = apecs_init(*memory_start_p, *memory_end_p);
+#elif defined(CONFIG_ALPHA_ALCOR)
+	*memory_start_p = alcor_init(*memory_start_p, *memory_end_p);
 #endif
 }
 
diff -u --recursive --new-file v1.3.69/linux/arch/i386/boot/bootsect.S linux/arch/i386/boot/bootsect.S
--- v1.3.69/linux/arch/i386/boot/bootsect.S	Fri Feb 23 13:54:33 1996
+++ linux/arch/i386/boot/bootsect.S	Wed Feb 28 08:26:33 1996
@@ -53,10 +53,6 @@
 ! ld86 requires an entry symbol. This may as well be the usual one.
 .globl	_main
 _main:
-	nop
-	jmp	over_magic
-	.byte	0xF0
-over_magic:
 #if 0 /* hook for debugger, harmless unless BIOS is fussy (old HP) */
 	int	3
 #endif
diff -u --recursive --new-file v1.3.69/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c
--- v1.3.69/linux/arch/i386/kernel/irq.c	Wed Feb  7 15:11:21 1996
+++ linux/arch/i386/kernel/irq.c	Fri Mar  1 07:50:38 1996
@@ -23,6 +23,7 @@
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/timex.h>
+#include <linux/malloc.h>
 #include <linux/random.h>
 
 #include <asm/system.h>
@@ -32,6 +33,7 @@
 #include <asm/smp.h>
 
 #define CR0_NE 32
+#define TIMER_IRQ 0                     /* Keep this in sync with time.c */
 
 static unsigned char cache_21 = 0xff;
 static unsigned char cache_A1 = 0xff;
@@ -158,36 +160,34 @@
 /*
  * Initial irq handlers.
  */
-struct irqaction {
-	void (*handler)(int, struct pt_regs *);
-	unsigned long flags;
-	unsigned long mask;
-	const char *name;
-};
-
-static struct irqaction irq_action[16] = {
-	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
-	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
-	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
-	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
-	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
-	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
-	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
-	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }
+static struct irqaction timer_irq   = { NULL, 0, 0, NULL, NULL, NULL};
+static struct irqaction cascade_irq = { NULL, 0, 0, NULL, NULL, NULL};
+static struct irqaction math_irq    = { NULL, 0, 0, NULL, NULL, NULL};
+
+static struct irqaction *irq_action[16] = {
+	  NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL,
+	  NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL
 };
 
 int get_irq_list(char *buf)
 {
 	int i, len = 0;
-	struct irqaction * action = irq_action;
+	struct irqaction * action;
 
-	for (i = 0 ; i < 16 ; i++, action++) {
-		if (!action->handler)
-			continue;
-		len += sprintf(buf+len, "%3d: %8d %c %s\n",
+	for (i = 0 ; i < 16 ; i++) {
+	        action = *(i + irq_action);
+		if (!action) 
+		        continue;
+		len += sprintf(buf+len, "%2d: %8d %c %s",
 			i, kstat.interrupts[i],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
 			action->name);
+		for (action=action->next; action; action = action->next) {
+			len += sprintf(buf+len, ",%s %s",
+				(action->flags & SA_INTERRUPT) ? " +" : "",
+				action->name);
+		}
+		len += sprintf(buf+len, "\n");
 	}
 /*
  *	Linus - should you add NMI counts here ?????
@@ -203,7 +203,7 @@
 
 int get_smp_prof_list(char *buf) {
         int i,j, len = 0;
-        struct irqaction * action = irq_action;
+        struct irqaction * action;
         unsigned long sum_spins = 0;
         unsigned long sum_spins_syscall = 0;
         unsigned long sum_spins_sys_idle = 0;
@@ -222,7 +222,8 @@
         for (i=0;i<smp_num_cpus;i++)
           len += sprintf(buf+len,"        P%1d ",i);
         len += sprintf(buf+len,"\n");
-        for (i = 0 ; i < NR_IRQS ; i++, action++) {
+        for (i = 0 ; i < NR_IRQS ; i++) {
+	        action = *(i + irq_action);
                 if (!action->handler)
                         continue;
                 len += sprintf(buf+len, "%3d: %10d ",
@@ -232,6 +233,11 @@
                 len += sprintf(buf+len, "%c %s\n",
                         (action->flags & SA_INTERRUPT) ? '+' : ' ',
                         action->name);
+		for (action=action->next; action; action = action->next) {
+			len += sprintf(buf+len, ",%s %s",
+				(action->flags & SA_INTERRUPT) ? " +" : "",
+				action->name);
+		}
         }
         len+=sprintf(buf+len, "LCK: %10lu",
                 sum_spins);
@@ -273,7 +279,8 @@
  */
 asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
 {
-	struct irqaction * action = irq + irq_action;
+	struct irqaction * action = *(irq + irq_action);
+
 #ifdef __SMP__
 	if(smp_threads_ready && active_kernel_processor!=smp_processor_id())
 		panic("IRQ %d: active processor set wrongly(%d not %d).\n", irq, active_kernel_processor, smp_processor_id());
@@ -283,9 +290,13 @@
 #ifdef __SMP_PROF__
         int_count[smp_processor_id()][irq]++;
 #endif
-	if (action->flags & SA_SAMPLE_RANDOM)
-		add_interrupt_randomness(irq);
-	action->handler(irq, regs);
+	while (action) {
+	    if (action->flags & SA_SAMPLE_RANDOM) {
+	        add_interrupt_randomness(irq);
+            }
+	    action->handler(irq, action->dev_id, regs);
+	    action = action->next;
+	}
 }
 
 /*
@@ -295,7 +306,7 @@
  */
 asmlinkage void do_fast_IRQ(int irq)
 {
-	struct irqaction * action = irq + irq_action;
+	struct irqaction * action = *(irq + irq_action);
 #ifdef __SMP__
 	/* IRQ 13 is allowed - thats an invalidate */
 	if(smp_threads_ready && active_kernel_processor!=smp_processor_id() && irq!=13)
@@ -306,56 +317,95 @@
 #ifdef __SMP_PROF__
         int_count[smp_processor_id()][irq]++;
 #endif
-	if (action->flags & SA_SAMPLE_RANDOM)
+	while (action) {
+	    if (action->flags & SA_SAMPLE_RANDOM)
 		add_interrupt_randomness(irq);
-	action->handler(irq, NULL);
+	    action->handler(irq, action->dev_id, NULL);
+	    action = action->next;
+	}
 }
 
 #define SA_PROBE SA_ONESHOT
 
-int request_irq(unsigned int irq, void (*handler)(int, struct pt_regs *),
-	unsigned long irqflags, const char * devname)
+int request_irq(unsigned int irq, 
+		void (*handler)(int, void *, struct pt_regs *),
+		unsigned long irqflags, 
+		const char * devname,
+		void *dev_id)
 {
-	struct irqaction * action;
+	struct irqaction * action, *tmp = NULL;
 	unsigned long flags;
 
 	if (irq > 15)
-		return -EINVAL;
-	action = irq + irq_action;
-	if (action->handler)
-		return -EBUSY;
+	    return -EINVAL;
 	if (!handler)
-		return -EINVAL;
+	    return -EINVAL;
+	action = *(irq + irq_action);
+	if (action) {
+	    if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) {
+		for (tmp = action; tmp->next; tmp = tmp->next);
+	    } else {
+		return -EBUSY;
+	    }
+	    if ((action->flags & SA_INTERRUPT) ^ (irqflags & SA_INTERRUPT)) {
+	      printk("Attempt to mix fast and slow interrupts on IRQ%d denied\n", irq);
+	      return -EBUSY;
+	    }   
+	}
 	if (irqflags & SA_SAMPLE_RANDOM)
 		rand_initialize_irq(irq);
 	save_flags(flags);
 	cli();
+	if (irq == 2)
+	    action = &cascade_irq;
+	else if (irq == 13)
+	  action = &math_irq;
+	else if (irq == TIMER_IRQ)
+	  action = &timer_irq;
+	else
+	  action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+
+	if (!action) { 
+	    restore_flags(flags);
+	    return -ENOMEM;
+	}
+
 	action->handler = handler;
 	action->flags = irqflags;
 	action->mask = 0;
 	action->name = devname;
-	if (!(action->flags & SA_PROBE)) { /* SA_ONESHOT is used by probing */
+	action->next = NULL;
+	action->dev_id = dev_id;
+
+	if (tmp) {
+	    tmp->next = action;
+	} else {
+	    *(irq + irq_action) = action;
+	    if (!(action->flags & SA_PROBE)) {/* SA_ONESHOT used by probing */
 		if (action->flags & SA_INTERRUPT)
-			set_intr_gate(0x20+irq,fast_interrupt[irq]);
+		  set_intr_gate(0x20+irq,fast_interrupt[irq]);
 		else
-			set_intr_gate(0x20+irq,interrupt[irq]);
-	}
-	if (irq < 8) {
+		  set_intr_gate(0x20+irq,interrupt[irq]);
+	    }
+	    if (irq < 8) {
 		cache_21 &= ~(1<<irq);
 		outb(cache_21,0x21);
-	} else {
+	    } else {
 		cache_21 &= ~(1<<2);
 		cache_A1 &= ~(1<<(irq-8));
 		outb(cache_21,0x21);
 		outb(cache_A1,0xA1);
+	    }
 	}
+
 	restore_flags(flags);
 	return 0;
 }
 		
-void free_irq(unsigned int irq)
+void free_irq(unsigned int irq, void *dev_id)
 {
-	struct irqaction * action = irq + irq_action;
+	struct irqaction * action = *(irq + irq_action);
+	struct irqaction * tmp = NULL;
 	unsigned long flags;
 
 	if (irq > 15) {
@@ -366,20 +416,43 @@
 		printk("Trying to free free IRQ%d\n",irq);
 		return;
 	}
+	if (dev_id) {
+	    for (; action; action = action->next) {
+	        if (action->dev_id == dev_id) break;
+		tmp = action;
+	    }
+	    if (!action) {
+		printk("Trying to free free shared IRQ%d\n",irq);
+		return;
+	    }
+	} else if (action->flags & SA_SHIRQ) {
+	    printk("Trying to free shared IRQ%d with NULL device ID\n", irq);
+	    return;
+	}
 	save_flags(flags);
 	cli();
-	if (irq < 8) {
+	if (action && tmp) {
+	    tmp->next = action->next;
+	} else {
+	    *(irq + irq_action) = action->next;
+	}
+
+	if ((irq == 2) || (irq == 13) | (irq == TIMER_IRQ))
+	  memset(action, 0, sizeof(struct irqaction));
+	else 
+	  kfree_s(action, sizeof(struct irqaction));
+	
+	if (!(*(irq + irq_action))) {
+	    if (irq < 8) {
 		cache_21 |= 1 << irq;
 		outb(cache_21,0x21);
-	} else {
+	    } else {
 		cache_A1 |= 1 << (irq-8);
 		outb(cache_A1,0xA1);
+	    }
+	    set_intr_gate(0x20+irq,bad_interrupt[irq]);
 	}
-	set_intr_gate(0x20+irq,bad_interrupt[irq]);
-	action->handler = NULL;
-	action->flags = 0;
-	action->mask = 0;
-	action->name = NULL;
+
 	restore_flags(flags);
 }
 
@@ -398,7 +471,7 @@
  */
  
 
-static void math_error_irq(int cpl, struct pt_regs *regs)
+static void math_error_irq(int cpl, void *dev_id, struct pt_regs *regs)
 {
 	outb(0,0xF0);
 	if (ignore_irq13 || !hard_math)
@@ -408,7 +481,7 @@
 
 #endif
 
-static void no_action(int cpl, struct pt_regs * regs) { }
+static void no_action(int cpl, void *dev_id, struct pt_regs *regs) { }
 
 unsigned long probe_irq_on (void)
 {
@@ -417,7 +490,7 @@
 
 	/* first, snaffle up any unassigned irqs */
 	for (i = 15; i > 0; i--) {
-		if (!request_irq(i, no_action, SA_PROBE, "probe")) {
+		if (!request_irq(i, no_action, SA_PROBE, "probe", NULL)) {
 			enable_irq(i);
 			irqs |= (1 << i);
 		}
@@ -431,7 +504,7 @@
 	for (i = 15; i > 0; i--) {
 		if (irqs & (1 << i) & irqmask) {
 			irqs ^= (1 << i);
-			free_irq(i);
+			free_irq(i, NULL);
 		}
 	}
 #ifdef DEBUG
@@ -447,7 +520,7 @@
 	irqmask = (((unsigned int)cache_A1)<<8) | (unsigned int)cache_21;
 	for (i = 15; i > 0; i--) {
 		if (irqs & (1 << i)) {
-			free_irq(i);
+			free_irq(i, NULL);
 		}
 	}
 #ifdef DEBUG
@@ -481,13 +554,13 @@
 #ifdef __SMP__	
 	set_intr_gate(0x20+i, interrupt[i]);	/* IRQ '16' - IPI for rescheduling */
 #endif	
-	if (request_irq(2, no_action, SA_INTERRUPT, "cascade"))
+	if (request_irq(2, no_action, SA_INTERRUPT, "cascade", NULL))
 		printk("Unable to get IRQ2 for cascade.\n");
 #ifndef __SMP__		
-	if (request_irq(13,math_error_irq, 0, "math error"))
+	if (request_irq(13, math_error_irq, 0, "math error", NULL))
 		printk("Unable to get IRQ13 for math-error handler.\n");
 #else
-	if (request_irq(13, smp_message_irq, SA_INTERRUPT, "IPI"))
+	if (request_irq(13, smp_message_irq, SA_INTERRUPT, "IPI", NULL))
 		printk("Unable to get IRQ13 for IPI.\n");
 #endif				
 	request_region(0x20,0x20,"pic1");
diff -u --recursive --new-file v1.3.69/linux/arch/i386/kernel/smp.c linux/arch/i386/kernel/smp.c
--- v1.3.69/linux/arch/i386/kernel/smp.c	Wed Feb 28 11:50:00 1996
+++ linux/arch/i386/kernel/smp.c	Fri Mar  1 07:50:38 1996
@@ -7,6 +7,8 @@
  *	Much of the core SMP work is based on previous work by Thomas Radke, to
  *	whom a great many thanks are extended.
  *
+ *	Thanks to Intel for testing against several Pentium and Pentium Pro
+ *	MP machines.
  *
  *	This code is released under the GNU public license version 2 or
  *	later.
@@ -35,12 +37,12 @@
 #include <asm/pgtable.h>
 #include <asm/smp.h>
 
-static int smp_found_config=0;				/* Have we found an SMP box 				*/
+int smp_found_config=0;					/* Have we found an SMP box 				*/
 
 unsigned long cpu_present_map = 0;			/* Bitmask of existing CPU's 				*/
 int smp_num_cpus;					/* Total count of live CPU's 				*/
 int smp_threads_ready=0;				/* Set when the idlers are all forked 			*/
-volatile unsigned long cpu_number_map[NR_CPUS];		/* which CPU maps to which logical number		*/
+volatile int cpu_number_map[NR_CPUS];			/* which CPU maps to which logical number		*/
 volatile unsigned long cpu_callin_map[NR_CPUS] = {0,};	/* We always use 0 the rest is ready for parallel delivery */
 volatile unsigned long smp_invalidate_needed;		/* Used for the invalidate map thats also checked in the spinlock */
 struct cpuinfo_x86 cpu_data[NR_CPUS];			/* Per cpu bogomips and other parameters 		*/
@@ -49,6 +51,7 @@
 unsigned char boot_cpu_id = 0;				/* Processor that is doing the boot up 			*/
 static unsigned char *kstack_base,*kstack_end;		/* Kernel stack list pointers 				*/
 static int smp_activated = 0;				/* Tripped once we need to start cross invalidating 	*/
+int apic_version[NR_CPUS];				/* APIC version number					*/
 static volatile int smp_commenced=0;			/* Tripped when we start scheduling 		    	*/
 unsigned long apic_addr=0xFEE00000;			/* Address of APIC (defaults to 0xFEE00000)		*/
 unsigned long nlong = 0;				/* dummy used for apic_reg address + 0x20		*/
@@ -114,6 +117,8 @@
 		"Unknown","Unknown",
 		"80486DX/4"
 	};
+	if(family==0x6)
+		return("Pentium(tm) Pro");
 	if(family==0x5)
 		return("Pentium(tm)");
 	if(family==0x0F && model==0x0F)
@@ -208,7 +213,10 @@
 					if(m->mpc_apicid>NR_CPUS)
 						printk("Processor #%d unused. (Max %d processors).\n",m->mpc_apicid, NR_CPUS);
 					else						
+					{
 						cpu_present_map|=(1<<m->mpc_apicid);
+						apic_version[m->mpc_apicid]=m->mpc_apicver;
+					}
 				}
 				mpt+=sizeof(*m);
 				count+=sizeof(*m);
@@ -345,6 +353,10 @@
 				else
 					cpu_present_map=3;
 				printk("Processors: %d\n", num_processors);
+				/*
+				 *	Only use the first one found.
+				 */
+				return;
 			}
 		}
 		bp+=4;
@@ -494,19 +506,44 @@
  
 void smp_boot_cpus(void)
 {
-	int i=0;
+	int i,j;
 	int cpucount=0;
+	unsigned long cfg;
 	void *stack;
 	extern unsigned long init_user_stack[];
 	
 	/*
+	 *	Initialize the logical to physical cpu number mapping
+	 */
+
+	for (i = 0; i < NR_CPUS; i++)
+		cpu_number_map[i] = -1;
+
+	/*
+	 *	Setup boot CPU information
+	 */
+ 
+	kernel_stacks[boot_cpu_id]=(void *)init_user_stack;	/* Set up for boot processor first */
+
+	smp_store_cpu_info(boot_cpu_id);			/* Final full version of the data */
+
+	cpu_present_map |= (1 << smp_processor_id());
+	cpu_number_map[boot_cpu_id] = 0;
+	active_kernel_processor=boot_cpu_id;
+
+	/*
+	 *	If we don't conform to the Intel MPS standard, get out
+	 *	of here now!
+	 */
+
+	if (!smp_found_config)
+		return;
+
+	/*
 	 *	Map the local APIC into kernel space
 	 */
 
-	/* Mapping on non-Intel conforming platforms is a bad move. */
-	if (1<cpu_present_map)	
-		apic_reg = vremap(0xFEE00000,4096);
-	
+	apic_reg = vremap(0xFEE00000,4096);
 	
 	if(apic_reg == NULL)
 		panic("Unable to map local apic.\n");
@@ -515,39 +552,68 @@
 	{
 		int reg;
 
+		/*
+		 *	This is to verify that we're looking at
+		 *	a real local APIC.  Check these against
+		 *	your board if the CPUs aren't getting
+		 *	started for no apparent reason.
+		 */
+
 		reg = apic_read(APIC_VERSION);
-		printk("Getting VERSION: %x\n", reg);
+		SMP_PRINTK(("Getting VERSION: %x\n", reg));
 
 		apic_write(APIC_VERSION, 0);
 		reg = apic_read(APIC_VERSION);
-		printk("Getting VERSION: %x\n", reg);
+		SMP_PRINTK(("Getting VERSION: %x\n", reg));
+
+		/*
+		 *	The two version reads above should print the same
+		 *	NON-ZERO!!! numbers.  If the second one is zero,
+		 *	there is a problem with the APIC write/read
+		 *	definitions.
+		 *
+		 *	The next two are just to see if we have sane values.
+		 *	They're only really relevant if we're in Virtual Wire
+		 *	compatibility mode, but most boxes are anymore.
+		 */
+
 
 		reg = apic_read(APIC_LVT0);
-		printk("Getting LVT0: %x\n", reg);
+		SMP_PRINTK(("Getting LVT0: %x\n", reg));
 
 		reg = apic_read(APIC_LVT1);
-		printk("Getting LVT1: %x\n", reg);
+		SMP_PRINTK(("Getting LVT1: %x\n", reg));
 	}
 #endif
 	
 	/*
-	 *	Now scan the cpu present map and fire up anything we find.
+	 *	Enable the local APIC
 	 */
-	 
-	kernel_stacks[boot_cpu_id]=(void *)init_user_stack;	/* Set up for boot processor first */
-
-	smp_store_cpu_info(boot_cpu_id);			/* Final full version of the data */
-	
-	active_kernel_processor=boot_cpu_id;
+ 
+	cfg=apic_read(APIC_SPIV);
+	cfg|=(1<<8);		/* Enable APIC */
+	apic_write(APIC_SPIV,cfg);
 
+	udelay(10);
+			
+	/*
+	 *	Now scan the cpu present map and fire up the other CPUs.
+	 */
+ 
 	SMP_PRINTK(("CPU map: %lx\n", cpu_present_map));
 		
 	for(i=0;i<NR_CPUS;i++)
 	{
-		if((cpu_present_map&(1<<i)) && i!=boot_cpu_id)		/* Rebooting yourself is a bad move */
+		/*
+		 *	Don't even attempt to start the boot CPU!
+		 */
+		if (i == boot_cpu_id)
+			continue;
+
+		if (cpu_present_map & (1 << i))
 		{
-			unsigned long cfg, send_status, accept_status;
-			int timeout;
+			unsigned long send_status, accept_status;
+			int timeout, num_starts;
 			
 			/*
 			 *	We need a kernel stack for each processor.
@@ -560,16 +626,8 @@
 			install_trampoline(stack);
 
 			printk("Booting processor %d stack %p: ",i,stack);			/* So we set whats up   */
-				
-			/*
-			 *	Enable the local APIC
-			 */
-			 
-			cfg=apic_read(APIC_SPIV);
-			cfg|=(1<<8);		/* Enable APIC */
-			apic_write(APIC_SPIV,cfg);
-			
-			/*
+
+			/*				
 			 *	This gunge runs the startup process for
 			 *	the targeted processor.
 			 */
@@ -577,17 +635,24 @@
 			SMP_PRINTK(("Setting warm reset code and vector.\n"));
 
 			/*
-			 *	Needed to boot a 486 board.
+			 *	Install a writable page 0 entry.
 			 */
 			 
 			CMOS_WRITE(0xa, 0xf);
 			pg0[0]=7;
+			local_invalidate();
 			*((volatile unsigned short *) 0x467) = ((unsigned long)stack)>>4;
 			*((volatile unsigned short *) 0x469) = 0;
+			
+			/*
+			 *	Protect it again
+			 */
+			 
 			pg0[0]= pte_val(mk_pte(0, PAGE_READONLY));
+			local_invalidate();
 
 			/*
-			 *	Clean up the errors
+			 *	Be paranoid about clearing APIC errors.
 			 */
 
 			apic_write(APIC_ESR, 0);
@@ -597,9 +662,13 @@
 			 *	Status is now clean
 			 */
 			 
-			send_status = 0;
+			send_status = 	0;
 			accept_status = 0;
 
+			/*
+			 *	Starting actual IPI sequence...
+			 */
+
 			SMP_PRINTK(("Asserting INIT.\n"));
 
 			/*
@@ -611,123 +680,76 @@
 			apic_write(APIC_ICR2, cfg|SET_APIC_DEST_FIELD(i)); 			/* Target chip     	*/
 			cfg=apic_read(APIC_ICR);
 			cfg&=~0xCDFFF;								/* Clear bits 		*/
-			cfg|=0x0000c500;	/* Urgh.. fix for constants */
+			cfg |= (APIC_DEST_FIELD | APIC_DEST_LEVELTRIG
+				| APIC_DEST_ASSERT | APIC_DEST_DM_INIT);
 			apic_write(APIC_ICR, cfg);						/* Send IPI */
 
-			timeout = 0;
-			do {
-				udelay(1000);
-				if ((send_status = (!(apic_read(APIC_ICR) & 0x00001000))))
-					break;
-			} while (timeout++ < 1000);
-
-#ifdef EEK2
-			if (send_status) {
-				apic_write(APIC_ESR, 0);
-				accept_status = (apic_read(APIC_ESR) & 0xEF);
-			}
-#endif
+			udelay(200);
+			SMP_PRINTK(("Deasserting INIT.\n"));
 
+			cfg=apic_read(APIC_ICR2);
+			cfg&=0x00FFFFFF;
+			apic_write(APIC_ICR2, cfg|SET_APIC_DEST_FIELD(i));			/* Target chip     	*/
+			cfg=apic_read(APIC_ICR);
+			cfg&=~0xCDFFF;								/* Clear bits 		*/
+			cfg |= (APIC_DEST_FIELD | APIC_DEST_LEVELTRIG
+				| APIC_DEST_DM_INIT);
+			apic_write(APIC_ICR, cfg);						/* Send IPI */
+			
 			/*
-			 *	And off again
+			 *	Should we send STARTUP IPIs ?
+			 *
+			 *	Determine this based on the APIC version.
+			 *	If we don't have an integrated APIC, don't
+			 *	send the STARTUP IPIs.
 			 */
-			 
-			if (send_status && !accept_status)
-			{
-				SMP_PRINTK(("Deasserting INIT.\n"));
-			
-				cfg=apic_read(APIC_ICR2);
-				cfg&=0x00FFFFFF;
-				apic_write(APIC_ICR2, cfg|SET_APIC_DEST_FIELD(i));			/* Target chip     	*/
-				cfg=apic_read(APIC_ICR);
-				cfg&=~0xCDFFF;								/* Clear bits 		*/
-				cfg|=0x00008500;
-				apic_write(APIC_ICR, cfg);						/* Send IPI */
-
-				timeout = 0;
-				do {
-					udelay(1000);
-					if ((send_status = !(apic_read(APIC_ICR) & 0x00001000) ))
-						break;
-				} while (timeout++ < 1000);
 
-				if (send_status) {
-					udelay(1000000);
-					apic_write(APIC_ESR, 0);
-					accept_status = (apic_read(APIC_ESR) & 0xEF);
-				}
-			}
+			if ( apic_version[i] & 0xF0 )
+				num_starts = 2;
+			else
+				num_starts = 0;
 
 			/*
-			 *	We currently assume an integrated
-			 *	APIC only, so STARTUP IPIs must be
-			 *	sent as well.
+			 *	Run STARTUP IPI loop.
 			 */
 
-			if (send_status && !accept_status)
+			for (j = 0; !(send_status || accept_status)
+				    && (j < num_starts) ; j++)
 			{
-				SMP_PRINTK(("Sending first STARTUP.\n"));
-			
-				/*
-				 *	First STARTUP IPI
-				 */
-
-				cfg=apic_read(APIC_ICR2);
-				cfg&=0x00FFFFFF;
-				apic_write(APIC_ICR2, cfg|SET_APIC_DEST_FIELD(i));			/* Target chip     	*/
-				cfg=apic_read(APIC_ICR);
-				cfg&=~0xCDFFF	;							/* Clear bits 		*/
-				cfg|=APIC_DEST_FIELD|APIC_DEST_DM_STARTUP|(((unsigned long)stack)>>12);	/* Boot on the stack 	*/		
-				apic_write(APIC_ICR, cfg);						/* Kick the second 	*/
+				SMP_PRINTK(("Sending STARTUP #%d.\n",j));
 
-				timeout = 0;
-				do {
-					udelay(1000);
-					if ((send_status = !(apic_read(APIC_ICR) & 0x00001000)) )
-						break;
-				} while (timeout++ < 1000);
-
-				if (send_status) {
-					udelay(1000000);
-					apic_write(APIC_ESR, 0);
-					accept_status = (apic_read(APIC_ESR) & 0xEF);
-				}
-			}
-
-			if (send_status && !accept_status)
-			{
-				SMP_PRINTK(("Sending second STARTUP.\n"));
+				apic_write(APIC_ESR, 0);
 			
 				/*
-				 *	Second STARTUP IPI
+				 *	STARTUP IPI
 				 */
 
 				cfg=apic_read(APIC_ICR2);
 				cfg&=0x00FFFFFF;
 				apic_write(APIC_ICR2, cfg|SET_APIC_DEST_FIELD(i));			/* Target chip     	*/
 				cfg=apic_read(APIC_ICR);
-				cfg&=~0xCDFFF	;							/* Clear bits 		*/
-				cfg|=APIC_DEST_FIELD|APIC_DEST_DM_STARTUP|(((unsigned long)stack)>>12);	/* Boot on the stack 	*/		
+				cfg&=~0xCDFFF;								/* Clear bits 		*/
+				cfg |= (APIC_DEST_FIELD
+					| APIC_DEST_DM_STARTUP
+					| (((int) stack) >> 12) );					/* Boot on the stack 	*/		
 				apic_write(APIC_ICR, cfg);						/* Kick the second 	*/
 
 				timeout = 0;
 				do {
-					udelay(1000);
-					if ((send_status = !(apic_read(APIC_ICR) & 0x00001000)))
-						break;
-				} while (timeout++ < 1000);
+					udelay(10);
+				} while ( (send_status = (apic_read(APIC_ICR) & 0x1000))
+					  && (timeout++ < 1000));
+				udelay(200);
 
-				if (send_status) {
-					udelay(1000000);
-					apic_write(APIC_ESR, 0);
-					accept_status = (apic_read(APIC_ESR) & 0xEF);
-				}
+				accept_status = (apic_read(APIC_ESR) & 0xEF);
 			}
 
-			if (!send_status)		/* APIC never delivered?? */
+			if (send_status)		/* APIC never delivered?? */
 				printk("APIC never delivered???\n");
-			else if (accept_status)		/* Send accept error */
+			if (accept_status)		/* Send accept error */
 				printk("APIC delivery error (%lx).\n", accept_status);
+			
+			if( !(send_status || accept_status) )
 			{
 				for(timeout=0;timeout<50000;timeout++)
 				{
@@ -746,28 +768,54 @@
 					if(*((volatile unsigned char *)8192)==0xA5)
 						printk("Stuck ??\n");
 					else
-						printk("Not responding val=(%lx).\n", *((unsigned long *) stack));
-					cpu_present_map&=~(1<<i);
-					cpu_number_map[i] = -1;
+						printk("Not responding.\n");
 				}
 			}
 
 			/* mark "stuck" area as not stuck */
 			*((volatile unsigned long *)8192) = 0;
 		}
-		else if (i == boot_cpu_id)
-		{
-			cpu_number_map[i] = 0;
-		}
-		else
-		{
-			cpu_number_map[i] = -1;
-		}
-
+		
+		/* 
+		 *	Make sure we unmap all failed CPUs
+		 */
+		 
+		if (cpu_number_map[i] == -1)
+			cpu_present_map &= ~(1 << i);
 	}
+
+	/*
+	 *	Cleanup possible dangling ends...
+	 */
+
+	/*
+	 *	Install writable page 0 entry.
+	 */
+
+	cfg = pg0[0];
+	pg0[0] = 3;	/* writeable, present, addr 0 */
+	local_invalidate();
+
+	/*
+	 *	Paranoid:  Set warm reset code and vector here back
+	 *	to default values.
+	 */
+
+	CMOS_WRITE(0, 0xf);
+
+	*((volatile long *) 0x467) = 0;
+
+	/*
+	 *	Restore old page 0 entry.
+	 */
+
+	pg0[0] = cfg;
+	local_invalidate();
+
 	/*
 	 *	Allow the user to impress friends.
 	 */
+	
 	if(cpucount==0)
 	{
 		printk("Error: only one processor found.\n");
@@ -1000,7 +1048,7 @@
  *	Reschedule call back
  */
 
-void smp_reschedule_irq(int cpl, struct pt_regs *regs)
+void smp_reschedule_irq(int cpl, void *dev_id, struct pt_regs *regs)
 {
 #ifdef DEBUGGING_SMP_RESCHED
 	static int ct=0;
@@ -1101,7 +1149,7 @@
  *	Message call back.
  */
  
-void smp_message_irq(int cpl, struct pt_regs *regs)
+void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs)
 {
 	int i=smp_processor_id();
 /*	static int n=0;
diff -u --recursive --new-file v1.3.69/linux/arch/i386/kernel/time.c linux/arch/i386/kernel/time.c
--- v1.3.69/linux/arch/i386/kernel/time.c	Mon Dec 11 15:42:00 1995
+++ linux/arch/i386/kernel/time.c	Fri Mar  1 07:50:38 1996
@@ -245,7 +245,7 @@
  * timer_interrupt() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick
  */
-static inline void timer_interrupt(int irq, struct pt_regs * regs)
+static inline void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	do_timer(regs);
 
@@ -274,13 +274,13 @@
  * cycle counter value at the time of the timer interrupt, so that
  * we later on can estimate the time of day more exactly.
  */
-static void pentium_timer_interrupt(int irq, struct pt_regs * regs)
+static void pentium_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	/* read Pentium cycle counter */
 	__asm__(".byte 0x0f,0x31"
 		:"=a" (((unsigned long *) &last_timer_cc)[0]),
 		 "=d" (((unsigned long *) &last_timer_cc)[1]));
-	timer_interrupt(irq, regs);
+	timer_interrupt(irq, NULL, regs);
 }
 
 /* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
@@ -355,7 +355,7 @@
 
 void time_init(void)
 {
-	void (*irq_handler)(int, struct pt_regs *);
+	void (*irq_handler)(int, void *, struct pt_regs *);
 	xtime.tv_sec = get_cmos_time();
 	xtime.tv_usec = 0;
 
@@ -374,6 +374,6 @@
 			 "=d" (((unsigned long *) &init_timer_cc)[1]));
 	}
 #endif
-	if (request_irq(TIMER_IRQ, irq_handler, 0, "timer") != 0)
+	if (request_irq(TIMER_IRQ, irq_handler, 0, "timer", NULL) != 0)
 		panic("Could not allocate timer IRQ!");
 }
diff -u --recursive --new-file v1.3.69/linux/arch/mips/kernel/irq.c linux/arch/mips/kernel/irq.c
--- v1.3.69/linux/arch/mips/kernel/irq.c	Sun Dec 17 11:43:10 1995
+++ linux/arch/mips/kernel/irq.c	Fri Mar  1 07:50:38 1996
@@ -32,6 +32,7 @@
 #include <linux/types.h>
 #include <linux/interrupt.h>
 #include <linux/timex.h>
+#include <linux/malloc.h>
 #include <linux/random.h>
 
 #include <asm/bitops.h>
@@ -42,6 +43,8 @@
 #include <asm/mipsregs.h>
 #include <asm/system.h>
 
+#define TIMER_IRQ 0                     /* Keep this in sync with time.c */
+
 unsigned char cache_21 = 0xff;
 unsigned char cache_A1 = 0xff;
 
@@ -98,36 +101,34 @@
 /*
  * Initial irq handlers.
  */
-struct irqaction {
-	void (*handler)(int, struct pt_regs *);
-	unsigned long flags;
-	unsigned long mask;
-	const char *name;
-};
-
-static struct irqaction irq_action[16] = {
-	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
-	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
-	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
-	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
-	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
-	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
-	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
-	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }
+static struct irqaction timer_irq = { NULL, 0, 0, NULL, NULL, NULL};
+static struct irqaction cascade_irq = { NULL, 0, 0, NULL, NULL, NULL};
+static struct irqaction math_irq = { NULL, 0, 0, NULL, NULL, NULL};
+
+static struct irqaction *irq_action[16] = {
+	  NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL,
+	  NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL
 };
 
 int get_irq_list(char *buf)
 {
 	int i, len = 0;
-	struct irqaction * action = irq_action;
+	struct irqaction * action;
 
-	for (i = 0 ; i < 16 ; i++, action++) {
-		if (!action->handler)
-			continue;
-		len += sprintf(buf+len, "%3d: %8d %c %s\n",
+	for (i = 0 ; i < 16 ; i++) {
+	        action = *(i + irq_action);
+		if (!action) 
+		        continue;
+		len += sprintf(buf+len, "%2d: %8d %c %s",
 			i, kstat.interrupts[i],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
 			action->name);
+		for (action=action->next; action; action = action->next) {
+			len += sprintf(buf+len, ",%s %s",
+				(action->flags & SA_INTERRUPT) ? " +" : "",
+				action->name);
+		}
+		len += sprintf(buf+len, "\n");
 	}
 	return len;
 }
@@ -141,12 +142,15 @@
  */
 asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
 {
-	struct irqaction * action = irq + irq_action;
+	struct irqaction * action = *(irq + irq_action);
 
 	kstat.interrupts[irq]++;
 	if (action->flags & SA_SAMPLE_RANDOM)
 		add_interrupt_randomness(irq);
-	action->handler(irq, regs);
+	while (action) {
+	    action->handler(irq, action->dev_id, regs);
+	    action = action->next;
+	}
 }
 
 /*
@@ -156,38 +160,74 @@
  */
 asmlinkage void do_fast_IRQ(int irq)
 {
-	struct irqaction * action = irq + irq_action;
+	struct irqaction * action = *(irq + irq_action);
 
 	kstat.interrupts[irq]++;
 	if (action->flags & SA_SAMPLE_RANDOM)
 		add_interrupt_randomness(irq);
-	action->handler(irq, NULL);
+	while (action) {
+	    action->handler(irq, action->dev_id, NULL);
+	    action = action->next;
+	}
 }
 
 #define SA_PROBE SA_ONESHOT
 
-int request_irq(unsigned int irq, void (*handler)(int, struct pt_regs *),
-	unsigned long irqflags, const char * devname)
+int request_irq(unsigned int irq, 
+		void (*handler)(int, void *, struct pt_regs *),
+		unsigned long irqflags, 
+		const char * devname,
+		void *dev_id)
 {
-	struct irqaction * action;
+	struct irqaction * action, *tmp = NULL;
 	unsigned long flags;
 
 	if (irq > 15)
 		return -EINVAL;
-	action = irq + irq_action;
-	if (action->handler)
-		return -EBUSY;
 	if (!handler)
-		return -EINVAL;
+	    return -EINVAL;
+	action = *(irq + irq_action);
+	if (action) {
+	    if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) {
+		for (tmp = action; tmp->next; tmp = tmp->next);
+	    } else {
+		return -EBUSY;
+	    }
+	    if ((action->flags & SA_INTERRUPT) ^ (irqflags & SA_INTERRUPT)) {
+	      printk("Attempt to mix fast and slow interrupts on IRQ%d denied\n", irq);
+	      return -EBUSY;
+	    }   
+	}
 	if (irqflags & SA_SAMPLE_RANDOM)
 		rand_initialize_irq(irq);
 	save_flags(flags);
 	cli();
+	if (irq == 2)
+	    action = &cascade_irq;
+	else if (irq == 13)
+	  action = &math_irq;
+	else if (irq == TIMER_IRQ)
+	  action = &timer_irq;
+	else
+	  action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+
+	if (!action) { 
+	    restore_flags(flags);
+	    return -ENOMEM;
+	}
+
 	action->handler = handler;
 	action->flags = irqflags;
 	action->mask = 0;
 	action->name = devname;
-	if (!(action->flags & SA_PROBE)) { /* SA_ONESHOT is used by probing */
+	action->next = NULL;
+	action->dev_id = dev_id;
+
+	if (tmp) {
+	    tmp->next = action;
+	} else {
+	    *(irq + irq_action) = action;
+	    if (!(action->flags & SA_PROBE)) {/* SA_ONESHOT used by probing */
 		/*
 		 * FIXME: Does the SA_INTERRUPT flag make any sense on MIPS???
 		 */
@@ -195,23 +235,25 @@
 			set_int_vector(irq,fast_interrupt);
 		else
 			set_int_vector(irq,interrupt);
-	}
-	if (irq < 8) {
+	    }
+	    if (irq < 8) {
 		cache_21 &= ~(1<<irq);
 		outb(cache_21,0x21);
-	} else {
+	    } else {
 		cache_21 &= ~(1<<2);
 		cache_A1 &= ~(1<<(irq-8));
 		outb(cache_21,0x21);
 		outb(cache_A1,0xA1);
+	    }
 	}
 	restore_flags(flags);
 	return 0;
 }
 
-void free_irq(unsigned int irq)
+void free_irq(unsigned int irq, void *dev_id)
 {
-	struct irqaction * action = irq + irq_action;
+	struct irqaction * action = *(irq + irq_action);
+	struct irqaction * tmp = NULL;
 	unsigned long flags;
 
 	if (irq > 15) {
@@ -222,24 +264,46 @@
 		printk("Trying to free free IRQ%d\n",irq);
 		return;
 	}
+	if (dev_id) {
+	    for (; action; action = action->next) {
+	        if (action->dev_id == dev_id) break;
+		tmp = action;
+	    }
+	    if (!action) {
+		printk("Trying to free free shared IRQ%d\n",irq);
+		return;
+	    }
+	} else if (action->flags & SA_SHIRQ) {
+	    printk("Trying to free shared IRQ%d with NULL device ID\n", irq);
+	    return;
+	}
 	save_flags(flags);
 	cli();
-	if (irq < 8) {
+	if (action && tmp) {
+	    tmp->next = action->next;
+	} else {
+	    *(irq + irq_action) = action->next;
+	}
+
+	if ((irq == 2) || (irq == 13) | (irq == TIMER_IRQ))
+	  memset(action, 0, sizeof(struct irqaction));
+	else 
+	  kfree_s(action, sizeof(struct irqaction));
+	
+	if (!(*(irq + irq_action))) {
+	    if (irq < 8) {
 		cache_21 |= 1 << irq;
 		outb(cache_21,0x21);
-	} else {
+	    } else {
 		cache_A1 |= 1 << (irq-8);
 		outb(cache_A1,0xA1);
+	    }
+	    set_int_vector(irq,bad_interrupt);
 	}
-	set_int_vector(irq,bad_interrupt);
-	action->handler = NULL;
-	action->flags = 0;
-	action->mask = 0;
-	action->name = NULL;
 	restore_flags(flags);
 }
 
-static void no_action(int cpl, struct pt_regs * regs) { }
+static void no_action(int cpl, void *dev_id, struct pt_regs * regs) { }
 
 unsigned long probe_irq_on (void)
 {
@@ -248,7 +312,7 @@
 
 	/* first, snaffle up any unassigned irqs */
 	for (i = 15; i > 0; i--) {
-		if (!request_irq(i, no_action, SA_PROBE, "probe")) {
+		if (!request_irq(i, no_action, SA_PROBE, "probe", NULL)) {
 			enable_irq(i);
 			irqs |= (1 << i);
 		}
@@ -262,7 +326,7 @@
 	for (i = 15; i > 0; i--) {
 		if (irqs & (1 << i) & irqmask) {
 			irqs ^= (1 << i);
-			free_irq(i);
+			free_irq(i, NULL);
 		}
 	}
 #ifdef DEBUG
@@ -278,7 +342,7 @@
 	irqmask = (((unsigned int)cache_A1)<<8) | (unsigned int)cache_21;
 	for (i = 15; i > 0; i--) {
 		if (irqs & (1 << i)) {
-			free_irq(i);
+			free_irq(i, NULL);
 		}
 	}
 #ifdef DEBUG
@@ -317,7 +381,7 @@
 			outb_p(LATCH & 0xff , 0x40);	/* LSB */
 			outb(LATCH >> 8 , 0x40);	/* MSB */
 
-			if (request_irq(2, no_action, SA_INTERRUPT, "cascade"))
+			if (request_irq(2, no_action, SA_INTERRUPT, "cascade", NULL))
 				printk("Unable to get IRQ2 for cascade\n");
 			break;
 		default:
diff -u --recursive --new-file v1.3.69/linux/arch/ppc/kernel/irq.c linux/arch/ppc/kernel/irq.c
--- v1.3.69/linux/arch/ppc/kernel/irq.c	Mon Nov 27 12:48:26 1995
+++ linux/arch/ppc/kernel/irq.c	Fri Mar  1 07:50:38 1996
@@ -24,6 +24,7 @@
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/timex.h>
+#include <linux/malloc.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -72,37 +73,34 @@
 /*
  * Irq handlers.
  */
-struct irqaction {
-	void (*handler)(int, struct pt_regs *);
-	unsigned long flags;
-	unsigned long mask;
-	const char *name;
-	int notified;
-};
-
-static struct irqaction irq_action[16] = {
-	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
-	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
-	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
-	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
-	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
-	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
-	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
-	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }
+static struct irqaction timer_irq = { NULL, 0, 0, NULL, NULL, NULL};
+static struct irqaction cascade_irq = { NULL, 0, 0, NULL, NULL, NULL};
+static struct irqaction math_irq = { NULL, 0, 0, NULL, NULL, NULL};
+
+static struct irqaction *irq_action[16] = {
+	  NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL,
+	  NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL
 };
 
 int get_irq_list(char *buf)
 {
 	int i, len = 0;
-	struct irqaction * action = irq_action;
+	struct irqaction * action;
 
-	for (i = 0 ; i < 16 ; i++, action++) {
-		if (!action->handler)
-			continue;
-		len += sprintf(buf+len, "%2d: %8d %c %s\n",
+	for (i = 0 ; i < 16 ; i++) {
+	        action = *(i + irq_action);
+		if (!action) 
+		        continue;
+		len += sprintf(buf+len, "%2d: %8d %c %s",
 			i, kstat.interrupts[i],
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
 			action->name);
+		for (action=action->next; action; action = action->next) {
+			len += sprintf(buf+len, ",%s %s",
+				(action->flags & SA_INTERRUPT) ? " +" : "",
+				action->name);
+		}
+		len += sprintf(buf+len, "\n");
 	}
 	return len;
 }
@@ -110,7 +108,7 @@
 asmlinkage void handle_IRQ(struct pt_regs *regs)
 {
 	int irq, s;
-	struct irqaction *action;
+	struct irqaction * action;
 	intr_count++;
 	/* Figure out IRQ#, etc. */
 	outb(0x0C, 0x20);  /* Poll interrupt controller */
@@ -134,14 +132,17 @@
 		outb(cache_21 | (1<<irq), 0x21);
 		outb(0x20, 0x20);
 	}
-	action = irq + irq_action;
+	action = *(irq + irq_action);
 	kstat.interrupts[irq]++;
-	if (action->handler)
-	{
-		action->handler(irq, regs);
-	} else
-	{
+	while (action) {
+	    if (action->handler)
+	    {
+		action->handler(irq, action->dev_id, regs);
+	    } else
+	    {
 		_printk("Bogus interrupt #%d\n", irq);
+	    }
+	    action = action->next;
 	}
 	if (_disable_interrupts() && !action->notified)
 	{
@@ -202,10 +203,13 @@
 
 #define SA_PROBE SA_ONESHOT
 
-int request_irq(unsigned int irq, void (*handler)(int, struct pt_regs *),
-	unsigned long irqflags, const char * devname)
+int request_irq(unsigned int irq, 
+		void (*handler)(int, void *, struct pt_regs *),
+		unsigned long irqflags, 
+		const char * devname,
+		void *dev_id)
 {
-	struct irqaction * action;
+	struct irqaction * action, *tmp = NULL;
 	unsigned long flags;
 
 #if 0
@@ -214,41 +218,73 @@
 #endif
 	if (irq > 15)
 		return -EINVAL;
-	action = irq + irq_action;
-	if (action->handler)
-		return -EBUSY;
 	if (!handler)
-		return -EINVAL;
+	    return -EINVAL;
+	action = *(irq + irq_action);
+	if (action) {
+	    if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) {
+		for (tmp = action; tmp->next; tmp = tmp->next);
+	    } else {
+		return -EBUSY;
+	    }
+	    if ((action->flags & SA_INTERRUPT) ^ (irqflags & SA_INTERRUPT)) {
+	      printk("Attempt to mix fast and slow interrupts on IRQ%d denied\n", irq);
+	      return -EBUSY;
+	    }   
+	}
 	save_flags(flags);
 	cli();
+	if (irq == 2)
+	    action = &cascade_irq;
+	else if (irq == 13)
+	  action = &math_irq;
+	else if (irq == TIMER_IRQ)
+	  action = &timer_irq;
+	else
+	  action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+
+	if (!action) { 
+	    restore_flags(flags);
+	    return -ENOMEM;
+	}
+
 	action->handler = handler;
 	action->flags = irqflags;
 	action->mask = 0;
 	action->name = devname;
+	action->next = NULL;
+	action->dev_id = dev_id;
+
+	if (tmp) {
+	    tmp->next = action;
+	} else {
+	    *(irq + irq_action) = action;
 #if 0	
-	if (!(action->flags & SA_PROBE)) { /* SA_ONESHOT is used by probing */
+	    if (!(action->flags & SA_PROBE)) { /* SA_ONESHOT is used by probing */
 		if (action->flags & SA_INTERRUPT)
-			set_intr_gate(0x20+irq,fast_interrupt[irq]);
+		  set_intr_gate(0x20+irq,fast_interrupt[irq]);
 		else
-			set_intr_gate(0x20+irq,interrupt[irq]);
-	}
+		  set_intr_gate(0x20+irq,interrupt[irq]);
+	    }
 #endif	
-	if (irq < 8) {
+	    if (irq < 8) {
 		cache_21 &= ~(1<<irq);
 		outb(cache_21,0x21);
-	} else {
+	    } else {
 		cache_21 &= ~(1<<2);
 		cache_A1 &= ~(1<<(irq-8));
 		outb(cache_21,0x21);
 		outb(cache_A1,0xA1);
+	    }
 	}
 	restore_flags(flags);
 	return 0;
 }
 		
-void free_irq(unsigned int irq)
+void free_irq(unsigned int irq, void *dev_id)
 {
-	struct irqaction * action = irq + irq_action;
+	struct irqaction * action = *(irq + irq_action);
+	struct irqaction * tmp = NULL;
 	unsigned long flags;
 
 	if (irq > 15) {
@@ -259,26 +295,49 @@
 		printk("Trying to free free IRQ%d\n",irq);
 		return;
 	}
+	if (dev_id) {
+	    for (; action; action = action->next) {
+	        if (action->dev_id == dev_id) break;
+		tmp = action;
+	    }
+	    if (!action) {
+		printk("Trying to free free shared IRQ%d\n",irq);
+		return;
+	    }
+	} else if (action->flags & SA_SHIRQ) {
+	    printk("Trying to free shared IRQ%d with NULL device ID\n", irq);
+	    return;
+	}
 	save_flags(flags);
 	cli();
-	if (irq < 8) {
+	if (action && tmp) {
+	    tmp->next = action->next;
+	} else {
+	    *(irq + irq_action) = action->next;
+	}
+
+	if ((irq == 2) || (irq == 13) | (irq == TIMER_IRQ))
+	  memset(action, 0, sizeof(struct irqaction));
+	else 
+	  kfree_s(action, sizeof(struct irqaction));
+	
+	if (!(*(irq + irq_action))) {
+	    if (irq < 8) {
 		cache_21 |= 1 << irq;
 		outb(cache_21,0x21);
-	} else {
+	    } else {
 		cache_A1 |= 1 << (irq-8);
 		outb(cache_A1,0xA1);
-	}
+	    }
 #if 0	
-	set_intr_gate(0x20+irq,bad_interrupt[irq]);
+	    set_intr_gate(0x20+irq,bad_interrupt[irq]);
 #endif	
-	action->handler = NULL;
-	action->flags = 0;
-	action->mask = 0;
-	action->name = NULL;
+	}
+
 	restore_flags(flags);
 }
 
-static void no_action(int cpl, struct pt_regs * regs) { }
+static void no_action(int cpl, void *dev_id, struct pt_regs * regs) { }
 
 unsigned /*int*/ long probe_irq_on (void)
 {
@@ -287,7 +346,7 @@
 
 	/* first, snaffle up any unassigned irqs */
 	for (i = 15; i > 0; i--) {
-		if (!request_irq(i, no_action, SA_PROBE, "probe")) {
+		if (!request_irq(i, no_action, SA_PROBE, "probe", NULL)) {
 			enable_irq(i);
 			irqs |= (1 << i);
 		}
@@ -301,7 +360,7 @@
 	for (i = 15; i > 0; i--) {
 		if (irqs & (1 << i) & irqmask) {
 			irqs ^= (1 << i);
-			free_irq(i);
+			free_irq(i, NULL);
 		}
 	}
 #ifdef DEBUG
@@ -317,7 +376,7 @@
 	irqmask = (((unsigned int)cache_A1)<<8) | (unsigned int)cache_21;
 	for (i = 15; i > 0; i--) {
 		if (irqs & (1 << i)) {
-			free_irq(i);
+			free_irq(i, NULL);
 		}
 	}
 #ifdef DEBUG
@@ -347,7 +406,7 @@
 	outb_p(0x34,0x43);		/* binary, mode 2, LSB/MSB, ch 0 */
 	outb_p(LATCH & 0xff , 0x40);	/* LSB */
 	outb(LATCH >> 8 , 0x40);	/* MSB */
-	if (request_irq(2, no_action, SA_INTERRUPT, "cascade"))
+	if (request_irq(2, no_action, SA_INTERRUPT, "cascade", NULL))
 		printk("Unable to get IRQ2 for cascade\n");
 	request_region(0x20,0x20,"pic1");
 	request_region(0xa0,0x20,"pic2");
diff -u --recursive --new-file v1.3.69/linux/arch/sparc/kernel/irq.c linux/arch/sparc/kernel/irq.c
--- v1.3.69/linux/arch/sparc/kernel/irq.c	Sat Nov 25 19:04:36 1995
+++ linux/arch/sparc/kernel/irq.c	Fri Mar  1 07:50:38 1996
@@ -16,6 +16,7 @@
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/interrupt.h>
+#include <linux/malloc.h>
 
 #include <asm/ptrace.h>
 #include <asm/processor.h>
@@ -143,62 +144,79 @@
 /*
  * Initial irq handlers.
  */
-struct irqaction {
-	void (*handler)(int, struct pt_regs *);
-	unsigned long flags;
-	unsigned long mask;
-	const char *name;
-};
-
-static struct irqaction irq_action[16] = {
-  { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
-  { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
-  { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
-  { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
-  { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
-  { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
-  { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
-  { NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }
+static struct irqaction timer_irq = { NULL, 0, 0, NULL, NULL, NULL};
+static struct irqaction cascade_irq = { NULL, 0, 0, NULL, NULL, NULL};
+static struct irqaction math_irq = { NULL, 0, 0, NULL, NULL, NULL};
+
+static struct irqaction *irq_action[16] = {
+	  NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL,
+	  NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL
 };
 
-
 int
 get_irq_list(char *buf)
 {
 	int i, len = 0;
-	struct irqaction * action = irq_action;
+	struct irqaction * action;
 
-	for (i = 0 ; i < 16 ; i++, action++) {
-		if (!action->handler)
-			continue;
-		len += sprintf(buf+len, "%2d: %8d %c %s\n",
-			       i, kstat.interrupts[i],
-			       (action->flags & SA_INTERRUPT) ? '+' : ' ',
-			       action->name);
+	for (i = 0 ; i < 16 ; i++) {
+	        action = *(i + irq_action);
+		if (!action) 
+		        continue;
+		len += sprintf(buf+len, "%2d: %8d %c %s",
+			i, kstat.interrupts[i],
+			(action->flags & SA_INTERRUPT) ? '+' : ' ',
+			action->name);
+		for (action=action->next; action; action = action->next) {
+			len += sprintf(buf+len, ",%s %s",
+				(action->flags & SA_INTERRUPT) ? " +" : "",
+				action->name);
+		}
+		len += sprintf(buf+len, "\n");
 	}
 	return len;
 }
 
 void
-free_irq(unsigned int irq)
+free_irq(unsigned int irq, void *dev_id)
 {
-        struct irqaction * action = irq + irq_action;
+	struct irqaction * action = *(irq + irq_action);
+	struct irqaction * tmp = NULL;
         unsigned long flags;
 
         if (irq > 14) {  /* 14 irq levels on the sparc */
                 printk("Trying to free bogus IRQ %d\n", irq);
                 return;
         }
-        if (!action->handler) {
-                printk("Trying to free free IRQ%d\n", irq);
-                return;
-        }
+	if (!action->handler) {
+		printk("Trying to free free IRQ%d\n",irq);
+		return;
+	}
+	if (dev_id) {
+	    for (; action; action = action->next) {
+	        if (action->dev_id == dev_id) break;
+		tmp = action;
+	    }
+	    if (!action) {
+		printk("Trying to free free shared IRQ%d\n",irq);
+		return;
+	    }
+	} else if (action->flags & SA_SHIRQ) {
+	    printk("Trying to free shared IRQ%d with NULL device ID\n", irq);
+	    return;
+	}
         save_flags(flags); cli();
-        disable_irq(irq);
-        action->handler = NULL;
-        action->flags = 0;
-        action->mask = 0;
-        action->name = NULL;
+	if (action && tmp) {
+	    tmp->next = action->next;
+	} else {
+	    *(irq + irq_action) = action->next;
+	}
+	kfree_s(action, sizeof(struct irqaction));
+
+	if (!(*(irq + irq_action))) {
+	    disable_irq(irq);
+	}
+
         restore_flags(flags);
 }
 
@@ -206,15 +224,16 @@
 unexpected_irq(int irq, struct pt_regs * regs)
 {
         int i;
+	struct irqaction * action = *(irq + irq_action);
 
         printk("IO device interrupt, irq = %d\n", irq);
         printk("PC = %08lx NPC = %08lx FP=%08lx\n", regs->pc, 
 		    regs->npc, regs->u_regs[14]);
         printk("Expecting: ");
         for (i = 0; i < 16; i++)
-                if (irq_action[i].handler)
-                        prom_printf("[%s:%d:0x%x] ", irq_action[i].name, (int) i,
-			       (unsigned int) irq_action[i].handler);
+                if (action->handler)
+                        prom_printf("[%s:%d:0x%x] ", action->name, (int) i,
+			       (unsigned int) action->handler);
         printk("AIEEE\n");
 	panic("bogus interrupt received");
 }
@@ -222,13 +241,16 @@
 void
 handler_irq(int irq, struct pt_regs * regs)
 {
-	struct irqaction * action = irq_action + irq;
+	struct irqaction * action = *(irq + irq_action);
 
 	kstat.interrupts[irq]++;
-	if (!action->handler)
-		unexpected_irq(irq, regs);
-	else
-		action->handler(irq, regs);
+	while (action) {
+	    if (!action->handler)
+	        unexpected_irq(irq, action->dev_id, regs);
+	    else
+		action->handler(irq, action->dev_id, regs);
+	    action = action->next;
+	}
 }
 
 /*
@@ -241,10 +263,13 @@
 asmlinkage void
 do_IRQ(int irq, struct pt_regs * regs)
 {
-	struct irqaction *action = irq + irq_action;
+	struct irqaction * action = *(irq + irq_action);
 
 	kstat.interrupts[irq]++;
-	action->handler(irq, regs);
+	while (action) {
+	    action->handler(irq, action->dev_id, regs);
+	    action = action->next;
+	}
 	return;
 }
 
@@ -263,21 +288,38 @@
 
 int
 request_fast_irq(unsigned int irq, void (*handler)(int, struct pt_regs *),
-		 unsigned long irqflags, const char *devname)
+		 unsigned long irqflags, const char *devname, void *dev_id)
+)
 {
-	struct irqaction *action;
+	struct irqaction * action, *tmp = NULL;
 	unsigned long flags;
 
 	if(irq > 14)
 		return -EINVAL;
-	action = irq + irq_action;
-	if(action->handler)
+	if (!handler)
+	    return -EINVAL;
+	action = *(irq + irq_action);
+	if (action) {
+	    if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) {
+		for (tmp = action; tmp->next; tmp = tmp->next);
+	    } else {
 		return -EBUSY;
-	if(!handler)
-		return -EINVAL;
+	    }
+	    if ((action->flags & SA_INTERRUPT) ^ (irqflags & SA_INTERRUPT)) {
+	      printk("Attempt to mix fast and slow interrupts on IRQ%d denied\n", irq);
+	      return -EBUSY;
+	    }   
+	}
 
 	save_flags(flags); cli();
 
+	action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+
+	if (!action) { 
+	    restore_flags(flags);
+	    return -ENOMEM;
+	}
+
 	/* Dork with trap table if we get this far. */
 	sparc_ttable[SP_TRAP_IRQ1+(irq-1)].inst_one =
 		SPARC_BRANCH((unsigned long) handler,
@@ -290,6 +332,13 @@
 	action->flags = irqflags;
 	action->mask = 0;
 	action->name = devname;
+	action->dev_id = dev_id;
+
+	if (tmp) {
+	    tmp->next = action;
+	} else {
+	    *(irq + irq_action) = action;
+	}
 
 	restore_flags(flags);
 	return 0;
@@ -299,25 +348,48 @@
 		
 int
 request_irq(unsigned int irq, void (*handler)(int, struct pt_regs *),
-	    unsigned long irqflags, const char * devname)
+	    unsigned long irqflags, const char * devname, void *dev_id)
 {
-	struct irqaction *action;
+	struct irqaction * action, *tmp = NULL;
 	unsigned long flags;
 
 	if(irq > 14)
 		return -EINVAL;
 
-	action = irq + irq_action;
-	if(action->handler)
+	if (!handler)
+	    return -EINVAL;
+	action = *(irq + irq_action);
+	if (action) {
+	    if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) {
+		for (tmp = action; tmp->next; tmp = tmp->next);
+	    } else {
 		return -EBUSY;
-	if(!handler)
-		return -EINVAL;
-
+	    }
+	    if ((action->flags & SA_INTERRUPT) ^ (irqflags & SA_INTERRUPT)) {
+	      printk("Attempt to mix fast and slow interrupts on IRQ%d denied\n", irq);
+	      return -EBUSY;
+	    }   
+	}
 	save_flags(flags); cli();
+	action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+
+	if (!action) { 
+	    restore_flags(flags);
+	    return -ENOMEM;
+	}
+
 	action->handler = handler;
 	action->flags = irqflags;
 	action->mask = 0;
 	action->name = devname;
+	action->next = NULL;
+	action->dev_id = dev_id;
+
+	if (tmp) {
+	    tmp->next = action;
+	} else {
+	    *(irq + irq_action) = action;
+	}
 	enable_irq(irq);
 	if(irq == 10)
 		probe_clock();
diff -u --recursive --new-file v1.3.69/linux/drivers/block/Config.in linux/drivers/block/Config.in
--- v1.3.69/linux/drivers/block/Config.in	Wed Feb 28 11:50:00 1996
+++ linux/drivers/block/Config.in	Wed Feb 28 08:42:32 1996
@@ -21,11 +21,11 @@
   bool '   Other IDE chipset support' CONFIG_IDE_CHIPSETS
   if [ "$CONFIG_IDE_CHIPSETS" = "y" ]; then
     comment 'Note: most of these also require special kernel boot parameters'
-    bool '      DTC-2278        chipset support' CONFIG_BLK_DEV_DTC2278
-    bool '      Holtek HT6560B  chipset support' CONFIG_BLK_DEV_HT6560B
-    bool '      QDI QD6580      chipset support' CONFIG_BLK_DEV_QD6580
-    bool '      UMC 8672        chipset support' CONFIG_BLK_DEV_UMC8672
-    bool '      ALI M1439/M1445 chipset support' CONFIG_BLK_DEV_ALI14XX
+    bool '      DTC-2278        support' CONFIG_BLK_DEV_DTC2278
+    bool '      Holtek HT6560B  support' CONFIG_BLK_DEV_HT6560B
+    bool '      QDI QD6580      support' CONFIG_BLK_DEV_QD6580
+    bool '      UMC 8672        support' CONFIG_BLK_DEV_UMC8672
+    bool '      ALI M1439/M1445 support' CONFIG_BLK_DEV_ALI14XX
   fi
 fi
 
diff -u --recursive --new-file v1.3.69/linux/drivers/block/README.hd linux/drivers/block/README.hd
--- v1.3.69/linux/drivers/block/README.hd	Thu Aug  4 08:35:02 1994
+++ linux/drivers/block/README.hd	Wed Feb 28 08:42:32 1996
@@ -5,4 +5,4 @@
 The hdparm.c program for controlling various features is now packaged
 separately.  Look for it on your favorite linux FTP site.
 
--mlord@bnr.ca
+-mlord@pobox.com
diff -u --recursive --new-file v1.3.69/linux/drivers/block/README.ide linux/drivers/block/README.ide
--- v1.3.69/linux/drivers/block/README.ide	Wed Feb 14 14:37:07 1996
+++ linux/drivers/block/README.ide	Wed Feb 28 08:42:32 1996
@@ -1,6 +1,6 @@
 README.ide -- Information regarding ide.c and ide-cd.c (IDE driver in 1.3.xx)
 ================================================================================
-Supported by:  mlord@bnr.ca           -- disks, interfaces, probing
+Supported by:  mlord@pobox.com        -- disks, interfaces, probing
                snyder@fnald0.fnal.gov -- cdroms, ATAPI, audio
 
    +-----------------------------------------------------------------+
@@ -58,7 +58,7 @@
 NEW!    - ide-cd.c now supports door locking and auto-loading.
 		- Also preliminary support for multisession
 		  and direct reads of audio data.
-NEW!	- the hdparm-2.6 package can be used to set PIO modes for some chipsets.
+NEW!	- the hdparm-2.7 package can be used to set PIO modes for some chipsets.
 
 For work in progress, see the comments in ide.c, ide-cd.c, and triton.c.
 
@@ -67,24 +67,6 @@
 Look for this support to be added to the kernel soon.
 
 
-***  IMPORTANT NOTICES (for kernel versions prior to 1.3.22)
-***  =================
-***  "CMD" EIDE Interfaces will not (by default) work *reliably* when drives
-***  are attached to the second interface.  This is due to a flaw in the
-***  hardware.  To "fix" this, supply the special kernel "command line"
-***  parameter to LILO or LOADLIN:    ide1=serialize
-***
-***  "CMD 640B" EIDE Interfaces will not work *reliably* when "hdparm -u1"
-***  (interrupt unmasking) is used.  This is due to a flaw in the hardware,
-***  and is only a problem when "hdparm -u1" is used after booting.
-***
-***  "RZ1000" EIDE Interfaces will also not work *reliably* when "hdparm -u1"
-***  (interrupt unmasking) is used.  This is due to a flaw in the hardware,
-***  and is only a problem when "hdparm -u1" is used after booting.
-***
-***  Failure to abide by these restrictions can cause severe data corruption!
-
-
 ***  IMPORTANT NOTICES (for kernel versions after 1.3.21)
 ***  =================
 ***  PCI versions of the CMD640 and RZ1000 interfaces are now detected
@@ -216,7 +198,7 @@
 under control of ide.c.   To have ide.c also "take over" the primary
 IDE port in this situation, use the "command line" parameter:  ide0=0x1f0
 
-mlord@bnr.ca
+mlord@pobox.com
 snyder@fnald0.fnal.gov
 ================================================================================
 
@@ -448,7 +430,7 @@
 
 For really high end systems, go for fast/wide 7200rpm SCSI.  But it'll cost ya!
 
-mlord@bnr.ca
+mlord@pobox.com
 
 ================================================================================
 EIDE card compatibility reports:
diff -u --recursive --new-file v1.3.69/linux/drivers/block/cmd640.c linux/drivers/block/cmd640.c
--- v1.3.69/linux/drivers/block/cmd640.c	Wed Feb 14 14:37:07 1996
+++ linux/drivers/block/cmd640.c	Wed Feb 28 08:42:32 1996
@@ -482,6 +482,7 @@
 	const char* 	name;
 	int		mode;	
 } drives_ra[] = {
+        { "QUANTUM LIGHTNING 540A", 0 },
         { "ST3655A",	0 },
         { "SAMSUNG",	0 },	/* Be conservative */
  	{ NULL, 0 }
diff -u --recursive --new-file v1.3.69/linux/drivers/block/dtc2278.c linux/drivers/block/dtc2278.c
--- v1.3.69/linux/drivers/block/dtc2278.c	Wed Feb 14 14:37:07 1996
+++ linux/drivers/block/dtc2278.c	Wed Feb 28 08:42:32 1996
@@ -33,9 +33,19 @@
  * /dev/hd.. ) for the drives connected to the EIDE interface. (I get my
  * filesystem  corrupted with -u1, but under heavy disk load only :-)
  *
- * This chipset is now forced to use the "serialize" feature,
+ * This card is now forced to use the "serialize" feature,
  * and irq-unmasking is disallowed.  If io_32bit is enabled,
  * it must be done for BOTH drives on each interface.
+ *
+ * This code was written for the DTC2278E, but might work with any of these:
+ *
+ * DTC2278S has only a single IDE interface.
+ * DTC2278D has two IDE interfaces and is otherwise identical to the S version.
+ * DTC2278E has onboard BIOS, while the others do not.
+ *
+ * There may be a fourth controller type. The S and D versions use the
+ * Winbond chip, and I think the E version does also.
+ *
  */
 
 static void sub22 (char b, char c)
diff -u --recursive --new-file v1.3.69/linux/drivers/block/floppy.c linux/drivers/block/floppy.c
--- v1.3.69/linux/drivers/block/floppy.c	Sat Feb 17 16:02:46 1996
+++ linux/drivers/block/floppy.c	Fri Mar  1 07:50:39 1996
@@ -1586,7 +1586,7 @@
 { 0, 0, (void *) (void *) unexpected_floppy_interrupt, 0 };
 
 /* interrupt handler */
-static void floppy_interrupt(int irq, struct pt_regs * regs)
+static void floppy_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
 	void (*handler)(void) = DEVICE_INTR;
 
@@ -2085,6 +2085,7 @@
 		DPRINT("request list destroyed in floppy request done\n");
 		return;
 	}
+
 	if (uptodate){
 		/* maintain values for invalidation on geometry
 		 * change */
diff -u --recursive --new-file v1.3.69/linux/drivers/block/genhd.c linux/drivers/block/genhd.c
--- v1.3.69/linux/drivers/block/genhd.c	Fri Feb  9 17:53:00 1996
+++ linux/drivers/block/genhd.c	Wed Feb 28 08:42:32 1996
@@ -8,7 +8,7 @@
  *  Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug
  *  in the early extended-partition checks and added DM partitions
  *
- *  Support for DiskManager v6.0x added by Mark Lord (mlord@bnr.ca)
+ *  Support for DiskManager v6.0x added by Mark Lord,
  *  with information provided by OnTrack.  This now works for linux fdisk
  *  and LILO, as well as loadlin and bootln.  Note that disks other than
  *  /dev/hda *must* have a "DOS" type 0x51 partition in the first slot (hda1).
@@ -54,37 +54,49 @@
 extern int scsi_dev_init(void);
 extern int net_dev_init(void);
 
-static void print_minor_name (struct gendisk *hd, int minor)
+/*
+ * disk_name() is used by genhd.c and md.c.
+ * It formats the devicename of the indicated disk
+ * into the supplied buffer, and returns a pointer
+ * to that same buffer (for convenience).
+ */
+char *disk_name (struct gendisk *hd, int minor, char *buf)
 {
-	unsigned int unit = minor >> hd->minor_shift;
-	unsigned int part = minor & ((1 << hd->minor_shift) - 1);
+	unsigned int part;
+	const char *maj = hd->major_name;
+	char unit = (minor >> hd->minor_shift) + 'a';
 
 #ifdef CONFIG_BLK_DEV_IDE
 	/*
 	 * IDE devices use multiple major numbers, but the drives
 	 * are named as:  {hda,hdb}, {hdc,hdd}, {hde,hdf}, {hdg,hdh}..
-	 * This requires some creative handling here to find the
-	 * correct name to use, with some help from ide.c
+	 * This requires special handling here.
 	 */
-	if (!strcmp(hd->major_name,"ide")) {
-		char name[16];		/* more than large enough */
-		strcpy(name, hd->real_devices); /* courtesy ide.c */
-		name[strlen(name)-1] += unit;
-		printk(" %s", name);
-	} else
+	switch (hd->major) {
+		case IDE3_MAJOR:
+			unit += 2;
+		case IDE2_MAJOR:
+			unit += 2;
+		case IDE1_MAJOR:
+			unit += 2;
+		case IDE0_MAJOR:
+			maj = "hd";
+	}
 #endif
-		printk(" %s%c", hd->major_name, 'a' + unit);
+	part = minor & ((1 << hd->minor_shift) - 1);
 	if (part)
-		printk("%d", part);
+		sprintf(buf, "%s%c%d", maj, unit, part);
 	else
-		printk(":");
+		sprintf(buf, "%s%c", maj, unit);
+	return buf;
 }
 
 static void add_partition (struct gendisk *hd, int minor, int start, int size)
 {
+	char buf[8];
 	hd->part[minor].start_sect = start;
 	hd->part[minor].nr_sects   = size;
-	print_minor_name(hd, minor);
+	printk(" %s", disk_name(hd, minor, buf));
 }
 
 static inline int is_extended_partition(struct partition *p)
@@ -482,6 +494,7 @@
 {
 	static int first_time = 1;
 	unsigned long first_sector;
+	char buf[8];
 
 	if (first_time)
 		printk("Partition check:\n");
@@ -497,8 +510,7 @@
 		return;
 	}
 
-	printk(" ");
-	print_minor_name(hd, MINOR(dev));
+	printk(" %s:", disk_name(hd, MINOR(dev), buf));
 #ifdef CONFIG_MSDOS_PARTITION
 	if (msdos_partition(hd, dev, first_sector))
 		return;
diff -u --recursive --new-file v1.3.69/linux/drivers/block/hd.c linux/drivers/block/hd.c
--- v1.3.69/linux/drivers/block/hd.c	Mon Oct 23 18:02:03 1995
+++ linux/drivers/block/hd.c	Fri Mar  1 07:50:39 1996
@@ -16,7 +16,7 @@
  *  in the early extended-partition checks and added DM partitions
  *
  *  IRQ-unmask, drive-id, multiple-mode, support for ">16 heads",
- *  and general streamlining by mlord@bnr.ca (Mark Lord).
+ *  and general streamlining by Mark Lord.
  */
 
 #define DEFAULT_MULT_COUNT  0	/* set to 0 to disable multiple mode at boot */
@@ -930,7 +930,7 @@
 	NULL		/* next */
 };
 	
-static void hd_interrupt(int irq, struct pt_regs *regs)
+static void hd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	void (*handler)(void) = DEVICE_INTR;
 
@@ -1020,7 +1020,7 @@
 		special_op[i] = 1;
 	}
 	if (NR_HD) {
-		if (request_irq(HD_IRQ, hd_interrupt, SA_INTERRUPT, "hd")) {
+		if (request_irq(HD_IRQ, hd_interrupt, SA_INTERRUPT, "hd", NULL)) {
 			printk("hd: unable to get IRQ%d for the harddisk driver\n",HD_IRQ);
 			NR_HD = 0;
 		} else {
diff -u --recursive --new-file v1.3.69/linux/drivers/block/ide.c linux/drivers/block/ide.c
--- v1.3.69/linux/drivers/block/ide.c	Wed Feb 14 14:37:08 1996
+++ linux/drivers/block/ide.c	Fri Mar  1 07:50:39 1996
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/block/ide.c	Version 5.28  Feb 11, 1996
+ *  linux/drivers/block/ide.c	Version 5.30  Feb 27, 1996
  *
  *  Copyright (C) 1994-1996  Linus Torvalds & authors (see below)
  */
@@ -45,16 +45,16 @@
  *  | Early work on error handling by Mika Liljeberg (liljeber@cs.Helsinki.FI).
  *  |
  *  | IRQ-unmask, drive-id, multiple-mode, support for ">16 heads",
- *  | and general streamlining by Mark Lord (mlord@bnr.ca).
+ *  | and general streamlining by Mark Lord (mlord@pobox.com).
  *
  *  October, 1994 -- Complete line-by-line overhaul for linux 1.1.x, by:
  *
- *	Mark Lord	(mlord@bnr.ca)			(IDE Perf.Pkg)
+ *	Mark Lord	(mlord@pobox.com)		(IDE Perf.Pkg)
  *	Delman Lee	(delman@mipg.upenn.edu)		("Mr. atdisk2")
  *	Petri Mattila	(ptjmatti@kruuna.helsinki.fi)	(EIDE stuff)
  *	Scott Snyder	(snyder@fnald0.fnal.gov)	(ATAPI IDE cd-rom)
  *
- *  Maintained by Mark Lord (mlord@bnr.ca):  ide.c, ide.h, triton.c, hd.c, ..
+ *  Maintained by Mark Lord (mlord@pobox.com):  ide.c, ide.h, triton.c, hd.c, ..
  *
  *  This was a rewrite of just about everything from hd.c, though some original
  *  code is still sprinkled about.  Think of it as a major evolution, with
@@ -205,6 +205,9 @@
  *			force io_32bit to be the same on drive pairs of dtc2278
  *			improved IDE tape error handling, and tape DMA support
  *			bugfix in ide_do_drive_cmd() for cdroms + serialize
+ * Version 5.29		fixed non-IDE check for too many physical heads
+ *			don't use LBA if capacity is smaller than CHS
+ * Version 5.30		remove real_devices kludge, formerly used by genhd.c
  *
  *  Some additional driver compile-time options are in ide.h
  *
@@ -470,19 +473,19 @@
 static unsigned long current_capacity (ide_drive_t  *drive)
 {
 	struct hd_driveid *id = drive->id;
-	unsigned long capacity;
+	unsigned long capacity = drive->cyl * drive->head * drive->sect;
 
 	if (!drive->present)
 		return 0;
 	if (drive->media != ide_disk)
 		return 0x7fffffff;	/* cdrom or tape */
+	drive->select.b.lba = 0;
 	/* Determine capacity, and use LBA if the drive properly supports it */
 	if (id != NULL && (id->capability & 2) && lba_capacity_is_ok(id)) {
-		drive->select.b.lba = 1;
-		capacity = id->lba_capacity;
-	} else {
-		drive->select.b.lba = 0;
-		capacity = drive->cyl * drive->head * drive->sect;
+		if (id->lba_capacity >= capacity) {
+			capacity = id->lba_capacity;
+			drive->select.b.lba = 1;
+		}
 	}
 	return (capacity - drive->sect0);
 }
@@ -511,13 +514,6 @@
 			drive->part[0].start_sect = -1; /* skip partition check */
 		}
 	}
-	/*
-	 * The partition check in genhd.c needs this string to identify
-	 * our minor devices by name for display purposes.
-	 * Note that doing this will prevent us from working correctly
-	 * if ever called a second time for this major (never happens).
-	 */
-	gd->real_devices = hwif->drives[0].name;  /* name of first drive */
 }
 
 /*
@@ -619,6 +615,7 @@
 		if ((tmp = GET_ERR()) == 1)
 			printk("success\n");
 		else {
+#if FANCY_STATUS_DUMPS
 			printk("master: ");
 			switch (tmp & 0x7f) {
 				case 1: printk("passed");
@@ -636,6 +633,9 @@
 			if (tmp & 0x80)
 				printk("; slave: failed");
 			printk("\n");
+#else
+			printk("failed\n");
+#endif /* FANCY_STATUS_DUMPS */
 		}
 	}
 	hwgroup->poll_timeout = 0;	/* done polling */
@@ -1154,8 +1154,9 @@
 		} else
 			drive->mult_req = 0;
 	} else if (s->all) {
+		int special = s->all;
 		s->all = 0;
-		printk("%s: bad special flag: 0x%02x\n", drive->name, s->all);
+		printk("%s: bad special flag: 0x%02x\n", drive->name, special);
 	}
 }
 
@@ -1461,20 +1462,26 @@
 	do_hwgroup_request (ide_hwifs[0].hwgroup);
 }
 
+#if MAX_HWIFS > 1
 static void do_ide1_request (void)	/* invoked with cli() */
 {
 	do_hwgroup_request (ide_hwifs[1].hwgroup);
 }
+#endif
 
+#if MAX_HWIFS > 2
 static void do_ide2_request (void)	/* invoked with cli() */
 {
 	do_hwgroup_request (ide_hwifs[2].hwgroup);
 }
+#endif
 
+#if MAX_HWIFS > 3
 static void do_ide3_request (void)	/* invoked with cli() */
 {
 	do_hwgroup_request (ide_hwifs[3].hwgroup);
 }
+#endif
 
 static void timer_expiry (unsigned long data)
 {
@@ -1561,7 +1568,7 @@
 /*
  * entry point for all interrupts, caller does cli() for us
  */
-static void ide_intr (int irq, struct pt_regs *regs)
+static void ide_intr (int irq, void *dev_id, struct pt_regs *regs)
 {
 	ide_hwgroup_t  *hwgroup = irq_to_hwgroup[irq];
 	ide_handler_t  *handler;
@@ -2103,10 +2110,10 @@
 	ide_fixstring (id->fw_rev,    sizeof(id->fw_rev),    bswap);
 	ide_fixstring (id->serial_no, sizeof(id->serial_no), bswap);
 
+#ifdef CONFIG_BLK_DEV_IDEATAPI
 	/*
 	 * Check for an ATAPI device
 	 */
-
 	if (cmd == WIN_PIDENTIFY) {
 		byte type = (id->config >> 8) & 0x1f;
 		printk("%s: %s, ATAPI ", drive->name, id->model);
@@ -2153,6 +2160,7 @@
 		printk("- not supported by this kernel\n");
 		return;
 	}
+#endif /* CONFIG_BLK_DEV_IDEATAPI */
 
 	/* check for removeable disks (eg. SYQUEST), ignore 'WD' drives */
 	if (id->config & (1<<7)) {	/* removeable disk ? */
@@ -2392,24 +2400,16 @@
 #endif	/* CONFIG_BLK_DEV_IDECD */
 		else {
 			drive->present = 0;	/* nuke it */
-			return 1;		/* drive was found */
-		}
-	}
-	if (drive->media == ide_disk && !drive->select.b.lba) {
-		if (!drive->head || drive->head > 16) {
-			printk("%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n",
-			 drive->name, drive->head);
-			drive->present = 0;
 		}
 	}
 	return 1;	/* drive was found */
 }
 
 /*
- *  This routine only knows how to look for drive units 0 and 1
- *  on an interface, so any setting of MAX_DRIVES > 2 won't work here.
+ * This routine only knows how to look for drive units 0 and 1
+ * on an interface, so any setting of MAX_DRIVES > 2 won't work here.
  */
-static void probe_for_drives (ide_hwif_t *hwif)
+static void probe_hwif (ide_hwif_t *hwif)
 {
 	unsigned int unit;
 
@@ -2429,25 +2429,25 @@
 		unsigned long flags;
 		save_flags(flags);
 
-#if (MAX_DRIVES > 2)
-		printk("%s: probing for first 2 of %d possible drives\n", hwif->name, MAX_DRIVES);
-#endif
 		sti();	/* needed for jiffies and irq probing */
 		/*
 		 * Second drive should only exist if first drive was found,
-		 * but a lot of cdrom drives seem to be configured as slave-only
+		 * but a lot of cdrom drives are configured as single slaves.
 		 */
-		for (unit = 0; unit < 2; ++unit) { /* note the hardcoded '2' */
-			ide_drive_t *drive = &hwif->drives[unit];
-			(void) probe_for_drive (drive);
-		}
 		for (unit = 0; unit < MAX_DRIVES; ++unit) {
 			ide_drive_t *drive = &hwif->drives[unit];
-			if (drive->present) {
+			(void) probe_for_drive (drive);
+			if (drive->present && drive->media == ide_disk) {
+				if ((!drive->head || drive->head > 16) && !drive->select.b.lba) {
+					printk("%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n",
+					 drive->name, drive->head);
+					drive->present = 0;
+				}
+			}
+			if (drive->present && !hwif->present) {
 				hwif->present = 1;
 				request_region(hwif->io_base,  8, hwif->name);
 				request_region(hwif->ctl_port, 1, hwif->name);
-				break;
 			}
 		}
 		restore_flags(flags);
@@ -2883,7 +2883,7 @@
 	 * Grab the irq if we don't already have it from a previous hwif
 	 */
 	if (hwgroup == NULL)  {
-		if (request_irq(irq, ide_intr, SA_INTERRUPT|SA_SAMPLE_RANDOM, hwif->name)) {
+		if (request_irq(irq, ide_intr, SA_INTERRUPT|SA_SAMPLE_RANDOM, hwif->name, NULL)) {
 			restore_flags(flags);
 			printk(" -- FAILED!");
 			return 1;
@@ -2893,7 +2893,7 @@
 	 * Check for serialization with ide1.
 	 * This code depends on us having already taken care of ide1.
 	 */
-	if (hwif->serialized && hwif->name[3] == '0' && ide_hwifs[1].present)
+	if (hwif->serialized && hwif->index == 0 && ide_hwifs[1].present)
 		hwgroup = ide_hwifs[1].hwgroup;
 	/*
 	 * If this is the first interface in a group,
@@ -3025,7 +3025,7 @@
 		if (!hwif->noprobe) {
 			if (hwif->io_base == HD_DATA)
 				probe_cmos_for_drives (hwif);
-			probe_for_drives (hwif);
+			probe_hwif (hwif);
 		}
 		if (hwif->present) {
 			if (!hwif->irq) {
@@ -3055,9 +3055,15 @@
 		hwif->present = 0; /* we set it back to 1 if all is ok below */
 		switch (hwif->major) {
 			case IDE0_MAJOR: rfn = &do_ide0_request; break;
+#if MAX_HWIFS > 1
 			case IDE1_MAJOR: rfn = &do_ide1_request; break;
+#endif
+#if MAX_HWIFS > 2
 			case IDE2_MAJOR: rfn = &do_ide2_request; break;
+#endif
+#if MAX_HWIFS > 3
 			case IDE3_MAJOR: rfn = &do_ide3_request; break;
+#endif
 			default:
 				printk("%s: request_fn NOT DEFINED\n", hwif->name);
 				continue;
diff -u --recursive --new-file v1.3.69/linux/drivers/block/ide.h linux/drivers/block/ide.h
--- v1.3.69/linux/drivers/block/ide.h	Wed Feb 14 14:37:08 1996
+++ linux/drivers/block/ide.h	Fri Mar  1 10:38:34 1996
@@ -126,7 +126,9 @@
 #define PARTN_BITS	6	/* number of minor dev bits for partitions */
 #define PARTN_MASK	((1<<PARTN_BITS)-1)	/* a useful bit mask */
 #define MAX_DRIVES	2	/* per interface; 2 assumed by lots of code */
+#ifndef MAX_HWIFS
 #define MAX_HWIFS	4	/* an arbitrary, but realistic limit */
+#endif
 #define SECTOR_WORDS	(512 / 4)	/* number of 32bit words per sector */
 
 /*
diff -u --recursive --new-file v1.3.69/linux/drivers/block/ide_modes.h linux/drivers/block/ide_modes.h
--- v1.3.69/linux/drivers/block/ide_modes.h	Wed Feb 14 14:37:09 1996
+++ linux/drivers/block/ide_modes.h	Wed Feb 28 08:42:33 1996
@@ -86,6 +86,7 @@
 	{ "QUANTUM LPS270A", 3 },
 	{ "QUANTUM LPS365A", 3 },
 	{ "QUANTUM LPS540A", 3 },
+	{ "QUANTUM LIGHTNING 540A", 3 },
 	{ "QUANTUM FIREBALL", 3 }, /* For models 540/640/1080/1280 */
 				   /* 1080A works fine in mode4 with triton */
 	{ NULL,	0 }
diff -u --recursive --new-file v1.3.69/linux/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c
--- v1.3.69/linux/drivers/block/ll_rw_blk.c	Wed Feb 28 11:50:00 1996
+++ linux/drivers/block/ll_rw_blk.c	Wed Feb 28 08:42:33 1996
@@ -294,6 +294,8 @@
 		if (blk_size[major][MINOR(bh->b_dev)] < (sector + count)>>1) {
 			bh->b_state = 0;
 			printk("attempt to access beyond end of device\n");
+			printk("%s: rw=%d, want=%d, limit=%d\n", kdevname(bh->b_dev),
+			 rw, (sector + count)>>1, blk_size[major][MINOR(bh->b_dev)]);
 			return;
 		}
 	/* Uhhuh.. Nasty dead-lock possible here.. */
diff -u --recursive --new-file v1.3.69/linux/drivers/block/md.c linux/drivers/block/md.c
--- v1.3.69/linux/drivers/block/md.c	Wed Feb 28 11:50:00 1996
+++ linux/drivers/block/md.c	Wed Feb 28 08:42:33 1996
@@ -28,6 +28,7 @@
 #include <linux/fs.h>
 #include <linux/proc_fs.h>
 #include <linux/blkdev.h>
+#include <linux/genhd.h>
 #include <errno.h>
 
 #define MAJOR_NR MD_MAJOR
@@ -94,8 +95,6 @@
   static char name[10];		/* This should be long
 				   enough for a device name ! */
   struct gendisk *hd=find_gendisk (dev);
-  char base_name;
-  int minor=MINOR(dev);
 
   if (!hd)
   {
@@ -104,12 +103,7 @@
     return (name);
   }
 
-  base_name = (hd->major == IDE1_MAJOR) ? 'c' : 'a';
-  sprintf(name, "%s%c%d",
-	  hd->major_name,
-	  base_name + (minor >> hd->minor_shift),
-	  minor & ((1 << hd->minor_shift) - 1));
-  return (name);
+  return disk_name (hd, MINOR(dev), name);  /* routine in genhd.c */
 }
 
 
diff -u --recursive --new-file v1.3.69/linux/drivers/block/rz1000.c linux/drivers/block/rz1000.c
--- v1.3.69/linux/drivers/block/rz1000.c	Wed Feb 14 14:37:09 1996
+++ linux/drivers/block/rz1000.c	Wed Feb 28 08:42:33 1996
@@ -5,7 +5,7 @@
  */
 
 /*
- *  Principal Author/Maintainer:  mlord@bnr.ca (Mark Lord)
+ *  Principal Author/Maintainer:  mlord@pobox.com (Mark Lord)
  *
  *  This file provides support for disabling the buggy read-ahead
  *  mode of the RZ1000 IDE chipset, commonly used on Intel motherboards.
diff -u --recursive --new-file v1.3.69/linux/drivers/block/triton.c linux/drivers/block/triton.c
--- v1.3.69/linux/drivers/block/triton.c	Wed Feb 14 14:37:09 1996
+++ linux/drivers/block/triton.c	Wed Feb 28 08:42:33 1996
@@ -85,7 +85,10 @@
  *	- like most Conner models, this drive proves that even a fast interface
  *	  cannot improve slow media.  Both DMA and PIO peak around 3.5MB/sec.
  *
- * If you have any drive models to add, email your results to:  mlord@bnr.ca
+ *   Maxtor 71260AT (1204Meg w/256kB buffer), DMA mword0/sword2, PIO mode3.
+ *	- works with DMA, giving 3-4MB/sec performance, about the same as mode3.
+ *
+ * If you have any drive models to add, email your results to:  mlord@pobox.com
  * Keep an eye on /var/adm/messages for "DMA disabled" messages.
  *
  * Some people have reported trouble with Intel Zappa motherboards.
@@ -118,6 +121,7 @@
  * known to work fine with this interface under Linux.
  */
 const char *good_dma_drives[] = {"Micropolis 2112A",
+				 "Maxtor 71260 AT",
 				 "CONNER CTMA 4000"};
 
 /*
diff -u --recursive --new-file v1.3.69/linux/drivers/block/xd.c linux/drivers/block/xd.c
--- v1.3.69/linux/drivers/block/xd.c	Mon Oct 23 18:02:04 1995
+++ linux/drivers/block/xd.c	Fri Mar  1 07:50:39 1996
@@ -168,10 +168,10 @@
 		for (i = 0; i < xd_drives; i++)
 			printk("xd_geninit: drive %d geometry - heads = %d, cylinders = %d, sectors = %d\n",i,xd_info[i].heads,xd_info[i].cylinders,xd_info[i].sectors);
 
-		if (!request_irq(xd_irq,xd_interrupt_handler, 0, "XT harddisk")) {
+		if (!request_irq(xd_irq,xd_interrupt_handler, 0, "XT harddisk", NULL)) {
 			if (request_dma(xd_dma,"xd")) {
 				printk("xd_geninit: unable to get DMA%d\n",xd_dma);
-				free_irq(xd_irq);
+				free_irq(xd_irq, NULL);
 			}
 		}
 		else
@@ -391,7 +391,7 @@
 }
 
 /* xd_interrupt_handler: interrupt service routine */
-static void xd_interrupt_handler(int irq, struct pt_regs * regs)
+static void xd_interrupt_handler(int irq, void *dev_id, struct pt_regs * regs)
 {
 	if (inb(XD_STATUS) & STAT_INTERRUPT) {							/* check if it was our device */
 #ifdef DEBUG_OTHER
diff -u --recursive --new-file v1.3.69/linux/drivers/cdrom/cdu31a.c linux/drivers/cdrom/cdu31a.c
--- v1.3.69/linux/drivers/cdrom/cdu31a.c	Wed Feb  7 15:11:21 1996
+++ linux/drivers/cdrom/cdu31a.c	Fri Mar  1 07:50:39 1996
@@ -521,7 +521,7 @@
 }
 
 static void
-cdu31a_interrupt(int irq, struct pt_regs *regs)
+cdu31a_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
    unsigned char val;
 
@@ -3085,7 +3085,7 @@
       
       if (cdu31a_irq > 0)
       {
-	 if (request_irq(cdu31a_irq, cdu31a_interrupt, SA_INTERRUPT, "cdu31a"))
+	 if (request_irq(cdu31a_irq, cdu31a_interrupt, SA_INTERRUPT, "cdu31a", NULL))
 	 {
 	    printk("Unable to grab IRQ%d for the CDU31A driver\n", cdu31a_irq);
 	    cdu31a_irq = 0;
diff -u --recursive --new-file v1.3.69/linux/drivers/cdrom/cm206.c linux/drivers/cdrom/cm206.c
--- v1.3.69/linux/drivers/cdrom/cm206.c	Thu Nov  9 11:23:47 1995
+++ linux/drivers/cdrom/cm206.c	Fri Mar  1 07:50:39 1996
@@ -221,7 +221,7 @@
    as there seems so reason for this to happen.
 */
 
-static void cm206_interrupt(int sig, struct pt_regs * regs) /* you rang? */
+static void cm206_interrupt(int sig, void *dev_id, struct pt_regs * regs) /* you rang? */
 {
   volatile ush fool;
     cd->intr_ds = inw(r_data_status); /* resets data_ready, data_error,
@@ -1052,7 +1052,7 @@
       return;
     }
   case 3: 
-    free_irq(cm206_irq);
+    free_irq(cm206_irq, NULL);
   case 2: 
   case 1: 
     kfree(cd);
@@ -1156,7 +1156,7 @@
   else printk(" single");
   printk(" speed drive");
   if (e & dcf_motorized_tray) printk(", motorized tray");
-  if (request_irq(cm206_irq, cm206_interrupt, 0, "cm206")) {
+  if (request_irq(cm206_irq, cm206_interrupt, 0, "cm206", NULL)) {
     printk("\nUnable to reserve IRQ---aborted\n");
     cleanup(2);
     return -EIO;
diff -u --recursive --new-file v1.3.69/linux/drivers/cdrom/mcd.c linux/drivers/cdrom/mcd.c
--- v1.3.69/linux/drivers/cdrom/mcd.c	Sat Feb 17 16:02:46 1996
+++ linux/drivers/cdrom/mcd.c	Fri Mar  1 07:50:40 1996
@@ -628,7 +628,7 @@
  */
 
 static void
-mcd_interrupt(int irq, struct pt_regs * regs)
+mcd_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
 	int st;
 
@@ -1234,7 +1234,7 @@
 
 	/* don't get the IRQ until we know for sure the drive is there */
 
-	if (request_irq(mcd_irq, mcd_interrupt, SA_INTERRUPT, "Mitsumi CD"))
+	if (request_irq(mcd_irq, mcd_interrupt, SA_INTERRUPT, "Mitsumi CD", NULL))
 	{
 		printk("Unable to get IRQ%d for Mitsumi CD-ROM\n", mcd_irq);
                 return -EIO;
@@ -1617,7 +1617,7 @@
        return;    
      }
   release_region(mcd_port,4);
-  free_irq(mcd_irq);
+  free_irq(mcd_irq, NULL);
   printk("mcd module released.\n");
 }
 #endif MODULE
diff -u --recursive --new-file v1.3.69/linux/drivers/cdrom/mcdx.c linux/drivers/cdrom/mcdx.c
--- v1.3.69/linux/drivers/cdrom/mcdx.c	Tue Jan 23 21:15:39 1996
+++ linux/drivers/cdrom/mcdx.c	Fri Mar  1 07:50:40 1996
@@ -191,7 +191,7 @@
 	structure fops. */
 
 /* ???  exported by the mcdx_sigaction struct */
-static void mcdx_intr(int, struct pt_regs*);
+static void mcdx_intr(int, void *, struct pt_regs*);
 
 /* exported by file_ops */
 static int mcdx_open(struct inode*, struct file*);
@@ -835,7 +835,7 @@
 }
 
 static void 
-mcdx_intr(int irq, struct pt_regs* regs)
+mcdx_intr(int irq, void *dev_id, struct pt_regs* regs)
 {
     struct s_drive_stuff *stuffp;
 	unsigned char x;
@@ -1002,7 +1002,7 @@
 		stuffp = mcdx_stuffp[i];
 		if (!stuffp) continue;
 		release_region((unsigned long) stuffp->wreg_data, MCDX_IO_SIZE);
-		free_irq(stuffp->irq);
+		free_irq(stuffp->irq, NULL);
 		if (stuffp->toc) {
 			TRACE((MALLOC, "cleanup_module() free toc @ %p\n", stuffp->toc));
 			kfree(stuffp->toc);
@@ -1170,7 +1170,7 @@
 
 		TRACE((INIT, "init() subscribe irq and i/o\n"));
 		mcdx_irq_map[stuffp->irq] = stuffp;
-		if (request_irq(stuffp->irq, mcdx_intr, SA_INTERRUPT, DEVICE_NAME)) {
+		if (request_irq(stuffp->irq, mcdx_intr, SA_INTERRUPT, DEVICE_NAME, NULL)) {
             WARN(("%s=0x%3p,%d: Init failed. Can't get irq (%d).\n",
                     MCDX,
                     stuffp->wreg_data, stuffp->irq, stuffp->irq));
diff -u --recursive --new-file v1.3.69/linux/drivers/cdrom/sonycd535.c linux/drivers/cdrom/sonycd535.c
--- v1.3.69/linux/drivers/cdrom/sonycd535.c	Tue Jan  2 16:46:24 1996
+++ linux/drivers/cdrom/sonycd535.c	Fri Mar  1 07:50:40 1996
@@ -313,7 +313,7 @@
 }
 
 static void
-cdu535_interrupt(int irq, struct pt_regs *regs)
+cdu535_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	disable_interrupts();
 	if (cdu535_irq_wait != NULL)
@@ -1566,7 +1566,7 @@
 #endif
 			if (sony535_irq_used > 0) {
 			    if (request_irq(sony535_irq_used, cdu535_interrupt,
-								SA_INTERRUPT, CDU535_HANDLE)) {
+								SA_INTERRUPT, CDU535_HANDLE, NULL)) {
 					printk("Unable to grab IRQ%d for the " CDU535_MESSAGE_NAME
 							" driver; polling instead.\n", sony535_irq_used);
 					sony535_irq_used = 0;
diff -u --recursive --new-file v1.3.69/linux/drivers/char/atixlmouse.c linux/drivers/char/atixlmouse.c
--- v1.3.69/linux/drivers/char/atixlmouse.c	Thu Nov  9 11:23:48 1995
+++ linux/drivers/char/atixlmouse.c	Fri Mar  1 07:50:40 1996
@@ -69,7 +69,7 @@
 	struct fasync_struct *fasync;
 } mouse;
 
-void mouse_interrupt(int irq, struct pt_regs * regs)
+void mouse_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
 	char dx, dy, buttons;
 
@@ -110,7 +110,7 @@
 		return;
 	ATIXL_MSE_INT_OFF(); /* Interrupts are really shut down here */
 	mouse.ready = 0;
-	free_irq(ATIXL_MOUSE_IRQ);
+	free_irq(ATIXL_MOUSE_IRQ, NULL);
 	MOD_DEC_USE_COUNT;
 }
 
@@ -120,7 +120,7 @@
 		return -EINVAL;
 	if (mouse.active++)
 		return 0;
-	if (request_irq(ATIXL_MOUSE_IRQ, mouse_interrupt, 0, "ATIXL mouse")) {
+	if (request_irq(ATIXL_MOUSE_IRQ, mouse_interrupt, 0, "ATIXL mouse", NULL)) {
 		mouse.active--;
 		return -EBUSY;
 	}
diff -u --recursive --new-file v1.3.69/linux/drivers/char/busmouse.c linux/drivers/char/busmouse.c
--- v1.3.69/linux/drivers/char/busmouse.c	Fri Jan 26 01:37:05 1996
+++ linux/drivers/char/busmouse.c	Fri Mar  1 07:50:40 1996
@@ -60,7 +60,7 @@
 		mouse_irq=ints[1];
 }
 
-static void mouse_interrupt(int irq, struct pt_regs *regs)
+static void mouse_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	char dx, dy;
 	unsigned char buttons;
@@ -124,7 +124,7 @@
 	if (--mouse.active)
 		return;
 	MSE_INT_OFF();
-	free_irq(mouse_irq);
+	free_irq(mouse_irq, NULL);
 	MOD_DEC_USE_COUNT;
 }
 
@@ -138,7 +138,7 @@
 		return -EINVAL;
 	if (mouse.active++)
 		return 0;
-	if (request_irq(mouse_irq, mouse_interrupt, 0, "busmouse")) {
+	if (request_irq(mouse_irq, mouse_interrupt, 0, "busmouse", NULL)) {
 		mouse.active--;
 		return -EBUSY;
 	}
diff -u --recursive --new-file v1.3.69/linux/drivers/char/console.c linux/drivers/char/console.c
--- v1.3.69/linux/drivers/char/console.c	Sat Feb 17 18:14:28 1996
+++ linux/drivers/char/console.c	Wed Feb 28 08:25:04 1996
@@ -2001,7 +2001,7 @@
 	console_driver.num = MAX_NR_CONSOLES;
 	console_driver.type = TTY_DRIVER_TYPE_CONSOLE;
 	console_driver.init_termios = tty_std_termios;
-	console_driver.flags = TTY_DRIVER_REAL_RAW;
+	console_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS;
 	console_driver.refcount = &console_refcount;
 	console_driver.table = console_table;
 	console_driver.termios = console_termios;
diff -u --recursive --new-file v1.3.69/linux/drivers/char/cyclades.c linux/drivers/char/cyclades.c
--- v1.3.69/linux/drivers/char/cyclades.c	Sat Feb 17 16:02:48 1996
+++ linux/drivers/char/cyclades.c	Fri Mar  1 07:50:40 1996
@@ -604,7 +604,7 @@
  * while we are probing for submarines.
  */
 static void
-cy_probe(int irq, struct pt_regs *regs)
+cy_probe(int irq, void *dev_id, struct pt_regs *regs)
 {
   int save_xir, save_car;
   int index = 0;	/* probing interrupts is only for ISA */
@@ -637,7 +637,7 @@
    received, out buffer empty, modem change, etc.
  */
 static void
-cy_interrupt(int irq, struct pt_regs *regs)
+cy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
   struct tty_struct *tty;
   int status;
@@ -1037,7 +1037,7 @@
     
     for (i = 0, mask = 1; i < 16; i++, mask <<= 1) {
 	if (!(mask & dontgrab)
-	&& !request_irq(i, cy_probe, SA_INTERRUPT, "serial probe")) {
+	&& !request_irq(i, cy_probe, SA_INTERRUPT, "serial probe", NULL)) {
 	    irq_lines |= mask;
 	}
     }
@@ -1054,7 +1054,7 @@
     
     for (i = 0; i < 16; i++) {
 	if (irq_lines & (1 << i))
-	    free_irq(i);
+	    free_irq(i,NULL);
     }
 } /* free_all_interrupts */
 
@@ -2927,7 +2927,7 @@
     for (i = 0; i < NR_CARDS; i++) {
         if (cy_card[i].base_addr != 0)
 	{
-	    free_irq(cy_card[i].irq);
+	    free_irq(cy_card[i].irq,NULL);
 	}
     }
 }
@@ -2985,7 +2985,7 @@
 		}
 
 		/* allocate IRQ */
-		if(request_irq(cy_isa_irq,cy_interrupt,SA_INTERRUPT,"cyclades"))
+		if(request_irq(cy_isa_irq,cy_interrupt,SA_INTERRUPT,"cyclades",NULL))
 		{
 			printk("Cyclom-Y/ISA found at 0x%x but could not allocate interrupt IRQ#%d.\n",
 				(unsigned int) cy_isa_address,cy_isa_irq);
@@ -3082,7 +3082,7 @@
 		}
 
 		/* allocate IRQ */
-		if(request_irq(cy_pci_irq,cy_interrupt,SA_INTERRUPT,"cyclades"))
+		if(request_irq(cy_pci_irq,cy_interrupt,SA_INTERRUPT,"cyclades",NULL))
 		{
 			printk("Cyclom-Y/PCI found at 0x%x but could not allocate interrupt IRQ%d.\n",
 				(unsigned int) cy_pci_address,cy_pci_irq);
diff -u --recursive --new-file v1.3.69/linux/drivers/char/keyboard.c linux/drivers/char/keyboard.c
--- v1.3.69/linux/drivers/char/keyboard.c	Sat Feb 17 18:14:28 1996
+++ linux/drivers/char/keyboard.c	Fri Mar  1 07:50:40 1996
@@ -337,7 +337,7 @@
 	    e0_keys[scancode - 128];
 }
 
-static void keyboard_interrupt(int irq, struct pt_regs *regs)
+static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	unsigned char scancode, keycode;
 	static unsigned int prev_scancode = 0;   /* remember E0, E1 */
@@ -1183,7 +1183,7 @@
 	ttytab = console_driver.table;
 
 	bh_base[KEYBOARD_BH].routine = kbd_bh;
-	request_irq(KEYBOARD_IRQ, keyboard_interrupt, 0, "keyboard");
+	request_irq(KEYBOARD_IRQ, keyboard_interrupt, 0, "keyboard", NULL);
 	request_region(0x60,16,"kbd");
 #ifdef INIT_KBD
 	initialize_kbd();
diff -u --recursive --new-file v1.3.69/linux/drivers/char/lp.c linux/drivers/char/lp.c
--- v1.3.69/linux/drivers/char/lp.c	Mon Dec 11 15:42:02 1995
+++ linux/drivers/char/lp.c	Fri Mar  1 07:50:40 1996
@@ -147,7 +147,7 @@
 	return 0;
 }
 
-static void lp_interrupt(int irq, struct pt_regs *regs)
+static void lp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct lp_struct *lp = &lp_table[0];
 
@@ -358,7 +358,7 @@
 			return -ENOMEM;
 		}
 
-		ret = request_irq(irq, lp_interrupt, SA_INTERRUPT, "printer");
+		ret = request_irq(irq, lp_interrupt, SA_INTERRUPT, "printer", NULL);
 		if (ret) {
 			kfree_s(lp_table[minor].lp_buffer, LP_BUFFER_SIZE);
 			lp_table[minor].lp_buffer = NULL;
@@ -378,7 +378,7 @@
 	unsigned int irq;
 
 	if ((irq = LP_IRQ(minor))) {
-		free_irq(irq);
+		free_irq(irq, NULL);
 		kfree_s(lp_table[minor].lp_buffer, LP_BUFFER_SIZE);
 		lp_table[minor].lp_buffer = NULL;
 	}
@@ -447,14 +447,14 @@
 			}
 
 			if (oldirq) {
-				free_irq(oldirq);
+				free_irq(oldirq, NULL);
 			}
 			if (newirq) {
 				/* Install new irq */
-				if ((retval = request_irq(newirq, lp_interrupt, SA_INTERRUPT, "printer"))) {
+				if ((retval = request_irq(newirq, lp_interrupt, SA_INTERRUPT, "printer", NULL))) {
 					if (oldirq) {
 						/* restore old irq */
-						request_irq(oldirq, lp_interrupt, SA_INTERRUPT, "printer");
+						request_irq(oldirq, lp_interrupt, SA_INTERRUPT, "printer", NULL);
 					} else {
 						/* We don't need the buffer */
 						kfree_s(lp->lp_buffer, LP_BUFFER_SIZE);
diff -u --recursive --new-file v1.3.69/linux/drivers/char/msbusmouse.c linux/drivers/char/msbusmouse.c
--- v1.3.69/linux/drivers/char/msbusmouse.c	Thu Nov  9 11:23:48 1995
+++ linux/drivers/char/msbusmouse.c	Fri Mar  1 07:50:40 1996
@@ -48,7 +48,7 @@
 
 static struct mouse_status mouse;
 
-static void ms_mouse_interrupt(int irq, struct pt_regs * regs)
+static void ms_mouse_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
         char dx, dy;
 	unsigned char buttons;
@@ -97,7 +97,7 @@
 		return;
 	MS_MSE_INT_OFF();
 	mouse.ready = 0; 
-	free_irq(MOUSE_IRQ);
+	free_irq(MOUSE_IRQ, NULL);
 	MOD_DEC_USE_COUNT;
 }
 
@@ -107,7 +107,7 @@
 		return -EINVAL;
 	if (mouse.active++)
 		return 0;
-	if (request_irq(MOUSE_IRQ, ms_mouse_interrupt, 0, "MS Busmouse")) {
+	if (request_irq(MOUSE_IRQ, ms_mouse_interrupt, 0, "MS Busmouse", NULL)) {
 		mouse.active--;
 		return -EBUSY;
 	}
diff -u --recursive --new-file v1.3.69/linux/drivers/char/psaux.c linux/drivers/char/psaux.c
--- v1.3.69/linux/drivers/char/psaux.c	Thu Nov  9 11:23:48 1995
+++ linux/drivers/char/psaux.c	Fri Mar  1 07:50:40 1996
@@ -208,7 +208,7 @@
  * is waiting in the keyboard/aux controller.
  */
 
-static void aux_interrupt(int cpl, struct pt_regs * regs)
+static void aux_interrupt(int cpl, void *dev_id, struct pt_regs * regs)
 {
 	int head = queue->head;
 	int maxhead = (queue->tail-1) & (AUX_BUF_SIZE-1);
@@ -234,7 +234,7 @@
  */
 
 #ifdef CONFIG_82C710_MOUSE
-static void qp_interrupt(int cpl, struct pt_regs * regs)
+static void qp_interrupt(int cpl, void *dev_id, struct pt_regs * regs)
 {
 	int head = queue->head;
 	int maxhead = (queue->tail-1) & (AUX_BUF_SIZE-1);
@@ -262,7 +262,7 @@
 	poll_aux_status();
 	outb_p(AUX_DISABLE,AUX_COMMAND);      	/* Disable Aux device */
 	poll_aux_status();
-	free_irq(AUX_IRQ);
+	free_irq(AUX_IRQ, NULL);
 	MOD_DEC_USE_COUNT;
 }
 
@@ -280,7 +280,7 @@
 	outb_p(status & ~(QP_ENABLE|QP_INTS_ON), qp_status);
 	if (!poll_qp_status())
 		printk("Warning: Mouse device busy in release_qp()\n");
-	free_irq(QP_IRQ);
+	free_irq(QP_IRQ, NULL);
 	MOD_DEC_USE_COUNT;
 }
 #endif
@@ -311,7 +311,7 @@
 		return -EBUSY;
 	}
 	queue->head = queue->tail = 0;		/* Flush input queue */
-	if (request_irq(AUX_IRQ, aux_interrupt, 0, "PS/2 Mouse")) {
+	if (request_irq(AUX_IRQ, aux_interrupt, 0, "PS/2 Mouse", NULL)) {
 		aux_count--;
 		return -EBUSY;
 	}
@@ -341,7 +341,7 @@
 	if (qp_count++)
 		return 0;
 
-	if (request_irq(QP_IRQ, qp_interrupt, 0, "PS/2 Mouse")) {
+	if (request_irq(QP_IRQ, qp_interrupt, 0, "PS/2 Mouse", NULL)) {
 		qp_count--;
 		return -EBUSY;
 	}
@@ -361,7 +361,7 @@
 		qp_count--;
 		status &= ~(QP_ENABLE|QP_INTS_ON);
 		outb_p(status, qp_status);
-		free_irq(QP_IRQ);
+		free_irq(QP_IRQ, NULL);
 		return -EBUSY;
 	}
 
diff -u --recursive --new-file v1.3.69/linux/drivers/char/scc.c linux/drivers/char/scc.c
--- v1.3.69/linux/drivers/char/scc.c	Sat Feb 17 16:02:48 1996
+++ linux/drivers/char/scc.c	Fri Mar  1 07:50:41 1996
@@ -238,7 +238,7 @@
 static void scc_exint(register struct scc_channel *scc);
 static void scc_rxint(register struct scc_channel *scc);
 static void scc_spint(register struct scc_channel *scc);
-static void scc_isr(int irq, struct pt_regs *regs);
+static void scc_isr(int irq, void *dev_id, struct pt_regs *regs);
 static void scc_tx_timer(unsigned long);
 static void scc_rx_timer(unsigned long);
 static void scc_init_timer(struct scc_channel *scc);
@@ -732,7 +732,7 @@
  */
 
 static void
-scc_isr(int irq, struct pt_regs *regs)
+scc_isr(int irq, void *dev_id, struct pt_regs *regs)
 {
 	register unsigned char vector;	
 	register struct scc_channel *scc;
@@ -2128,7 +2128,7 @@
 			
 			if (!Ivec[hwcfg.irq].used && hwcfg.irq)
 			{
-				if (request_irq(hwcfg.irq, scc_isr, SA_INTERRUPT, "AX.25 SCC"))
+				if (request_irq(hwcfg.irq, scc_isr, SA_INTERRUPT, "AX.25 SCC", NULL))
 					printk("z8530drv: Warning --- could not get IRQ %d\n", hwcfg.irq);
 				else
 					Ivec[hwcfg.irq].used = 1;
@@ -2784,7 +2784,7 @@
 	}
 	
 	for (k=0; k < 16 ; k++)
-		if (Ivec[k].used) free_irq(k);
+		if (Ivec[k].used) free_irq(k, NULL);
 		
 	restore_flags(flags);
 }
diff -u --recursive --new-file v1.3.69/linux/drivers/char/serial.c linux/drivers/char/serial.c
--- v1.3.69/linux/drivers/char/serial.c	Sun Feb 11 15:32:44 1996
+++ linux/drivers/char/serial.c	Fri Mar  1 07:50:41 1996
@@ -351,7 +351,7 @@
  * This is the serial driver's interrupt routine while we are probing
  * for submarines.
  */
-static void rs_probe(int irq, struct pt_regs * regs)
+static void rs_probe(int irq, void *dev_id, struct pt_regs * regs)
 {
 	rs_irq_triggered = irq;
 	rs_triggered |= 1 << irq;
@@ -514,7 +514,7 @@
 /*
  * This is the serial driver's generic interrupt routine
  */
-static void rs_interrupt(int irq, struct pt_regs * regs)
+static void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
 	int status;
 	struct async_struct * info;
@@ -580,7 +580,7 @@
 /*
  * This is the serial driver's interrupt routine for a single port
  */
-static void rs_interrupt_single(int irq, struct pt_regs * regs)
+static void rs_interrupt_single(int irq, void *dev_id, struct pt_regs * regs)
 {
 	int status;
 	int pass_counter = 0;
@@ -629,7 +629,7 @@
 /*
  * This is the serial driver's for multiport boards
  */
-static void rs_interrupt_multi(int irq, struct pt_regs * regs)
+static void rs_interrupt_multi(int irq, void *dev_id, struct pt_regs * regs)
 {
 	int status;
 	struct async_struct * info;
@@ -794,11 +794,11 @@
 					info = info->next_port;
 				} while (info);
 				if (rs_multiport[i].port1)
-					rs_interrupt_multi(i, NULL);
+					rs_interrupt_multi(i, NULL, NULL);
 				else
-					rs_interrupt(i, NULL);
+					rs_interrupt(i, NULL, NULL);
 			} else
-				rs_interrupt_single(i, NULL);
+				rs_interrupt_single(i, NULL, NULL);
 			sti();
 		}
 	}
@@ -808,7 +808,7 @@
 
 	if (IRQ_ports[0]) {
 		cli();
-		rs_interrupt(0, NULL);
+		rs_interrupt(0, NULL, NULL);
 		sti();
 
 		timer_table[RS_TIMER].expires = jiffies + IRQ_timeout[0] - 2;
@@ -836,7 +836,7 @@
 	int			i, mask;
 	
 	for (i = 0, mask = 1; i < 16; i++, mask <<= 1) {
-		if (!(mask & dontgrab) && !request_irq(i, rs_probe, SA_INTERRUPT, "serial probe")) {
+		if (!(mask & dontgrab) && !request_irq(i, rs_probe, SA_INTERRUPT, "serial probe", NULL)) {
 			irq_lines |= mask;
 		}
 	}
@@ -852,7 +852,7 @@
 	
 	for (i = 0; i < 16; i++) {
 		if (irq_lines & (1 << i))
-			free_irq(i);
+			free_irq(i, NULL);
 	}
 }
 
@@ -886,7 +886,7 @@
 	unsigned short ICP;
 	unsigned long flags;
 	int	retval;
-	void (*handler)(int, struct pt_regs *);
+	void (*handler)(int, void *, struct pt_regs *);
 	unsigned long page;
 
 	page = get_free_page(GFP_KERNEL);
@@ -954,7 +954,7 @@
 	if (info->irq && (!IRQ_ports[info->irq] ||
 			  !IRQ_ports[info->irq]->next_port)) {
 		if (IRQ_ports[info->irq]) {
-			free_irq(info->irq);
+			free_irq(info->irq, NULL);
 			if (rs_multiport[info->irq].port1)
 				handler = rs_interrupt_multi;
 			else
@@ -962,7 +962,7 @@
 		} else 
 			handler = rs_interrupt_single;
 
-		retval = request_irq(info->irq, handler, SA_INTERRUPT, "serial");
+		retval = request_irq(info->irq, handler, SA_INTERRUPT, "serial", NULL);
 		if (retval) {
 			restore_flags(flags);
 			if (suser()) {
@@ -1089,14 +1089,14 @@
 	if (info->irq && (!IRQ_ports[info->irq] ||
 			  !IRQ_ports[info->irq]->next_port)) {
 		if (IRQ_ports[info->irq]) {
-			free_irq(info->irq);
-			retval = request_irq(info->irq, rs_interrupt_single, SA_INTERRUPT, "serial");
+			free_irq(info->irq, NULL);
+			retval = request_irq(info->irq, rs_interrupt_single, SA_INTERRUPT, "serial", NULL);
 			
 			if (retval)
 				printk("serial shutdown: request_irq: error %d"
 				       "  Couldn't reacquire IRQ.\n", retval);
 		} else
-			free_irq(info->irq);
+			free_irq(info->irq, NULL);
 	}
 
 	if (info->xmit_buf) {
@@ -1792,7 +1792,7 @@
 	struct rs_multiport_struct *multi;
 	int	was_multi, now_multi;
 	int	retval;
-	void (*handler)(int, struct pt_regs *);
+	void (*handler)(int, void *, struct pt_regs *);
 
 	if (!suser())
 		return -EPERM;
@@ -1846,14 +1846,14 @@
 	
 	if (IRQ_ports[info->irq]->next_port &&
 	    (was_multi != now_multi)) {
-		free_irq(info->irq);
+		free_irq(info->irq, NULL);
 		if (now_multi)
 			handler = rs_interrupt_multi;
 		else
 			handler = rs_interrupt;
 
 		retval = request_irq(info->irq, handler, SA_INTERRUPT,
-				     "serial");
+				     "serial", NULL);
 		if (retval) {
 			printk("Couldn't reallocate serial interrupt "
 			       "driver!!\n");
diff -u --recursive --new-file v1.3.69/linux/drivers/char/stallion.c linux/drivers/char/stallion.c
--- v1.3.69/linux/drivers/char/stallion.c	Fri Feb 16 11:34:06 1996
+++ linux/drivers/char/stallion.c	Fri Mar  1 07:50:41 1996
@@ -489,7 +489,7 @@
 static void	stl_sendbreak(stlport_t *portp, long len);
 static int	stl_waitcarrier(stlport_t *portp, struct file *filp);
 static void	stl_delay(int len);
-static void	stl_intr(int irq, struct pt_regs *regs);
+static void	stl_intr(int irq, void *dev_id, struct pt_regs *regs);
 static void	stl_offintr(void *private);
 static void	*stl_memalloc(int len);
 
@@ -594,7 +594,7 @@
 	}
 
 	for (i = 0; (i < stl_numintrs); i++)
-		free_irq(stl_gotintrs[i]);
+		free_irq(stl_gotintrs[i], NULL);
 
 	restore_flags(flags);
 }
@@ -1747,7 +1747,7 @@
  *	io region.
  */
 
-static void stl_intr(int irq, struct pt_regs *regs)
+static void stl_intr(int irq, void *dev_id, struct pt_regs *regs)
 {
 	stlbrd_t	*brdp;
 	stlpanel_t	*panelp;
@@ -2364,7 +2364,7 @@
 			break;
 	}
 	if (i >= stl_numintrs) {
-		if (request_irq(irq, stl_intr, SA_INTERRUPT, stl_drvname) != 0) {
+		if (request_irq(irq, stl_intr, SA_INTERRUPT, stl_drvname, NULL) != 0) {
 			printk("STALLION: failed to register interrupt routine for irq=%d\n", irq);
 			rc = -ENODEV;
 		} else {
diff -u --recursive --new-file v1.3.69/linux/drivers/char/tpqic02.c linux/drivers/char/tpqic02.c
--- v1.3.69/linux/drivers/char/tpqic02.c	Sat Feb 17 16:02:48 1996
+++ linux/drivers/char/tpqic02.c	Fri Mar  1 07:50:41 1996
@@ -1797,7 +1797,7 @@
  * When we are finished, set flags to indicate end, disable timer.
  * NOTE: This *must* be fast! 
  */
-static void qic02_tape_interrupt(int irq, struct pt_regs *regs)
+static void qic02_tape_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	int stat, r, i;
 
@@ -2812,7 +2812,7 @@
 
 static void qic02_release_resources(void)
 {
-	free_irq(QIC02_TAPE_IRQ);
+	free_irq(QIC02_TAPE_IRQ, NULL);
 	free_dma(QIC02_TAPE_DMA);
 	status_zombie = YES;
 } /* qic02_release_resources */
@@ -2835,7 +2835,7 @@
 	 */
 
 	/* get IRQ */
-	if (request_irq(QIC02_TAPE_IRQ, qic02_tape_interrupt, SA_INTERRUPT, "QIC-02")) {
+	if (request_irq(QIC02_TAPE_IRQ, qic02_tape_interrupt, SA_INTERRUPT, "QIC-02", NULL)) {
 		printk(TPQIC02_NAME ": can't allocate IRQ%d for QIC-02 tape\n",
 			QIC02_TAPE_IRQ);
 		status_zombie = YES;
@@ -2846,7 +2846,7 @@
 	if (request_dma(QIC02_TAPE_DMA,"QIC-02")) {
 		printk(TPQIC02_NAME ": can't allocate DMA%d for QIC-02 tape\n",
 			QIC02_TAPE_DMA);
-		free_irq(QIC02_TAPE_IRQ);
+		free_irq(QIC02_TAPE_IRQ, NULL);
 		status_zombie = YES;
 		return -1;
 	}
@@ -2931,7 +2931,7 @@
 	if (register_chrdev(QIC02_TAPE_MAJOR, TPQIC02_NAME, &qic02_tape_fops)) {
 		printk(TPQIC02_NAME ": Unable to get chrdev major %d\n", QIC02_TAPE_MAJOR);
 #ifndef CONFIG_QIC02_DYNCONF
-		free_irq(QIC02_TAPE_IRQ);
+		free_irq(QIC02_TAPE_IRQ, NULL);
 		free_dma(QIC02_TAPE_DMA);
 #endif
 		return -ENODEV;
@@ -2947,7 +2947,7 @@
 		/* No drive detected, so vanish */
 		tpqputs(TPQD_ALWAYS, "No drive detected -- driver going on vacation...");
 		status_dead = YES;
-		free_irq(QIC02_TAPE_IRQ);
+		free_irq(QIC02_TAPE_IRQ, NULL);
 		free_dma(QIC02_TAPE_DMA);
 		unregister_chrdev(QIC02_TAPE_MAJOR, TPQIC02_NAME);
 		return -ENODEV;
diff -u --recursive --new-file v1.3.69/linux/drivers/char/wdt.c linux/drivers/char/wdt.c
--- v1.3.69/linux/drivers/char/wdt.c	Fri Feb 23 13:54:34 1996
+++ linux/drivers/char/wdt.c	Fri Mar  1 07:50:41 1996
@@ -69,7 +69,7 @@
  *	Kernel methods.
  */
  
-static void wdt_interrupt(int irq, struct pt_regs *regs)
+static void wdt_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	/*
 	 *	Read the status register see what is up and
@@ -234,7 +234,7 @@
 int init_module(void)
 {
 	printk("WDT501-P module at %X(Interrupt %d)\n", io,irq);
-	if(request_irq(irq, wdt_interrupt, SA_INTERRUPT, "wdt501p"))
+	if(request_irq(irq, wdt_interrupt, SA_INTERRUPT, "wdt501p", NULL))
 	{
 		printk("IRQ %d is not free.\n", irq);
 		return -EIO;
@@ -254,7 +254,7 @@
 	mouse_deregister(&temp_mouse);
 #endif	
 	release_region(io,8);
-	free_irq(irq);
+	free_irq(irq, NULL);
 }
 
 #else
@@ -262,7 +262,7 @@
 int wdt_init(void)
 {
 	printk("WDT500/501-P driver at %X(Interrupt %d)\n", io,irq);
-	if(request_irq(irq, wdt_interrupt, SA_INTERRUPT, "wdt501p"))
+	if(request_irq(irq, wdt_interrupt, SA_INTERRUPT, "wdt501p", NULL))
 	{
 		printk("IRQ %d is not free.\n", irq);
 		return -EIO;
diff -u --recursive --new-file v1.3.69/linux/drivers/isdn/teles/card.c linux/drivers/isdn/teles/card.c
--- v1.3.69/linux/drivers/isdn/teles/card.c	Wed Feb 28 11:50:03 1996
+++ linux/drivers/isdn/teles/card.c	Wed Feb 28 08:32:54 1996
@@ -1050,6 +1050,15 @@
                                readhscx_0(card->membase, 1, HSCX_VSTR) & 0xf);
                 }
         } else {
+                switch (card->iobase) {
+                        case 0x180:
+                        case 0x280:
+                        case 0x380:
+                                printk(KERN_INFO "teles: port 0x%x specified, assuming 0x%x\n",
+                                       card->iobase, (card->iobase | 0xc00));
+                                card->iobase |= 0xc00;
+                                break;
+                }
                 if (check_region(card->iobase, 8)) {
                         printk(KERN_WARNING
                                "teles: ports %x-%x already in use\n",
diff -u --recursive --new-file v1.3.69/linux/drivers/net/3c501.c linux/drivers/net/3c501.c
--- v1.3.69/linux/drivers/net/3c501.c	Wed Dec 27 09:12:13 1995
+++ linux/drivers/net/3c501.c	Fri Mar  1 07:50:41 1996
@@ -93,7 +93,6 @@
 #include <linux/interrupt.h>
 #include <linux/malloc.h>
 #include <linux/string.h>
-#include <linux/ioport.h>
 #include <linux/errno.h>
 #include <linux/config.h>	/* for CONFIG_IP_MULTICAST */
 
@@ -120,7 +119,7 @@
 static int  el1_probe1(struct device *dev, int ioaddr);
 static int  el_open(struct device *dev);
 static int  el_start_xmit(struct sk_buff *skb, struct device *dev);
-static void el_interrupt(int irq, struct pt_regs *regs);
+static void el_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static void el_receive(struct device *dev);
 static void el_reset(struct device *dev);
 static int  el1_close(struct device *dev);
@@ -361,7 +360,7 @@
 	if (el_debug > 2)
 		printk("%s: Doing el_open()...", dev->name);
 
-	if (request_irq(dev->irq, &el_interrupt, 0, "3c501")) 
+	if (request_irq(dev->irq, &el_interrupt, 0, "3c501", NULL)) 
 		return -EAGAIN;
 
 	irq2dev_map[dev->irq] = dev;
@@ -489,7 +488,7 @@
  *	Handle the ether interface interrupts. 
  */
 
-static void el_interrupt(int irq, struct pt_regs *regs)
+static void el_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct device *dev = (struct device *)(irq2dev_map[irq]);
 	struct net_local *lp;
@@ -765,7 +764,7 @@
 	 *	Free and disable the IRQ. 
 	 */
 
-	free_irq(dev->irq);
+	free_irq(dev->irq, NULL);
 	outb(AX_RESET, AX_CMD);		/* Reset the chip */
 	irq2dev_map[dev->irq] = 0;
 
diff -u --recursive --new-file v1.3.69/linux/drivers/net/3c503.c linux/drivers/net/3c503.c
--- v1.3.69/linux/drivers/net/3c503.c	Thu Dec 21 08:53:31 1995
+++ linux/drivers/net/3c503.c	Fri Mar  1 07:50:41 1996
@@ -26,6 +26,7 @@
 
     Paul Gortmaker	: add support for the 2nd 8kB of RAM on 16 bit cards.
     Paul Gortmaker	: multiple card support for module users.
+    rjohnson@analogic.com : Fix up PIO interface for efficient operation.
 
 */
 
@@ -47,7 +48,7 @@
 
 #include "8390.h"
 #include "3c503.h"
-
+#define WRD_COUNT 4 
 
 int el2_probe(struct device *dev);
 int el2_pio_probe(struct device *dev);
@@ -193,7 +194,6 @@
 	printk(version);
 
     dev->base_addr = ioaddr;
-
     /* Allocate dev->priv and fill in 8390 specific dev fields. */
     if (ethdev_init(dev)) {
 	printk ("3c503: unable to allocate memory for dev->priv.\n");
@@ -251,7 +251,7 @@
 		writel(test_val, mem_base + i);
 		if (readl(mem_base) != 0xba5eba5e
 		    || readl(mem_base + i) != test_val) {
-		    printk("3c503.c: memory failure or memory address conflict.\n");
+		    printk("3c503: memory failure or memory address conflict.\n");
 		    dev->mem_start = 0;
 		    ei_status.name = "3c503-PIO";
 		    break;
@@ -319,9 +319,12 @@
 		dev->mem_start, dev->mem_end-1);
 
     else
+    {
+	ei_status.tx_start_page = EL2_MB1_START_PG;
+	ei_status.rx_start_page = EL2_MB1_START_PG + TX_PAGES;
 	printk("\n%s: %s, %dkB RAM, using programmed I/O (REJUMPER for SHARED MEMORY).\n",
 	       dev->name, ei_status.name, (wordlength+1)<<3);
-
+    }
     return 0;
 }
 
@@ -335,13 +338,13 @@
 
 	outb(EGACFR_NORM, E33G_GACFR);	/* Enable RAM and interrupts. */
 	do {
-	    if (request_irq (*irqp, NULL, 0, "bogus") != -EBUSY) {
+	    if (request_irq (*irqp, NULL, 0, "bogus", NULL) != -EBUSY) {
 		/* Twinkle the interrupt, and check if it's seen. */
 		autoirq_setup(0);
 		outb_p(0x04 << ((*irqp == 9) ? 2 : *irqp), E33G_IDCFR);
 		outb_p(0x00, E33G_IDCFR);
 		if (*irqp == autoirq_report(0)	 /* It's a good IRQ line! */
-		    && request_irq (dev->irq = *irqp, &ei_interrupt, 0, ei_status.name) == 0)
+		    && request_irq (dev->irq = *irqp, &ei_interrupt, 0, ei_status.name, NULL) == 0)
 		    break;
 	    }
 	} while (*++irqp);
@@ -350,7 +353,7 @@
 	    return -EAGAIN;
 	}
     } else {
-	if (request_irq(dev->irq, &ei_interrupt, 0, ei_status.name)) {
+	if (request_irq(dev->irq, &ei_interrupt, 0, ei_status.name, NULL)) {
 	    return -EAGAIN;
 	}
     }
@@ -364,7 +367,7 @@
 static int
 el2_close(struct device *dev)
 {
-    free_irq(dev->irq);
+    free_irq(dev->irq, NULL);
     dev->irq = ei_status.saved_irq;
     irq2dev_map[dev->irq] = NULL;
     outb(EGACFR_IRQOFF, E33G_GACFR);	/* disable interrupts. */
@@ -416,20 +419,23 @@
 
     /* Set the interrupt line. */
     outb_p((0x04 << (dev->irq == 9 ? 2 : dev->irq)), E33G_IDCFR);
-    outb_p(8, E33G_DRQCNT);		/* Set burst size to 8 */
+    outb_p((WRD_COUNT << 1), E33G_DRQCNT);	/* Set burst size to 8 */
     outb_p(0x20, E33G_DMAAH);	/* Put a valid addr in the GA DMA */
     outb_p(0x00, E33G_DMAAL);
     return;			/* We always succeed */
 }
 
-/* Either use the shared memory (if enabled on the board) or put the packet
-   out through the ASIC FIFO.  The latter is probably much slower. */
+/*
+ * Either use the shared memory (if enabled on the board) or put the packet
+ * out through the ASIC FIFO.
+ */
 static void
 el2_block_output(struct device *dev, int count,
 		 const unsigned char *buf, const start_page)
 {
-    int i;				/* Buffer index */
-    int boguscount = 0;		/* timeout counter */
+    unsigned short int *wrd;
+    int boguscount;		/* timeout counter */
+    unsigned shor tmp_rev;	/* temporary for reversed values */
 
     if (ei_status.word16)      /* Tx packets go into bank 0 on EL2/16 card */
 	outb(EGACFR_RSEL|EGACFR_TCM, E33G_GACFR);
@@ -443,29 +449,55 @@
 	outb(EGACFR_NORM, E33G_GACFR);	/* Back to bank1 in case on bank0 */
 	return;
     }
-    /* No shared memory, put the packet out the slow way. */
-    /* Set up then start the internal memory transfer to Tx Start Page */
-    outb(0x00, E33G_DMAAL);
-    outb_p(start_page, E33G_DMAAH);
+
+/*
+ *  No shared memory, put the packet out the other way.
+ *  Set up then start the internal memory transfer to Tx Start Page
+ */
+
+    tmp_rev = htons((unsigned short)start_page);
+    outb(tmp_rev&0xFF, E33G_DMAAH);
+    outb(tmp_rev>>8, E33G_DMAAL);
+
     outb_p((ei_status.interface_num ? ECNTRL_AUI : ECNTRL_THIN ) | ECNTRL_OUTPUT
 	   | ECNTRL_START, E33G_CNTRL);
 
-    /* This is the byte copy loop: it should probably be tuned for
-       speed once everything is working.  I think it is possible
-       to output 8 bytes between each check of the status bit. */
-    for(i = 0; i < count; i++) {
-	if (i % 8 == 0)
-	    while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
-		if (++boguscount > (i<<3) + 32) {
-		    printk("%s: FIFO blocked in el2_block_output (at %d of %d, bc=%d).\n",
-			   dev->name, i, count, boguscount);
-		    outb(EGACFR_NORM, E33G_GACFR);	/* To MB1 for EL2/16 */
-		    return;
-		}
-	outb(buf[i], E33G_FIFOH);
+/*
+ *  Here I am going to write data to the FIFO as quickly as possible.
+ *  Note that E33G_FIFOH is defined incorrectly. It is really
+ *  E33G_FIFOL, the lowest port address for both the byte and
+ *  word write. Variable 'count' is NOT checked. Caller must supply a
+ *  valid count. Note that I may write a harmless extra byte to the
+ *  8390 if the byte-count was not even.
+ */
+    wrd = (unsigned short int *) buf;
+    count  = (count + 1) >> 1;
+    for(;;) 
+    {
+        boguscount = 0x1000;
+        while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
+        {
+            if(!boguscount--)
+            {
+                printk("%s: FIFO blocked in el2_block_output.\n", dev->name);
+                el2_reset_8390(dev);
+                goto blocked;
+            }
+        }
+        if(count > WRD_COUNT)
+        {
+            outsw(E33G_FIFOH, wrd, WRD_COUNT);
+            wrd   += WRD_COUNT;
+            count -= WRD_COUNT;
+        }
+        else
+        {
+            outsw(E33G_FIFOH, wrd, count);
+            break;
+        }
     }
+    blocked:;
     outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
-    outb(EGACFR_NORM, E33G_GACFR);	/* Back to bank1 in case on bank0 */
     return;
 }
 
@@ -473,48 +505,50 @@
 static void
 el2_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
 {
-    unsigned int i;
+    int boguscount;
     unsigned long hdr_start = dev->mem_start + ((ring_page - EL2_MB1_START_PG)<<8);
-    unsigned long fifo_watchdog;
+    unsigned short tmp_rev;
 
     if (dev->mem_start) {       /* Use the shared memory. */
-#ifdef notdef
-	/* Officially this is what we are doing, but the readl() is faster */
 	memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
-#else
-	((unsigned int*)hdr)[0] = readl(hdr_start);
-#endif
 	return;
     }
 
-    /* No shared memory, use programmed I/O. Ugh. */
-    outb(0, E33G_DMAAL);
-    outb_p(ring_page & 0xff, E33G_DMAAH);
+/*
+ *  No shared memory, use programmed I/O.
+ */
+
+    tmp_rev = htons((unsigned short)ring_page);
+    outb(tmp_rev&0xFF, E33G_DMAAH);
+    outb(tmp_rev>>8, E33G_DMAAL);
+
     outb_p((ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI) | ECNTRL_INPUT
 	   | ECNTRL_START, E33G_CNTRL);
-
-    /* Header is < 8 bytes, so only check the FIFO at the beginning. */
-    fifo_watchdog = jiffies;
-    while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0) {
-	if (jiffies - fifo_watchdog > 2*HZ/100) {
-		printk("%s: FIFO blocked in el2_get_8390_hdr.\n", dev->name);
-		break;
-	}
+    boguscount = 0x1000;
+    while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
+    {
+        if(!boguscount--)
+        {
+            printk("%s: FIFO blocked in el2_get_8390_hdr.\n", dev->name);
+            memset(hdr, 0x00, sizeof(struct e8390_pkt_hdr));
+            el2_reset_8390(dev);
+            goto blocked;
+        }
     }
-
-    for(i = 0; i < sizeof(struct e8390_pkt_hdr); i++)
-	((char *)(hdr))[i] = inb_p(E33G_FIFOH);
-
+    insw(E33G_FIFOH, hdr, (sizeof(struct e8390_pkt_hdr))>> 1);
+    blocked:;
     outb_p(ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
 }
 
-/* Returns the new ring pointer. */
+
 static void
 el2_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset)
 {
     int boguscount = 0;
+    unsigned short int *buf;
+    unsigned short tmp_rev;
+
     int end_of_ring = dev->rmem_end;
-    unsigned int i;
 
     /* Maybe enable shared memory just be to be safe... nahh.*/
     if (dev->mem_start) {	/* Use the shared memory. */
@@ -531,32 +565,61 @@
 	}
 	return;
     }
-    /* No shared memory, use programmed I/O. */
-    outb(ring_offset & 0xff, E33G_DMAAL);
-    outb_p((ring_offset >> 8) & 0xff, E33G_DMAAH);
+
+/*
+ *  No shared memory, use programmed I/O.
+ */
+    tmp_rev = htons((unsigned short) ring_offset);
+    outb(tmp_rev&0xFF, E33G_DMAAL);
+    outb(tmp_rev>>8, E33G_DMAAH);
+
     outb_p((ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI) | ECNTRL_INPUT
 	   | ECNTRL_START, E33G_CNTRL);
 
-    /* This is the byte copy loop: it should probably be tuned for
-       speed once everything is working. */
-    for(i = 0; i < count; i++) {
-	if (i % 8 == 0)
-	    while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
-		if (++boguscount > (i<<3) + 32) {
-		    printk("%s: FIFO blocked in el2_block_input() (at %d of %d, bc=%d).\n",
-			   dev->name, i, count, boguscount);
-		    boguscount = 0;
-		    break;
-		}
-	(skb->data)[i] = inb_p(E33G_FIFOH);
+/*
+ *  Here I also try to get data as fast as possible. I am betting that I
+ *  can read one extra byte without clobering anything in the kernel because
+ *  this would only occur on an odd byte-count and allocation of skb->data
+ *  is word-aligned. Variable 'count' is NOT checked. Caller must check
+ *  for a valid count. 
+ *  [This is currently quite safe.... but if one day the 3c503 explodes
+ *   you know where to come looking ;)]
+ */
+
+    buf =  (unsigned short int *) skb->data;
+    count =  (count + 1) >> 1;
+    for(;;) 
+    {
+        boguscount = 0x1000;
+        while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
+        {
+            if(!boguscount--)
+            {
+                printk("%s: FIFO blocked in el2_block_input.\n", dev->name);
+                el2_reset_8390(dev);
+                goto blocked;
+            }
+        }
+        if(count > WRD_COUNT)
+        { 
+            insw(E33G_FIFOH, buf, WRD_COUNT);
+            buf   += WRD_COUNT;
+            count -= WRD_COUNT;
+        }
+        else
+        {
+            insw(E33G_FIFOH, buf, count);
+            break;
+        }
     }
+    blocked:;
     outb_p(ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
+    return;
 }
-
-
 #ifdef MODULE
 #define MAX_EL2_CARDS	4	/* Max number of EL2 cards per module */
-#define NAMELEN		8	/* # of chars for storing dev->name */
+#define NAMELEN 	8	/* #of chars for storing dev->name */
+
 static char namelist[NAMELEN * MAX_EL2_CARDS] = { 0, };
 static struct device dev_el2[MAX_EL2_CARDS] = {
 	{
@@ -596,7 +659,6 @@
 		}
 		found++;
 	}
-
 	return 0;
 }
 
diff -u --recursive --new-file v1.3.69/linux/drivers/net/3c505.c linux/drivers/net/3c505.c
--- v1.3.69/linux/drivers/net/3c505.c	Thu Dec 21 08:53:31 1995
+++ linux/drivers/net/3c505.c	Fri Mar  1 07:50:42 1996
@@ -635,7 +635,7 @@
  ******************************************************/
 
 static void
-elp_interrupt (int irq, struct pt_regs *reg_ptr)
+elp_interrupt (int irq, void *dev_id, struct pt_regs *reg_ptr)
 {
 	int len;
 	int dlen;
@@ -859,7 +859,7 @@
 	/*
 	 * install our interrupt service routine
 	 */
-	if (request_irq(dev->irq, &elp_interrupt, 0, "3c505")) {
+	if (request_irq(dev->irq, &elp_interrupt, 0, "3c505", NULL)) {
 		irq2dev_map[dev->irq] = NULL;
 		return -EAGAIN;
 	}
@@ -1150,7 +1150,7 @@
 	/*
 	 * release the IRQ
 	 */
-	free_irq(dev->irq);
+	free_irq(dev->irq, NULL);
 
 	/*
 	 * and we no longer have to map irq to dev either
diff -u --recursive --new-file v1.3.69/linux/drivers/net/3c507.c linux/drivers/net/3c507.c
--- v1.3.69/linux/drivers/net/3c507.c	Thu Nov  9 11:23:49 1995
+++ linux/drivers/net/3c507.c	Fri Mar  1 07:50:42 1996
@@ -280,7 +280,7 @@
 static int	el16_probe1(struct device *dev, int ioaddr);
 static int	el16_open(struct device *dev);
 static int	el16_send_packet(struct sk_buff *skb, struct device *dev);
-static void	el16_interrupt(int irq, struct pt_regs *regs);
+static void	el16_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static void el16_rx(struct device *dev);
 static int	el16_close(struct device *dev);
 static struct enet_statistics *el16_get_stats(struct device *dev);
@@ -361,7 +361,7 @@
 
 	irq = inb(ioaddr + IRQ_CONFIG) & 0x0f;
 
-	irqval = request_irq(irq, &el16_interrupt, 0, "3c507");
+	irqval = request_irq(irq, &el16_interrupt, 0, "3c507", NULL);
 	if (irqval) {
 		printk ("unable to get IRQ %d (irqval=%d).\n", irq, irqval);
 		return EAGAIN;
@@ -513,7 +513,7 @@
 /*	The typical workload of the driver:
 	Handle the network interface interrupts. */
 static void
-el16_interrupt(int irq, struct pt_regs *regs)
+el16_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct device *dev = (struct device *)(irq2dev_map[irq]);
 	struct net_local *lp;
@@ -907,7 +907,7 @@
 	dev_3c507.priv = NULL;
 
 	/* If we don't do this, we can't re-insmod it later. */
-	free_irq(dev_3c507.irq);
+	free_irq(dev_3c507.irq, NULL);
 	release_region(dev_3c507.base_addr, EL16_IO_EXTENT);
 }
 #endif /* MODULE */
diff -u --recursive --new-file v1.3.69/linux/drivers/net/3c509.c linux/drivers/net/3c509.c
--- v1.3.69/linux/drivers/net/3c509.c	Wed Feb 28 11:50:04 1996
+++ linux/drivers/net/3c509.c	Fri Mar  1 07:50:42 1996
@@ -102,7 +102,7 @@
 static ushort read_eeprom(short ioaddr, int index);
 static int el3_open(struct device *dev);
 static int el3_start_xmit(struct sk_buff *skb, struct device *dev);
-static void el3_interrupt(int irq, struct pt_regs *regs);
+static void el3_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static void update_stats(int addr, struct device *dev);
 static struct enet_statistics *el3_get_stats(struct device *dev);
 static int el3_rx(struct device *dev);
@@ -312,7 +312,7 @@
 	outw(RxReset, ioaddr + EL3_CMD);
 	outw(SetReadZero | 0x00, ioaddr + EL3_CMD);
 
-	if (request_irq(dev->irq, &el3_interrupt, 0, "3c509")) {
+	if (request_irq(dev->irq, &el3_interrupt, 0, "3c509", NULL)) {
 		return -EAGAIN;
 	}
 
@@ -464,7 +464,7 @@
 
 /* The EL3 interrupt handler. */
 static void
-el3_interrupt(int irq, struct pt_regs *regs)
+el3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct device *dev = (struct device *)(irq2dev_map[irq]);
 	int ioaddr, status;
@@ -680,7 +680,7 @@
 		outw(inw(ioaddr + WN4_MEDIA) & ~MEDIA_TP, ioaddr + WN4_MEDIA);
 	}
 
-	free_irq(dev->irq);
+	free_irq(dev->irq, NULL);
 	/* Switching back to window 0 disables the IRQ. */
 	EL3WINDOW(0);
 	/* But we explicitly zero the IRQ line select anyway. */
diff -u --recursive --new-file v1.3.69/linux/drivers/net/3c59x.c linux/drivers/net/3c59x.c
--- v1.3.69/linux/drivers/net/3c59x.c	Wed Feb 14 14:37:10 1996
+++ linux/drivers/net/3c59x.c	Fri Mar  1 07:50:42 1996
@@ -237,7 +237,7 @@
 static void vortex_timer(unsigned long arg);
 static int vortex_start_xmit(struct sk_buff *skb, struct device *dev);
 static int vortex_rx(struct device *dev);
-static void vortex_interrupt(int irq, struct pt_regs *regs);
+static void vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static int vortex_close(struct device *dev);
 static void update_stats(int addr, struct device *dev);
 static struct enet_statistics *vortex_get_stats(struct device *dev);
@@ -550,7 +550,7 @@
 	if (dev->irq == 0  ||  irq2dev_map[dev->irq] != NULL)
 		return -EAGAIN;
 	irq2dev_map[dev->irq] = dev;
-	if (request_irq(dev->irq, &vortex_interrupt, 0, vp->product_name)) {
+	if (request_irq(dev->irq, &vortex_interrupt, 0, vp->product_name, NULL)) {
 		irq2dev_map[dev->irq] = NULL;
 		return -EAGAIN;
 	}
@@ -736,7 +736,7 @@
 
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
-static void vortex_interrupt(int irq, struct pt_regs *regs)
+static void vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 #ifdef USE_SHARED_IRQ
 	struct device *dev = (struct device *)(irq == 0 ? regs : irq2dev_map[irq]);
@@ -774,7 +774,7 @@
 		if (donedidthis++ > 1) {
 			printk("%s: Bogus interrupt, bailing. Status %4.4x, start=%d.\n",
 				   dev->name, status, dev->start);
-			free_irq(dev->irq);
+			free_irq(dev->irq, NULL);
 		}
 	}
 
@@ -955,7 +955,7 @@
 #ifdef USE_SHARED_IRQ
 	free_shared_irq(dev->irq, dev);
 #else
-	free_irq(dev->irq);
+	free_irq(dev->irq, NULL);
 	/* Mmmm, we should diable all interrupt sources here. */
 	irq2dev_map[dev->irq] = 0;
 #endif
diff -u --recursive --new-file v1.3.69/linux/drivers/net/8390.c linux/drivers/net/8390.c
--- v1.3.69/linux/drivers/net/8390.c	Sun Dec 17 11:43:18 1995
+++ linux/drivers/net/8390.c	Fri Mar  1 07:50:42 1996
@@ -257,7 +257,7 @@
 
 /* The typical workload of the driver:
    Handle the ether interface interrupts. */
-void ei_interrupt(int irq, struct pt_regs * regs)
+void ei_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
     struct device *dev = (struct device *)(irq2dev_map[irq]);
     int e8390_base;
diff -u --recursive --new-file v1.3.69/linux/drivers/net/8390.h linux/drivers/net/8390.h
--- v1.3.69/linux/drivers/net/8390.h	Fri Nov 17 08:42:25 1995
+++ linux/drivers/net/8390.h	Fri Mar  1 10:37:20 1996
@@ -33,7 +33,7 @@
 extern void NS8390_init(struct device *dev, int startp);
 extern int ei_open(struct device *dev);
 extern int ei_close(struct device *dev);
-extern void ei_interrupt(int irq, struct pt_regs *regs);
+extern void ei_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 
 #ifndef HAVE_AUTOIRQ
 /* From auto_irq.c */
diff -u --recursive --new-file v1.3.69/linux/drivers/net/ac3200.c linux/drivers/net/ac3200.c
--- v1.3.69/linux/drivers/net/ac3200.c	Tue Jan  2 16:46:24 1996
+++ linux/drivers/net/ac3200.c	Fri Mar  1 07:50:42 1996
@@ -164,7 +164,7 @@
 	else if (dev->irq == 2)
 		dev->irq = 9;
 
-	if (request_irq(dev->irq, ei_interrupt, 0, "ac3200")) {
+	if (request_irq(dev->irq, ei_interrupt, 0, "ac3200", NULL)) {
 		printk (" unable to get IRQ %d.\n", dev->irq);
 		return EAGAIN;
 	}
@@ -172,7 +172,7 @@
 	/* Allocate dev->priv and fill in 8390 specific dev fields. */
 	if (ethdev_init(dev)) {
 		printk (" unable to allocate memory for dev->priv.\n");
-		free_irq(dev->irq);
+		free_irq(dev->irq, NULL);
 		return -ENOMEM;
 	}
 
@@ -227,7 +227,7 @@
 	/* Someday we may enable the IRQ and shared memory here. */
 	int ioaddr = dev->base_addr;
 
-	if (request_irq(dev->irq, ei_interrupt, 0, "ac3200"))
+	if (request_irq(dev->irq, ei_interrupt, 0, "ac3200", NULL))
 		return -EAGAIN;
 #endif
 
@@ -302,7 +302,7 @@
 #ifdef notyet
 	/* We should someday disable shared memory and interrupts. */
 	outb(0x00, ioaddr + 6);	/* Disable interrupts. */
-	free_irq(dev->irq);
+	free_irq(dev->irq, NULL);
 	irq2dev_map[dev->irq] = 0;
 #endif
 
@@ -366,7 +366,7 @@
 			kfree(dev->priv);
 			dev->priv = NULL;
 			/* Someday free_irq + irq2dev may be in ac_close_card() */
-			free_irq(dev->irq);
+			free_irq(dev->irq, NULL);
 			irq2dev_map[dev->irq] = NULL;
 			release_region(dev->base_addr, AC_IO_EXTENT);
 			unregister_netdev(dev);
diff -u --recursive --new-file v1.3.69/linux/drivers/net/apricot.c linux/drivers/net/apricot.c
--- v1.3.69/linux/drivers/net/apricot.c	Wed Dec 27 09:12:13 1995
+++ linux/drivers/net/apricot.c	Fri Mar  1 07:50:42 1996
@@ -183,7 +183,7 @@
 
 static int i596_open(struct device *dev);
 static int i596_start_xmit(struct sk_buff *skb, struct device *dev);
-static void i596_interrupt(int irq, struct pt_regs *regs);
+static void i596_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static int i596_close(struct device *dev);
 static struct enet_statistics *i596_get_stats(struct device *dev);
 static void i596_add_cmd(struct device *dev, struct i596_cmd *cmd);
@@ -537,7 +537,7 @@
     if (i596_debug > 1)
 	printk("%s: i596_open() irq %d.\n", dev->name, dev->irq);
 
-    if (request_irq(dev->irq, &i596_interrupt, 0, "apricot"))
+    if (request_irq(dev->irq, &i596_interrupt, 0, "apricot", NULL))
 	return -EAGAIN;
 
     irq2dev_map[dev->irq] = dev;
@@ -549,7 +549,7 @@
 
     if (i < 4)
     {
-        free_irq(dev->irq);
+        free_irq(dev->irq, NULL);
         irq2dev_map[dev->irq] = 0;
         return -EAGAIN;
     }
@@ -743,7 +743,7 @@
 }
 
 static void
-i596_interrupt(int irq, struct pt_regs *regs)
+i596_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
     struct device *dev = (struct device *)(irq2dev_map[irq]);
     struct i596_private *lp;
@@ -934,7 +934,7 @@
 		   dev->name, lp->scb.status, lp->scb.command);
 	    break;
     	}
-    free_irq(dev->irq);
+    free_irq(dev->irq, NULL);
     irq2dev_map[dev->irq] = 0;
     remove_rx_bufs(dev);
     MOD_DEC_USE_COUNT;
diff -u --recursive --new-file v1.3.69/linux/drivers/net/arcnet.c linux/drivers/net/arcnet.c
--- v1.3.69/linux/drivers/net/arcnet.c	Fri Feb 16 11:34:07 1996
+++ linux/drivers/net/arcnet.c	Fri Mar  1 07:50:43 1996
@@ -590,7 +590,7 @@
 		char *data,int length,int daddr,int exceptA);
 static int arcnet_go_tx(struct device *dev,int enable_irq);
 
-static void arcnet_interrupt(int irq,struct pt_regs *regs);
+static void arcnet_interrupt(int irq,void *dev_id,struct pt_regs *regs);
 static void arcnet_inthandler(struct device *dev);
 
 static void arcnet_rx(struct device *dev,int recbuf);
@@ -1023,7 +1023,7 @@
 	dev->base_addr=port;
 
 	/* reserve the irq */
-	irqval = request_irq(airq,&arcnet_interrupt,0,"arcnet");
+	irqval = request_irq(airq,&arcnet_interrupt,0,"arcnet",NULL);
 	if (irqval)
 	{
 		BUGMSG(D_NORMAL,"unable to get IRQ %d (irqval=%d).\n",
@@ -1820,7 +1820,7 @@
  * as well.
  */
 static void
-arcnet_interrupt(int irq,struct pt_regs *regs)
+arcnet_interrupt(int irq,void *dev_id,struct pt_regs *regs)
 {
 	struct device *dev = (struct device *)(irq2dev_map[irq]);
 	int ioaddr;
@@ -3252,7 +3252,7 @@
 
 	if (thiscard.irq)
 	{
-		free_irq(thiscard.irq);
+		free_irq(thiscard.irq,NULL);
 		/* very important! */
 		irq2dev_map[thiscard.irq] = NULL;
 	}
diff -u --recursive --new-file v1.3.69/linux/drivers/net/at1700.c linux/drivers/net/at1700.c
--- v1.3.69/linux/drivers/net/at1700.c	Sat Nov 25 19:04:40 1995
+++ linux/drivers/net/at1700.c	Fri Mar  1 07:50:43 1996
@@ -117,7 +117,7 @@
 static int read_eeprom(int ioaddr, int location);
 static int net_open(struct device *dev);
 static int	net_send_packet(struct sk_buff *skb, struct device *dev);
-static void net_interrupt(int irq, struct pt_regs *regs);
+static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static void net_rx(struct device *dev);
 static int net_close(struct device *dev);
 static struct enet_statistics *net_get_stats(struct device *dev);
@@ -192,7 +192,7 @@
 				 | (read_eeprom(ioaddr, 0)>>14)];
 
 	/* Snarf the interrupt vector now. */
-	if (request_irq(irq, &net_interrupt, 0, "at1700")) {
+	if (request_irq(irq, &net_interrupt, 0, "at1700", NULL)) {
 		printk ("AT1700 found at %#3x, but it's unusable due to a conflict on"
 				"IRQ %d.\n", ioaddr, irq);
 		return EAGAIN;
@@ -440,7 +440,7 @@
 /* The typical workload of the driver:
    Handle the network interface interrupts. */
 static void
-net_interrupt(int irq, struct pt_regs *regs)
+net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct device *dev = (struct device *)(irq2dev_map[irq]);
 	struct net_local *lp;
@@ -660,7 +660,7 @@
 	dev_at1700.priv = NULL;
 
 	/* If we don't do this, we can't re-insmod it later. */
-	free_irq(dev_at1700.irq);
+	free_irq(dev_at1700.irq, NULL);
 	irq2dev_map[dev_at1700.irq] = NULL;
 	release_region(dev_at1700.base_addr, AT1700_IO_EXTENT);
 }
diff -u --recursive --new-file v1.3.69/linux/drivers/net/atp.c linux/drivers/net/atp.c
--- v1.3.69/linux/drivers/net/atp.c	Sat Nov 25 19:04:40 1995
+++ linux/drivers/net/atp.c	Fri Mar  1 07:50:43 1996
@@ -135,7 +135,7 @@
 static void write_packet(short ioaddr, int length, unsigned char *packet, int mode);
 static void trigger_send(short ioaddr, int length);
 static int	net_send_packet(struct sk_buff *skb, struct device *dev);
-static void net_interrupt(int irq, struct pt_regs *regs);
+static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static void net_rx(struct device *dev);
 static void read_block(short ioaddr, int length, unsigned char *buffer, int data_mode);
 static int net_close(struct device *dev);
@@ -328,7 +328,7 @@
 	   port or interrupt may be shared. */
 	if (irq2dev_map[dev->irq] != 0
 		|| (irq2dev_map[dev->irq] = dev) == 0
-		|| request_irq(dev->irq, &net_interrupt, 0, "ATP")) {
+		|| request_irq(dev->irq, &net_interrupt, 0, "ATP", NULL)) {
 		return -EAGAIN;
 	}
 
@@ -484,7 +484,7 @@
 /* The typical workload of the driver:
    Handle the network interface interrupts. */
 static void
-net_interrupt(int irq, struct pt_regs * regs)
+net_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
 	struct device *dev = (struct device *)(irq2dev_map[irq]);
 	struct net_local *lp;
@@ -736,7 +736,7 @@
 
 	/* Free the IRQ line. */
 	outb(0x00, ioaddr + PAR_CONTROL);
-	free_irq(dev->irq);
+	free_irq(dev->irq, NULL);
 	irq2dev_map[dev->irq] = 0;
 
 	/* Leave the hardware in a reset state. */
diff -u --recursive --new-file v1.3.69/linux/drivers/net/auto_irq.c linux/drivers/net/auto_irq.c
--- v1.3.69/linux/drivers/net/auto_irq.c	Tue Aug 15 20:39:02 1995
+++ linux/drivers/net/auto_irq.c	Fri Mar  1 07:50:43 1996
@@ -50,7 +50,7 @@
 static unsigned long irq_handled;		/* The irq lines we have a handler on. */
 static volatile int irq_number;			/* The latest irq number we actually found. */
 
-static void autoirq_probe(int irq, struct pt_regs * regs)
+static void autoirq_probe(int irq, void *dev_id, struct pt_regs * regs)
 {
 	irq_number = irq;
 	set_bit(irq, (void *)&irq_bitmap);	/* irq_bitmap |= 1 << irq; */
@@ -67,7 +67,7 @@
 	irq_handled = 0;
 	for (i = 0; i < 16; i++) {
 		if (test_bit(i, &irqs_busy) == 0
-			&& request_irq(i, autoirq_probe, SA_INTERRUPT, "irq probe") == 0)
+			&& request_irq(i, autoirq_probe, SA_INTERRUPT, "irq probe", NULL) == 0)
 			set_bit(i, (void *)&irq_handled);	/* irq_handled |= 1 << i;*/
 	}
 	/* Update our USED lists. */
@@ -85,7 +85,7 @@
 #ifdef notdef
 			printk(" Spurious interrupt on IRQ %d\n", i);
 #endif
-			free_irq(i);
+			free_irq(i, NULL);
 		}
 	}
 	return irq_handled;
@@ -106,7 +106,7 @@
 	/* Retract the irq handlers that we installed. */
 	for (i = 0; i < 16; i++) {
 		if (test_bit(i, (void *)&irq_handled))
-			free_irq(i);
+			free_irq(i, NULL);
 	}
 	return irq_number;
 }
diff -u --recursive --new-file v1.3.69/linux/drivers/net/de4x5.c linux/drivers/net/de4x5.c
--- v1.3.69/linux/drivers/net/de4x5.c	Sun Dec 17 11:43:18 1995
+++ linux/drivers/net/de4x5.c	Fri Mar  1 07:50:43 1996
@@ -396,7 +396,7 @@
 */
 static int     de4x5_open(struct device *dev);
 static int     de4x5_queue_pkt(struct sk_buff *skb, struct device *dev);
-static void    de4x5_interrupt(int irq, struct pt_regs *regs);
+static void    de4x5_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static int     de4x5_close(struct device *dev);
 static struct  enet_statistics *de4x5_get_stats(struct device *dev);
 static void    set_multicast_list(struct device *dev);
@@ -761,7 +761,7 @@
     dce_ms_delay(10);
   }
 
-  if (request_irq(dev->irq, (void *)de4x5_interrupt, 0, lp->adapter_name)) {
+  if (request_irq(dev->irq, (void *)de4x5_interrupt, SA_SHIRQ, lp->adapter_name, dev)) {
     printk("de4x5_open(): Requested IRQ%d is busy\n",dev->irq);
     status = -EAGAIN;
   } else {
@@ -1065,9 +1065,9 @@
 ** interrupt is asserted and this routine entered.
 */
 static void
-de4x5_interrupt(int irq, struct pt_regs *regs)
+de4x5_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-    struct device *dev = (struct device *)(irq2dev_map[irq]);
+    struct device *dev = (struct device *)dev_id;
     struct de4x5_private *lp;
     s32 imr, omr, sts;
     u_long iobase;
@@ -1332,7 +1332,7 @@
   /*
   ** Free the associated irq
   */
-  free_irq(dev->irq);
+  free_irq(dev->irq, dev);
   irq2dev_map[dev->irq] = 0;
 
   MOD_DEC_USE_COUNT;
diff -u --recursive --new-file v1.3.69/linux/drivers/net/de600.c linux/drivers/net/de600.c
--- v1.3.69/linux/drivers/net/de600.c	Thu Nov  9 11:23:49 1995
+++ linux/drivers/net/de600.c	Fri Mar  1 07:50:43 1996
@@ -247,7 +247,7 @@
 static int	de600_start_xmit(struct sk_buff *skb, struct device *dev);
 
 /* Dispatch from interrupts. */
-static void	de600_interrupt(int irq, struct pt_regs *regs);
+static void	de600_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static int	de600_tx_intr(struct device *dev, int irq_status);
 static void	de600_rx_intr(struct device *dev);
 
@@ -336,7 +336,7 @@
 static int
 de600_open(struct device *dev)
 {
-	if (request_irq(DE600_IRQ, de600_interrupt, 0, "de600")) {
+	if (request_irq(DE600_IRQ, de600_interrupt, 0, "de600", NULL)) {
 		printk ("%s: unable to get IRQ %d\n", dev->name, DE600_IRQ);
 		return 1;
 	}
@@ -365,7 +365,7 @@
 	select_prn();
 
 	if (dev->start) {
-		free_irq(DE600_IRQ);
+		free_irq(DE600_IRQ, NULL);
 		irq2dev_map[DE600_IRQ] = NULL;
 		dev->start = 0;
 		MOD_DEC_USE_COUNT;
@@ -488,7 +488,7 @@
  * Handle the network interface interrupts.
  */
 static void
-de600_interrupt(int irq, struct pt_regs * regs)
+de600_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
 	struct device	*dev = irq2dev_map[irq];
 	byte		irq_status;
diff -u --recursive --new-file v1.3.69/linux/drivers/net/de620.c linux/drivers/net/de620.c
--- v1.3.69/linux/drivers/net/de620.c	Sat Nov 25 19:04:41 1995
+++ linux/drivers/net/de620.c	Fri Mar  1 07:50:43 1996
@@ -210,7 +210,7 @@
 static int	de620_start_xmit(struct sk_buff *, struct device *);
 
 /* Dispatch from interrupts. */
-static void	de620_interrupt(int, struct pt_regs *);
+static void	de620_interrupt(int, void *, struct pt_regs *);
 static int	de620_rx_intr(struct device *);
 
 /* Initialization */
@@ -432,7 +432,7 @@
 static int
 de620_open(struct device *dev)
 {
-	if (request_irq(dev->irq, de620_interrupt, 0, "de620")) {
+	if (request_irq(dev->irq, de620_interrupt, 0, "de620", NULL)) {
 		printk ("%s: unable to get IRQ %d\n", dev->name, dev->irq);
 		return 1;
 	}
@@ -457,7 +457,7 @@
 	/* disable recv */
 	de620_set_register(dev, W_TCR, RXOFF);
 
-	free_irq(dev->irq);
+	free_irq(dev->irq, NULL);
 	irq2dev_map[dev->irq] = NULL;
 
 	dev->start = 0;
@@ -598,7 +598,7 @@
  *
  */
 static void
-de620_interrupt(int irq_in, struct pt_regs *regs)
+de620_interrupt(int irq_in, void *dev_id, struct pt_regs *regs)
 {
 	struct device *dev = irq2dev_map[irq_in];
 	byte irq_status;
diff -u --recursive --new-file v1.3.69/linux/drivers/net/depca.c linux/drivers/net/depca.c
--- v1.3.69/linux/drivers/net/depca.c	Tue Feb 20 14:37:23 1996
+++ linux/drivers/net/depca.c	Fri Mar  1 07:50:43 1996
@@ -381,7 +381,7 @@
 */
 static int    depca_open(struct device *dev);
 static int    depca_start_xmit(struct sk_buff *skb, struct device *dev);
-static void   depca_interrupt(int irq, struct pt_regs * regs);
+static void   depca_interrupt(int irq, void *dev_id, struct pt_regs * regs);
 static int    depca_close(struct device *dev);
 static int    depca_ioctl(struct device *dev, struct ifreq *rq, int cmd);
 static struct enet_statistics *depca_get_stats(struct device *dev);
@@ -704,7 +704,7 @@
 
   depca_dbg_open(dev);
 
-  if (request_irq(dev->irq, &depca_interrupt, 0, lp->adapter_name)) {
+  if (request_irq(dev->irq, &depca_interrupt, 0, lp->adapter_name, NULL)) {
     printk("depca_open(): Requested IRQ%d is busy\n",dev->irq);
     status = -EAGAIN;
   } else {
@@ -836,7 +836,7 @@
 ** The DEPCA interrupt handler. 
 */
 static void
-depca_interrupt(int irq, struct pt_regs * regs)
+depca_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
   struct device *dev = (struct device *)(irq2dev_map[irq]);
   struct depca_private *lp;
@@ -1059,7 +1059,7 @@
   /*
   ** Free the associated irq
   */
-  free_irq(dev->irq);
+  free_irq(dev->irq, NULL);
   irq2dev_map[dev->irq] = NULL;
 
   MOD_DEC_USE_COUNT;
diff -u --recursive --new-file v1.3.69/linux/drivers/net/e2100.c linux/drivers/net/e2100.c
--- v1.3.69/linux/drivers/net/e2100.c	Wed Dec 13 09:02:46 1995
+++ linux/drivers/net/e2100.c	Fri Mar  1 07:50:43 1996
@@ -177,7 +177,7 @@
 	if (dev->irq < 2) {
 		int irqlist[] = {15,11,10,12,5,9,3,4}, i;
 		for (i = 0; i < 8; i++)
-			if (request_irq (irqlist[i], NULL, 0, "bogus") != -EBUSY) {
+			if (request_irq (irqlist[i], NULL, 0, "bogus", NULL) != -EBUSY) {
 				dev->irq = irqlist[i];
 				break;
 			}
@@ -253,7 +253,7 @@
 {
 	short ioaddr = dev->base_addr;
 
-	if (request_irq(dev->irq, ei_interrupt, 0, "e2100")) {
+	if (request_irq(dev->irq, ei_interrupt, 0, "e2100", NULL)) {
 		return EBUSY;
 	}
 	irq2dev_map[dev->irq] = dev;
@@ -352,7 +352,7 @@
 	if (ei_debug > 1)
 		printk("%s: Shutting down ethercard.\n", dev->name);
 
-	free_irq(dev->irq);
+	free_irq(dev->irq, NULL);
 	dev->irq = ei_status.saved_irq;
 
 	/* Shut off the interrupt line and secondary interface. */
diff -u --recursive --new-file v1.3.69/linux/drivers/net/eepro.c linux/drivers/net/eepro.c
--- v1.3.69/linux/drivers/net/eepro.c	Sat Nov 25 19:04:46 1995
+++ linux/drivers/net/eepro.c	Fri Mar  1 07:50:44 1996
@@ -135,7 +135,7 @@
 static int	eepro_probe1(struct device *dev, short ioaddr);
 static int	eepro_open(struct device *dev);
 static int	eepro_send_packet(struct sk_buff *skb, struct device *dev);
-static void	eepro_interrupt(int irq, struct pt_regs *regs);
+static void	eepro_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static void 	eepro_rx(struct device *dev);
 static void 	eepro_transmit_interrupt(struct device *dev);
 static int	eepro_close(struct device *dev);
@@ -376,7 +376,7 @@
 			if (dev->irq > 2) {
 				printk(", IRQ %d, %s.\n", dev->irq,
 						ifmap[dev->if_port]);
-				if (request_irq(dev->irq, &eepro_interrupt, 0, "eepro")) {
+				if (request_irq(dev->irq, &eepro_interrupt, 0, "eepro", NULL)) {
 					printk("%s: unable to get IRQ %d.\n", dev->name, dev->irq);
 					return -EAGAIN;
 				}
@@ -462,14 +462,14 @@
 
 		outb(BANK0_SELECT, ioaddr); /* Switch back to Bank 0 */
 
-		if (request_irq (*irqp, NULL, 0, "bogus") != EBUSY) {
+		if (request_irq (*irqp, NULL, 0, "bogus", NULL) != EBUSY) {
 			/* Twinkle the interrupt, and check if it's seen */
 			autoirq_setup(0);
 
 			outb(DIAGNOSE_CMD, ioaddr); /* RESET the 82595 */
 				
 			if (*irqp == autoirq_report(2) &&  /* It's a good IRQ line */
-				(request_irq(dev->irq = *irqp, &eepro_interrupt, 0, "eepro") == 0)) 
+				(request_irq(dev->irq = *irqp, &eepro_interrupt, 0, "eepro", NULL) == 0)) 
 					break;
 
 			/* clear all interrupts */
@@ -661,7 +661,7 @@
 /*	The typical workload of the driver:
 	Handle the network interface interrupts. */
 static void
-eepro_interrupt(int irq, struct pt_regs * regs)
+eepro_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
 	struct device *dev = (struct device *)(irq2dev_map[irq]);
 	int ioaddr, status, boguscount = 0;
@@ -744,7 +744,7 @@
 	outb(RESET_CMD, ioaddr); 
 
 	/* release the interrupt */
-	free_irq(dev->irq);
+	free_irq(dev->irq, NULL);
 
 	irq2dev_map[dev->irq] = 0;
 
diff -u --recursive --new-file v1.3.69/linux/drivers/net/eexpress.c linux/drivers/net/eexpress.c
--- v1.3.69/linux/drivers/net/eexpress.c	Sat Nov 25 19:04:46 1995
+++ linux/drivers/net/eexpress.c	Fri Mar  1 07:50:44 1996
@@ -286,7 +286,7 @@
 static int	eexp_probe1(struct device *dev, short ioaddr);
 static int	eexp_open(struct device *dev);
 static int	eexp_send_packet(struct sk_buff *skb, struct device *dev);
-static void	eexp_interrupt(int irq, struct pt_regs *regs);
+static void	eexp_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static void eexp_rx(struct device *dev);
 static int	eexp_close(struct device *dev);
 static struct enet_statistics *eexp_get_stats(struct device *dev);
@@ -429,7 +429,7 @@
 	if (irq2dev_map[dev->irq] != 0
 		/* This is always true, but avoid the false IRQ. */
 		|| (irq2dev_map[dev->irq] = dev) == 0
-		|| request_irq(dev->irq, &eexp_interrupt, 0, "EExpress")) {
+		|| request_irq(dev->irq, &eexp_interrupt, 0, "EExpress", NULL)) {
 		return -EAGAIN;
 	}
 
@@ -513,7 +513,7 @@
 /*	The typical workload of the driver:
 	Handle the network interface interrupts. */
 static void
-eexp_interrupt(int irq, struct pt_regs *regs)
+eexp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct device *dev = (struct device *)(irq2dev_map[irq]);
 	struct net_local *lp;
@@ -648,7 +648,7 @@
 	/* Disable the physical interrupt line. */
 	outb(0, ioaddr + SET_IRQ);
 
-	free_irq(dev->irq);
+	free_irq(dev->irq, NULL);
 
 	irq2dev_map[dev->irq] = 0;
 
diff -u --recursive --new-file v1.3.69/linux/drivers/net/eth16i.c linux/drivers/net/eth16i.c
--- v1.3.69/linux/drivers/net/eth16i.c	Sat Nov 25 19:04:46 1995
+++ linux/drivers/net/eth16i.c	Fri Mar  1 07:50:44 1996
@@ -326,7 +326,7 @@
 static int eth16i_close(struct device *dev);
 static int eth16i_tx(struct sk_buff *skb, struct device *dev);
 static void eth16i_rx(struct device *dev);
-static void eth16i_interrupt(int irq, struct pt_regs *regs);
+static void eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static void eth16i_multicast(struct device *dev, int num_addrs, void *addrs); 
 static void eth16i_select_regbank(unsigned char regbank, short ioaddr);
 static void eth16i_initialize(struct device *dev);
@@ -423,7 +423,7 @@
   dev->irq = irq;
 
   /* Try to obtain interrupt vector */
-  if(request_irq(dev->irq, &eth16i_interrupt, 0, "eth16i")) {
+  if(request_irq(dev->irq, &eth16i_interrupt, 0, "eth16i", NULL)) {
     printk("%s: %s at %#3x, but is unusable due 
            conflict on IRQ %d.\n", dev->name, cardname, ioaddr, irq);
     return EAGAIN;
@@ -1086,7 +1086,7 @@
   return;
 }
 
-static void eth16i_interrupt(int irq, struct pt_regs *regs)
+static void eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
   struct device *dev = (struct device *)(irq2dev_map[irq]);
   struct eth16i_local *lp;
@@ -1204,7 +1204,7 @@
 void cleanup_module(void)
 {
 	unregister_netdev( &dev_eth16i );
-	free_irq( dev_eth16i.irq );
+	free_irq( dev_eth16i.irq, NULL );
 	irq2dev_map[ dev_eth16i.irq ] = NULL;
 	release_region( dev_eth16i.base_addr, ETH16I_IO_EXTENT );
 }
diff -u --recursive --new-file v1.3.69/linux/drivers/net/ewrk3.c linux/drivers/net/ewrk3.c
--- v1.3.69/linux/drivers/net/ewrk3.c	Tue Jan  2 16:46:25 1996
+++ linux/drivers/net/ewrk3.c	Fri Mar  1 07:50:44 1996
@@ -130,11 +130,12 @@
                           Added verify_area() calls in depca_ioctl() from
                           suggestion by <heiko@colossus.escape.de>.
 			  Add new multicasting code.
+      0.41    20-Jan-96   Fix IRQ set up problem reported by <???>.
 
     =========================================================================
 */
 
-static const char *version = "ewrk3.c:v0.40 95/12/27 davies@wanton.lkg.dec.com\n";
+static const char *version = "ewrk3.c:v0.41 96/1/20 davies@wanton.lkg.dec.com\n";
 
 #include <linux/module.h>
 
@@ -205,7 +206,7 @@
 #define CRC_POLYNOMIAL_BE 0x04c11db7UL   /* Ethernet CRC, big endian */
 #define CRC_POLYNOMIAL_LE 0xedb88320UL   /* Ethernet CRC, little endian */
 
-#define QUEUE_PKT_TIMEOUT (100)          /* Jiffies */
+#define QUEUE_PKT_TIMEOUT (1*HZ)         /* Jiffies */
 
 /*
 ** EtherWORKS 3 shared memory window sizes
@@ -286,7 +287,7 @@
 */
 static int    ewrk3_open(struct device *dev);
 static int    ewrk3_queue_pkt(struct sk_buff *skb, struct device *dev);
-static void   ewrk3_interrupt(int irq, struct pt_regs *regs);
+static void   ewrk3_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static int    ewrk3_close(struct device *dev);
 static struct enet_statistics *ewrk3_get_stats(struct device *dev);
 static void   set_multicast_list(struct device *dev);
@@ -389,7 +390,7 @@
   nicsr = inb(EWRK3_CSR);
 
   icr = inb(EWRK3_ICR);
-  icr |= 0xf0;
+  icr &= 0x70;
   outb(icr, EWRK3_ICR);                           /* Disable all the IRQs */
 
   if (nicsr == CSR_TXD|CSR_RXD) {
@@ -624,7 +625,7 @@
   if (!lp->hard_strapped) {
     irq2dev_map[dev->irq] = dev;                   /* For latched interrupts */
 
-    if (request_irq(dev->irq, (void *)ewrk3_interrupt, 0, "ewrk3")) {
+    if (request_irq(dev->irq, (void *)ewrk3_interrupt, 0, "ewrk3", NULL)) {
       printk("ewrk3_open(): Requested IRQ%d is busy\n",dev->irq);
       status = -EAGAIN;
     } else {
@@ -812,7 +813,7 @@
 	    for (i=0; i<skb->len; i++) {
 	      outb(*p++, EWRK3_DATA);
 	    }
-	    outb(page, EWRK3_TQ);                     /* Start sending pkt */
+	    outb(page, EWRK3_TQ);                      /* Start sending pkt */
 	  } else {
 	    writeb((char)(TCR_QMODE|TCR_PAD|TCR_IFC), (char *)buf);/* ctrl byte*/
 	    buf+=1;
@@ -821,20 +822,20 @@
 	    if (lp->txc) {
 	      writeb((char)(((skb->len >> 8) & 0xff) | XCT), (char *)buf);
 	      buf+=1;
-	      writeb(0x04, (char *)buf);                 /* index byte */
+	      writeb(0x04, (char *)buf);               /* index byte */
 	      buf+=1;
-	      writeb(0x00, (char *)(buf + skb->len));    /* Write the XCT flag */
+	      writeb(0x00, (char *)(buf + skb->len));  /* Write the XCT flag */
 	      memcpy_toio(buf, skb->data, PRELOAD);/* Write PRELOAD bytes*/
-	      outb(page, EWRK3_TQ);                   /* Start sending pkt */
+	      outb(page, EWRK3_TQ);                    /* Start sending pkt */
 	      memcpy_toio(buf+PRELOAD, skb->data+PRELOAD, skb->len-PRELOAD);
-	      writeb(0xff, (char *)(buf + skb->len));    /* Write the XCT flag */
+	      writeb(0xff, (char *)(buf + skb->len));  /* Write the XCT flag */
 	    } else {
 	      writeb((char)((skb->len >> 8) & 0xff), (char *)buf);
 	      buf+=1;
-	      writeb(0x04, (char *)buf);                 /* index byte */
+	      writeb(0x04, (char *)buf);               /* index byte */
 	      buf+=1;
 	      memcpy_toio((char *)buf, skb->data, skb->len);/* Write data bytes */
-	      outb(page, EWRK3_TQ);                   /* Start sending pkt */
+	      outb(page, EWRK3_TQ);                    /* Start sending pkt */
 	    }
 	  }
 
@@ -869,7 +870,7 @@
 ** The EWRK3 interrupt handler. 
 */
 static void
-ewrk3_interrupt(int irq, struct pt_regs * regs)
+ewrk3_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
     struct device *dev = (struct device *)(irq2dev_map[irq]);
     struct ewrk3_private *lp;
@@ -1144,7 +1145,7 @@
   while (inb(EWRK3_RQ));
 
   if (!lp->hard_strapped) {
-    free_irq(dev->irq);
+    free_irq(dev->irq, NULL);
     
     irq2dev_map[dev->irq] = 0;
   }
@@ -1910,8 +1911,6 @@
 void
 cleanup_module(void)
 {
-  release_region(thisEthwrk.base_addr, EWRK3_TOTAL_SIZE);
-
   if (thisEthwrk.priv) {
     kfree(thisEthwrk.priv);
     thisEthwrk.priv = NULL;
@@ -1919,6 +1918,7 @@
   thisEthwrk.irq = 0;
 
   unregister_netdev(&thisEthwrk);
+  release_region(thisEthwrk.base_addr, EWRK3_TOTAL_SIZE);
 }
 #endif /* MODULE */
 
diff -u --recursive --new-file v1.3.69/linux/drivers/net/hp-plus.c linux/drivers/net/hp-plus.c
--- v1.3.69/linux/drivers/net/hp-plus.c	Fri Nov 17 08:42:25 1995
+++ linux/drivers/net/hp-plus.c	Fri Mar  1 07:50:44 1996
@@ -258,7 +258,7 @@
 	int ioaddr = dev->base_addr - NIC_OFFSET;
 	int option_reg;
 
-	if (request_irq(dev->irq, &ei_interrupt, 0, "hp-plus")) {
+	if (request_irq(dev->irq, &ei_interrupt, 0, "hp-plus", NULL)) {
 	    return -EAGAIN;
 	}
 
@@ -287,7 +287,7 @@
 	int ioaddr = dev->base_addr - NIC_OFFSET;
 	int option_reg = inw(ioaddr + HPP_OPTION);
 
-	free_irq(dev->irq);
+	free_irq(dev->irq, NULL);
 	irq2dev_map[dev->irq] = NULL;
 	ei_close(dev);
 	outw((option_reg & ~EnableIRQ) | MemDisable | NICReset | ChipReset,
diff -u --recursive --new-file v1.3.69/linux/drivers/net/hp.c linux/drivers/net/hp.c
--- v1.3.69/linux/drivers/net/hp.c	Fri Nov 17 08:42:25 1995
+++ linux/drivers/net/hp.c	Fri Mar  1 07:50:44 1996
@@ -150,13 +150,13 @@
 		int *irqp = wordmode ? irq_16list : irq_8list;
 		do {
 			int irq = *irqp;
-			if (request_irq (irq, NULL, 0, "bogus") != -EBUSY) {
+			if (request_irq (irq, NULL, 0, "bogus", NULL) != -EBUSY) {
 				autoirq_setup(0);
 				/* Twinkle the interrupt, and check if it's seen. */
 				outb_p(irqmap[irq] | HP_RUN, ioaddr + HP_CONFIGURE);
 				outb_p( 0x00 | HP_RUN, ioaddr + HP_CONFIGURE);
 				if (irq == autoirq_report(0)		 /* It's a good IRQ line! */
-					&& request_irq (irq, &ei_interrupt, 0, "hp") == 0) {
+					&& request_irq (irq, &ei_interrupt, 0, "hp", NULL) == 0) {
 					printk(" selecting IRQ %d.\n", irq);
 					dev->irq = *irqp;
 					break;
@@ -170,7 +170,7 @@
 	} else {
 		if (dev->irq == 2)
 			dev->irq = 9;
-		if (request_irq(dev->irq, ei_interrupt, 0, "hp")) {
+		if (request_irq(dev->irq, ei_interrupt, 0, "hp", NULL)) {
 			printk (" unable to get IRQ %d.\n", dev->irq);
 			return EBUSY;
 		}
@@ -179,7 +179,7 @@
 	/* Allocate dev->priv and fill in 8390 specific dev fields. */
 	if (ethdev_init(dev)) {
 		printk (" unable to get memory for dev->priv.\n");
-		free_irq(dev->irq);
+		free_irq(dev->irq, NULL);
 		return -ENOMEM;
 	}
 
@@ -431,7 +431,7 @@
 			int ioaddr = dev->base_addr - NIC_OFFSET;
 			kfree(dev->priv);
 			dev->priv = NULL;
-			free_irq(dev->irq);
+			free_irq(dev->irq, NULL);
 			irq2dev_map[dev->irq] = NULL;
 			release_region(ioaddr, HP_IO_EXTENT);
 			unregister_netdev(dev);
diff -u --recursive --new-file v1.3.69/linux/drivers/net/hp100.c linux/drivers/net/hp100.c
--- v1.3.69/linux/drivers/net/hp100.c	Sat Nov 25 19:04:46 1995
+++ linux/drivers/net/hp100.c	Fri Mar  1 07:50:44 1996
@@ -196,7 +196,7 @@
 static void hp100_update_stats( struct device *dev );
 static void hp100_clear_stats( int ioaddr );
 static void hp100_set_multicast_list( struct device *dev);
-static void hp100_interrupt( int irq, struct pt_regs *regs );
+static void hp100_interrupt( int irq, void *dev_id, struct pt_regs *regs );
 
 static void hp100_start_interface( struct device *dev );
 static void hp100_stop_interface( struct device *dev );
@@ -488,7 +488,7 @@
   int ioaddr = dev -> base_addr;
   struct hp100_private *lp = (struct hp100_private *)dev -> priv;
 
-  if ( request_irq( dev -> irq, hp100_interrupt, SA_INTERRUPT, lp -> id -> name ) )
+  if ( request_irq( dev -> irq, hp100_interrupt, SA_INTERRUPT, lp -> id -> name, NULL ) )
     {
       printk( "%s: unable to get IRQ %d\n", dev -> name, dev -> irq );
       return -EAGAIN;
@@ -561,7 +561,7 @@
   dev -> tbusy = 1;
   dev -> start = 0;
 
-  free_irq( dev -> irq );
+  free_irq( dev -> irq, NULL );
   irq2dev_map[ dev -> irq ] = NULL;
   MOD_DEC_USE_COUNT;
   return 0;
@@ -890,7 +890,7 @@
  *  hardware interrupt handling
  */
 
-static void hp100_interrupt( int irq, struct pt_regs *regs )
+static void hp100_interrupt( int irq, void *dev_id, struct pt_regs *regs )
 {
   struct device *dev = (struct device *)irq2dev_map[ irq ];
   struct hp100_private *lp;
diff -u --recursive --new-file v1.3.69/linux/drivers/net/ibmtr.c linux/drivers/net/ibmtr.c
--- v1.3.69/linux/drivers/net/ibmtr.c	Sun Feb 11 15:32:45 1996
+++ linux/drivers/net/ibmtr.c	Fri Mar  1 07:50:44 1996
@@ -134,7 +134,7 @@
 unsigned char get_sram_size(struct tok_info *adapt_info);
 
 static void tok_init_card(unsigned long dev_addr);
-static void tok_interrupt(int irq, struct pt_regs *regs);
+static void tok_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 
 static void initial_tok_int(struct device *dev);
 
@@ -481,7 +481,7 @@
   DPRINTK("Using %dK shared RAM\n",ti->mapped_ram_size/2);
 #endif
 
-  if (request_irq (dev->irq = irq, &tok_interrupt,0,"IBM TR") != 0) {
+  if (request_irq (dev->irq = irq, &tok_interrupt,0,"IBM TR", NULL) != 0) {
     DPRINTK("Could not grab irq %d.  Halting Token Ring driver.\n",irq);
     badti = ti;    /*  keep track of unused tok_info */
     return ENODEV;
@@ -590,7 +590,7 @@
 	return 0;
 }
 
-static void tok_interrupt (int irq, struct pt_regs *regs)
+static void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs)
 {
 
 	unsigned char status;
@@ -1315,7 +1315,7 @@
 	unregister_netdev(&dev_ibmtr);
 
 	/* If we don't do this, we can't re-insmod it later. */
-	free_irq(dev_ibmtr.irq);
+	free_irq(dev_ibmtr.irq, NULL);
 	irq2dev_map[dev_ibmtr.irq] = NULL;
 	release_region(dev_ibmtr.base_addr, TR_IO_EXTENT);
 }
diff -u --recursive --new-file v1.3.69/linux/drivers/net/lance.c linux/drivers/net/lance.c
--- v1.3.69/linux/drivers/net/lance.c	Thu Jan  4 21:54:55 1996
+++ linux/drivers/net/lance.c	Fri Mar  1 07:50:44 1996
@@ -254,7 +254,7 @@
 static void lance_init_ring(struct device *dev);
 static int lance_start_xmit(struct sk_buff *skb, struct device *dev);
 static int lance_rx(struct device *dev);
-static void lance_interrupt(int irq, struct pt_regs *regs);
+static void lance_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static int lance_close(struct device *dev);
 static struct enet_statistics *lance_get_stats(struct device *dev);
 static void set_multicast_list(struct device *dev);
@@ -564,7 +564,7 @@
 	int i;
 
 	if (dev->irq == 0 ||
-		request_irq(dev->irq, &lance_interrupt, 0, lp->name)) {
+		request_irq(dev->irq, &lance_interrupt, 0, lp->name, NULL)) {
 		return -EAGAIN;
 	}
 
@@ -826,7 +826,7 @@
 
 /* The LANCE interrupt handler. */
 static void
-lance_interrupt(int irq, struct pt_regs * regs)
+lance_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
 	struct device *dev = (struct device *)(irq2dev_map[irq]);
 	struct lance_private *lp;
@@ -1056,7 +1056,7 @@
 	if (dev->dma != 4)
 		disable_dma(dev->dma);
 
-	free_irq(dev->irq);
+	free_irq(dev->irq, NULL);
 
 	irq2dev_map[dev->irq] = 0;
 
diff -u --recursive --new-file v1.3.69/linux/drivers/net/ne.c linux/drivers/net/ne.c
--- v1.3.69/linux/drivers/net/ne.c	Tue Jan 23 21:15:42 1996
+++ linux/drivers/net/ne.c	Fri Mar  1 07:50:44 1996
@@ -364,7 +364,7 @@
     /* Snarf the interrupt now.  There's no point in waiting since we cannot
        share and the board will usually be enabled. */
     {
-	int irqval = request_irq(dev->irq, ei_interrupt, 0, name);
+	int irqval = request_irq(dev->irq, ei_interrupt, 0, name, NULL);
 	if (irqval) {
 	    printk (" unable to get IRQ %d (irqval=%d).\n", dev->irq, irqval);
 	    return EAGAIN;
@@ -376,7 +376,7 @@
     /* Allocate dev->priv and fill in 8390 specific dev fields. */
     if (ethdev_init(dev)) {
 	printk (" unable to get memory for dev->priv.\n");
-	free_irq(dev->irq);
+	free_irq(dev->irq, NULL);
 	return -ENOMEM;
     }
  
@@ -715,7 +715,7 @@
 		if (dev->priv != NULL) {
 			kfree(dev->priv);
 			dev->priv = NULL;
-			free_irq(dev->irq);
+			free_irq(dev->irq, NULL);
 			irq2dev_map[dev->irq] = NULL;
 			release_region(dev->base_addr, NE_IO_EXTENT);
 			unregister_netdev(dev);
diff -u --recursive --new-file v1.3.69/linux/drivers/net/ni52.c linux/drivers/net/ni52.c
--- v1.3.69/linux/drivers/net/ni52.c	Wed Feb 28 11:50:05 1996
+++ linux/drivers/net/ni52.c	Fri Mar  1 07:56:09 1996
@@ -188,7 +188,7 @@
 #define NI52_ADDR2 0x01
 
 static int     ni52_probe1(struct device *dev,int ioaddr);
-static void    ni52_interrupt(int irq,struct pt_regs *reg_ptr);
+static void    ni52_interrupt(int irq,void *dev_id,struct pt_regs *reg_ptr);
 static int     ni52_open(struct device *dev);
 static int     ni52_close(struct device *dev);
 static int     ni52_send_packet(struct sk_buff *,struct device *);
@@ -235,7 +235,7 @@
  */
 static int ni52_close(struct device *dev)
 {
-  free_irq(dev->irq);
+  free_irq(dev->irq, NULL);
   irq2dev_map[dev->irq] = NULL;
 
   ni_reset586(); /* the hard way to stop the receiver */
@@ -259,7 +259,7 @@
   startrecv586(dev);
   ni_enaint();
 
-  if(request_irq(dev->irq, &ni52_interrupt,0,"ni5210")) 
+  if(request_irq(dev->irq, &ni52_interrupt,0,"ni5210",NULL)) 
   {
     ni_reset586();
     return -EAGAIN;
@@ -810,7 +810,7 @@
  * Interrupt Handler ...
  */
 
-static void ni52_interrupt(int irq,struct pt_regs *reg_ptr)
+static void ni52_interrupt(int irq,void *dev_id,struct pt_regs *reg_ptr)
 {
   struct device *dev = (struct device *) irq2dev_map[irq];
   unsigned short stat;
diff -u --recursive --new-file v1.3.69/linux/drivers/net/ni65.c linux/drivers/net/ni65.c
--- v1.3.69/linux/drivers/net/ni65.c	Wed Feb 28 11:50:05 1996
+++ linux/drivers/net/ni65.c	Fri Mar  1 07:58:30 1996
@@ -116,7 +116,7 @@
 #define writedatareg(val) {outw(val,PORT+L_DATAREG);inw(PORT+L_DATAREG);}
 
 static int  ni65_probe1(struct device **dev,int);
-static void ni65_interrupt(int irq, struct pt_regs *regs);
+static void ni65_interrupt(int irq, void * dev_id, struct pt_regs *regs);
 static void ni65_recv_intr(struct device *dev,int);
 static void ni65_xmit_intr(struct device *dev,int);
 static int  ni65_open(struct device *dev);
@@ -249,7 +249,7 @@
            "ni6510", dev->base_addr, dev->irq,dev->dma);
 
   {        
-    int irqval = request_irq(dev->irq, &ni65_interrupt,0,"ni6510");
+    int irqval = request_irq(dev->irq, &ni65_interrupt,0,"ni6510",NULL);
     if (irqval) {
       printk ("%s: unable to get IRQ %d (irqval=%d).\n", 
                 dev->name,dev->irq, irqval);
@@ -258,7 +258,7 @@
     if(request_dma(dev->dma, "ni6510") != 0)
     {
       printk("%s: Can't request dma-channel %d\n",dev->name,(int) dev->dma);
-      free_irq(dev->irq);
+      free_irq(dev->irq,NULL);
       return -EAGAIN;
     }
   }
@@ -367,7 +367,7 @@
      printk(KERN_ERR "%s: can't RESET ni6510 card: %04x\n",dev->name,(int) inw(PORT+L_DATAREG));
      disable_dma(dev->dma);
      free_dma(dev->dma);
-     free_irq(dev->irq);
+     free_irq(dev->irq, NULL);
      return 0;
    }
 
@@ -439,7 +439,7 @@
       printk(KERN_ERR "%s: can't init am7990/lance, status: %04x\n",dev->name,(int) inw(PORT+L_DATAREG));
       disable_dma(dev->dma);
       free_dma(dev->dma);
-      free_irq(dev->irq);
+      free_irq(dev->irq, NULL);
       return 0; /* false */
     } 
 
@@ -451,7 +451,7 @@
 /* 
  * interrupt handler  
  */
-static void ni65_interrupt(int irq, struct pt_regs * regs)
+static void ni65_interrupt(int irq, void * dev_id, struct pt_regs * regs)
 {
   int csr0;
   struct device *dev = (struct device *) irq2dev_map[irq];
diff -u --recursive --new-file v1.3.69/linux/drivers/net/pi2.c linux/drivers/net/pi2.c
--- v1.3.69/linux/drivers/net/pi2.c	Tue Jan  2 16:46:25 1996
+++ linux/drivers/net/pi2.c	Fri Mar  1 07:50:45 1996
@@ -149,7 +149,7 @@
 static int pi_probe(struct device *dev, int card_type);
 static int pi_open(struct device *dev);
 static int pi_send_packet(struct sk_buff *skb, struct device *dev);
-static void pi_interrupt(int reg_ptr, struct pt_regs *regs);
+static void pi_interrupt(int reg_ptr, void *dev_id, struct pt_regs *regs);
 static int pi_close(struct device *dev);
 static int pi_ioctl(struct device *dev, struct ifreq *ifr, int cmd);
 static struct enet_statistics *pi_get_stats(struct device *dev);
@@ -1398,7 +1398,7 @@
 		   now.  There is no point in waiting since no other device can use
 		   the interrupt, and this marks the 'irqaction' as busy. */
 	{
-	    int irqval = request_irq(dev->irq, &pi_interrupt,0, "pi2");
+	    int irqval = request_irq(dev->irq, &pi_interrupt,0, "pi2", NULL);
 	    if (irqval) {
 		printk("PI: unable to get IRQ %d (irqval=%d).\n",
 		       dev->irq, irqval);
@@ -1461,7 +1461,7 @@
     if (dev->base_addr & 2) {	/* if A channel */
 	if (first_time) {
 	    if (request_dma(dev->dma,"pi2")) {
-		free_irq(dev->irq);
+		free_irq(dev->irq, NULL);
 		return -EAGAIN;
 	    }
 	    irq2dev_map[dev->irq] = dev;
@@ -1509,7 +1509,7 @@
 
 /* The typical workload of the driver:
    Handle the network interface interrupts. */
-static void pi_interrupt(int reg_ptr, struct pt_regs *regs)
+static void pi_interrupt(int reg_ptr, void *dev_id, struct pt_regs *regs)
 {
 /*    int irq = -(((struct pt_regs *) reg_ptr)->orig_eax + 2);*/
     struct pi_local *lp;
diff -u --recursive --new-file v1.3.69/linux/drivers/net/plip.c linux/drivers/net/plip.c
--- v1.3.69/linux/drivers/net/plip.c	Sat Nov 11 17:41:33 1995
+++ linux/drivers/net/plip.c	Fri Mar  1 07:50:45 1996
@@ -139,7 +139,7 @@
 static void plip_bh(struct device *dev);
 
 /* Interrupt handler */
-static void plip_interrupt(int irq, struct pt_regs *regs);
+static void plip_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 
 /* Functions for DEV methods */
 static int plip_rebuild_header(void *buff, struct device *dev,
@@ -800,7 +800,7 @@
 
 /* Handle the parallel port interrupts. */
 static void
-plip_interrupt(int irq, struct pt_regs * regs)
+plip_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
 	struct device *dev = (struct device *) irq2dev_map[irq];
 	struct net_local *nl = (struct net_local *)dev->priv;
@@ -940,7 +940,7 @@
 		return -EAGAIN;
 	}
 	cli();
-	if (request_irq(dev->irq , plip_interrupt, 0, dev->name) != 0) {
+	if (request_irq(dev->irq , plip_interrupt, 0, dev->name, NULL) != 0) {
 		sti();
 		printk("%s: couldn't get IRQ %d.\n", dev->name, dev->irq);
 		return -EAGAIN;
@@ -983,7 +983,7 @@
 	dev->tbusy = 1;
 	dev->start = 0;
 	cli();
-	free_irq(dev->irq);
+	free_irq(dev->irq, NULL);
 	irq2dev_map[dev->irq] = NULL;
 	nl->is_deferred = 0;
 	nl->connection = PLIP_CN_NONE;
diff -u --recursive --new-file v1.3.69/linux/drivers/net/pt.c linux/drivers/net/pt.c
--- v1.3.69/linux/drivers/net/pt.c	Tue Jan  2 16:46:25 1996
+++ linux/drivers/net/pt.c	Fri Mar  1 07:50:45 1996
@@ -120,7 +120,7 @@
 static int pt_probe(struct device *dev);
 static int pt_open(struct device *dev);
 static int pt_send_packet(struct sk_buff *skb, struct device *dev);
-static void pt_interrupt(int irq, struct pt_regs *regs);
+static void pt_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static int pt_close(struct device *dev);
 static int pt_ioctl(struct device *dev, struct ifreq *ifr, int cmd);
 static struct enet_statistics *pt_get_stats(struct device *dev);
@@ -868,7 +868,7 @@
          * the interrupt, and this marks the 'irqaction' as busy.
          */
         {
-            int irqval = request_irq(dev->irq, &pt_interrupt,0, "pt");
+            int irqval = request_irq(dev->irq, &pt_interrupt,0, "pt", NULL);
             if (irqval) {
                 printk("PT: ERROR: Unable to get IRQ %d (irqval = %d).\n",
                     dev->irq, irqval);
@@ -932,7 +932,7 @@
         {
             if (request_dma(dev->dma, "pt"))
             {
-                free_irq(dev->irq);
+                free_irq(dev->irq, NULL);
                 return -EAGAIN;
             }
         }
@@ -1480,7 +1480,7 @@
  * This routine is called by the kernel when there is an interrupt for the
  * PT.
  */
-static void pt_interrupt(int irq, struct pt_regs *regs)
+static void pt_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
     /* It's a tad dodgy here, but we assume pt0a until proven otherwise */
     struct device *dev = &pt0a;
diff -u --recursive --new-file v1.3.69/linux/drivers/net/seeq8005.c linux/drivers/net/seeq8005.c
--- v1.3.69/linux/drivers/net/seeq8005.c	Sat Nov 25 19:04:46 1995
+++ linux/drivers/net/seeq8005.c	Fri Mar  1 07:50:45 1996
@@ -81,7 +81,7 @@
 static int seeq8005_probe1(struct device *dev, int ioaddr);
 static int seeq8005_open(struct device *dev);
 static int seeq8005_send_packet(struct sk_buff *skb, struct device *dev);
-static void seeq8005_interrupt(int irq, struct pt_regs *regs);
+static void seeq8005_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static void seeq8005_rx(struct device *dev);
 static int seeq8005_close(struct device *dev);
 static struct enet_statistics *seeq8005_get_stats(struct device *dev);
@@ -304,7 +304,7 @@
 
 #if 0
 	{
-		 int irqval = request_irq(dev->irq, &seeq8005_interrupt, 0, "seeq8005");
+		 int irqval = request_irq(dev->irq, &seeq8005_interrupt, 0, "seeq8005", NULL);
 		 if (irqval) {
 			 printk ("%s: unable to get IRQ %d (irqval=%d).\n", dev->name,
 					 dev->irq, irqval);
@@ -350,7 +350,7 @@
 	struct net_local *lp = (struct net_local *)dev->priv;
 
 	{
-		 int irqval = request_irq(dev->irq, &seeq8005_interrupt, 0, "seeq8005");
+		 int irqval = request_irq(dev->irq, &seeq8005_interrupt, 0, "seeq8005", NULL);
 		 if (irqval) {
 			 printk ("%s: unable to get IRQ %d (irqval=%d).\n", dev->name,
 					 dev->irq, irqval);
@@ -418,7 +418,7 @@
 /* The typical workload of the driver:
    Handle the network interface interrupts. */
 static void
-seeq8005_interrupt(int irq, struct pt_regs * regs)
+seeq8005_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
 	struct device *dev = (struct device *)(irq2dev_map[irq]);
 	struct net_local *lp;
@@ -581,7 +581,7 @@
 	/* Flush the Tx and disable Rx here. */
 	outw( SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
 
-	free_irq(dev->irq);
+	free_irq(dev->irq, NULL);
 
 	irq2dev_map[dev->irq] = 0;
 
diff -u --recursive --new-file v1.3.69/linux/drivers/net/sk_g16.c linux/drivers/net/sk_g16.c
--- v1.3.69/linux/drivers/net/sk_g16.c	Sun Jan 14 16:30:11 1996
+++ linux/drivers/net/sk_g16.c	Fri Mar  1 07:50:45 1996
@@ -63,7 +63,6 @@
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/malloc.h>
-#include <linux/ioport.h>
 #include <linux/string.h> 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -487,7 +486,7 @@
 
 static int   SK_open(struct device *dev);
 static int   SK_send_packet(struct sk_buff *skb, struct device *dev);
-static void  SK_interrupt(int irq, struct pt_regs * regs);
+static void  SK_interrupt(int irq, void *dev_id, struct pt_regs * regs);
 static void  SK_rxintr(struct device *dev);
 static void  SK_txintr(struct device *dev);
 static int   SK_close(struct device *dev);
@@ -886,7 +885,7 @@
 
 	do
 	{
-	  irqval = request_irq(irqtab[i], &SK_interrupt, 0, "sk_g16");
+	  irqval = request_irq(irqtab[i], &SK_interrupt, 0, "sk_g16", NULL);
 	  i++;
 	} while (irqval && irqtab[i]);
 
@@ -903,7 +902,7 @@
     }
     else if (dev->irq == 2) /* IRQ2 is always IRQ9 */
     {
-	if (request_irq(9, &SK_interrupt, 0, "sk_g16"))
+	if (request_irq(9, &SK_interrupt, 0, "sk_g16", NULL))
 	{
 	    printk("%s: unable to get IRQ 9\n", dev->name);
 	    return -EAGAIN;
@@ -924,7 +923,7 @@
 
 	/* check if IRQ free and valid. Then install Interrupt handler */
 
-	if (request_irq(dev->irq, &SK_interrupt, 0, "sk_g16"))
+	if (request_irq(dev->irq, &SK_interrupt, 0, "sk_g16", NULL))
 	{
 	    printk("%s: unable to get selected IRQ\n", dev->name);
 	    return -EAGAIN;
@@ -1299,7 +1298,7 @@
  * Description    : SK_G16 interrupt handler which checks for LANCE
  *                  Errors, handles transmit and receive interrupts
  *
- * Parameters     : I : int irq, struct pt_regs * regs -
+ * Parameters     : I : int irq, void *dev_id, struct pt_regs * regs -
  * Return Value   : None
  * Errors         : None
  * Globals        : None
@@ -1308,7 +1307,7 @@
  *     YY/MM/DD  uid  Description
 -*/
 
-static void SK_interrupt(int irq, struct pt_regs * regs)
+static void SK_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
     int csr0;
     struct device *dev = (struct device *) irq2dev_map[irq];
@@ -1665,7 +1664,7 @@
 
     SK_write_reg(CSR0, CSR0_STOP); /* STOP the LANCE */
 
-    free_irq(dev->irq);            /* Free IRQ */
+    free_irq(dev->irq, NULL);      /* Free IRQ */
     irq2dev_map[dev->irq] = 0;     /* Mark IRQ as unused */
 
     return 0; /* always succeed */
diff -u --recursive --new-file v1.3.69/linux/drivers/net/skeleton.c linux/drivers/net/skeleton.c
--- v1.3.69/linux/drivers/net/skeleton.c	Tue Jan  2 16:46:26 1996
+++ linux/drivers/net/skeleton.c	Fri Mar  1 07:50:45 1996
@@ -100,7 +100,7 @@
 static int netcard_probe1(struct device *dev, int ioaddr);
 static int net_open(struct device *dev);
 static int	net_send_packet(struct sk_buff *skb, struct device *dev);
-static void net_interrupt(int irq, struct pt_regs *regs);
+static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static void net_rx(struct device *dev);
 static int net_close(struct device *dev);
 static struct enet_statistics *net_get_stats(struct device *dev);
@@ -220,7 +220,7 @@
 		dev->irq = 9;
 
 	{
-		int irqval = request_irq(dev->irq, &net_interrupt, 0, cardname);
+		int irqval = request_irq(dev->irq, &net_interrupt, 0, cardname, NULL);
 		if (irqval) {
 			printk("%s: unable to get IRQ %d (irqval=%d).\n",
 				   dev->name, dev->irq, irqval);
@@ -313,7 +313,7 @@
 	 * This is used if the interrupt line can turned off (shared).
 	 * See 3c503.c for an example of selecting the IRQ at config-time.
 	 */
-	if (request_irq(dev->irq, &net_interrupt, 0, cardname)) {
+	if (request_irq(dev->irq, &net_interrupt, 0, cardname, NULL)) {
 		return -EAGAIN;
 	}
 	/*
@@ -321,7 +321,7 @@
 	 * and clean up on failure.
 	 */
 	if (request_dma(dev->dma, cardname)) {
-		free_irq(dev->irq);
+		free_irq(dev->irq, NULL);
 		return -EAGAIN;
 	}
 	irq2dev_map[dev->irq] = dev;
@@ -397,7 +397,7 @@
  *   Handle the network interface interrupts.
  */
 static void
-net_interrupt(int irq, struct pt_regs * regs)
+net_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
 	struct device *dev = (struct device *)(irq2dev_map[irq]);
 	struct net_local *lp;
@@ -505,7 +505,7 @@
 	/* If not IRQ or DMA jumpered, free up the line. */
 	outw(0x00, ioaddr+0);	/* Release the physical interrupt line. */
 
-	free_irq(dev->irq);
+	free_irq(dev->irq, NULL);
 	free_dma(dev->dma);
 
 	irq2dev_map[dev->irq] = 0;
@@ -615,7 +615,7 @@
 	 * allocate them in net_probe1().
 	 */
 	/*
-	   free_irq(this_device.irq);
+	   free_irq(this_device.irq, NULL);
 	   free_dma(this_device.dma);
 	*/
 	release_region(this_device.base_addr, NETCARD_IO_EXTENT);
diff -u --recursive --new-file v1.3.69/linux/drivers/net/slip.c linux/drivers/net/slip.c
--- v1.3.69/linux/drivers/net/slip.c	Wed Feb 28 11:50:05 1996
+++ linux/drivers/net/slip.c	Fri Mar  1 10:03:41 1996
@@ -1335,12 +1335,17 @@
 	{
 		for (i = 0; i < slip_maxdev; i++)  
 		{
-			if (slip_ctrls[i]->dev.start)
-			/* VSV = if dev->start==0, then device
-			unregistred while close proc. */ 
+			if (slip_ctrls[i])
 			{
-				unregister_netdev(&(slip_ctrls[i]->dev));
+				/*
+				 * VSV = if dev->start==0, then device
+				 * unregistred while close proc.
+				 */ 
+				if (slip_ctrls[i]->dev.start)
+					unregister_netdev(&(slip_ctrls[i]->dev));
+
 				kfree(slip_ctrls[i]);
+				slip_ctrls[i] = NULL;
 			}
 		}
 		kfree(slip_ctrls);
diff -u --recursive --new-file v1.3.69/linux/drivers/net/smc-ultra.c linux/drivers/net/smc-ultra.c
--- v1.3.69/linux/drivers/net/smc-ultra.c	Wed Dec 13 09:02:46 1995
+++ linux/drivers/net/smc-ultra.c	Fri Mar  1 07:50:46 1996
@@ -233,7 +233,7 @@
 {
 	int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */
 
-	if (request_irq(dev->irq, ei_interrupt, 0, ei_status.name))
+	if (request_irq(dev->irq, ei_interrupt, 0, ei_status.name, NULL))
 		return -EAGAIN;
 
 	outb(ULTRA_MEMENB, ioaddr);	/* Enable memory, 16 bit mode. */
@@ -330,7 +330,7 @@
 		printk("%s: Shutting down ethercard.\n", dev->name);
 
 	outb(0x00, ioaddr + 6);		/* Disable interrupts. */
-	free_irq(dev->irq);
+	free_irq(dev->irq, NULL);
 	irq2dev_map[dev->irq] = 0;
 
 	NS8390_init(dev, 0);
diff -u --recursive --new-file v1.3.69/linux/drivers/net/sunlance.c linux/drivers/net/sunlance.c
--- v1.3.69/linux/drivers/net/sunlance.c	Sat Nov 25 19:04:47 1995
+++ linux/drivers/net/sunlance.c	Fri Mar  1 07:50:49 1996
@@ -459,7 +459,7 @@
 }
 
 static void
-lance_interrupt (int irq, struct pt_regs *regs)
+lance_interrupt (int irq, void *dev_id, struct pt_regs *regs)
 {
     struct device *dev = (struct device *) (irq2dev_map [irq]);
     struct lance_private *lp;
@@ -517,7 +517,7 @@
     ll->rap = LE_CSR0;
     ll->rdp = LE_C0_STOP;
 
-    if (request_irq (dev->irq, &lance_interrupt, 0, "LANCE")){
+    if (request_irq (dev->irq, &lance_interrupt, 0, "LANCE", NULL)){
 	printk ("Lance: Can't get irq %d\n", dev->irq);
 	return -EAGAIN;
     }
@@ -569,7 +569,7 @@
     ll->rap = LE_CSR0;
     ll->rdp = LE_C0_STOP;
 
-    free_irq (dev->irq);
+    free_irq (dev->irq, NULL);
     irq2dev_map [dev->irq] = NULL;
     
     return 0;
diff -u --recursive --new-file v1.3.69/linux/drivers/net/tulip.c linux/drivers/net/tulip.c
--- v1.3.69/linux/drivers/net/tulip.c	Mon Dec 11 15:42:03 1995
+++ linux/drivers/net/tulip.c	Fri Mar  1 07:50:49 1996
@@ -155,7 +155,7 @@
 static void tulip_init_ring(struct device *dev);
 static int tulip_start_xmit(struct sk_buff *skb, struct device *dev);
 static int tulip_rx(struct device *dev);
-static void tulip_interrupt(int irq, struct pt_regs *regs);
+static void tulip_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static int tulip_close(struct device *dev);
 static struct enet_statistics *tulip_get_stats(struct device *dev);
 static void set_multicast_list(struct device *dev);
@@ -283,7 +283,7 @@
 	if (irq2dev_map[dev->irq] != NULL
 		|| (irq2dev_map[dev->irq] = dev) == NULL
 		|| dev->irq == 0
-		|| request_irq(dev->irq, &tulip_interrupt, 0, "DEC 21040 Tulip")) {
+		|| request_irq(dev->irq, &tulip_interrupt, 0, "DEC 21040 Tulip", NULL)) {
 		return -EAGAIN;
 	}
 
@@ -444,7 +444,7 @@
 
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
-static void tulip_interrupt(int irq, struct pt_regs *regs)
+static void tulip_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct device *dev = (struct device *)(irq2dev_map[irq]);
 	struct tulip_private *lp;
@@ -562,7 +562,7 @@
 		if (dev->start == 0  &&  --stopit < 0) {
 			printk("%s: Emergency stop, looping startup interrupt.\n",
 				   dev->name);
-			free_irq(irq);
+			free_irq(irq, NULL);
 		}
 	}
 
@@ -651,7 +651,7 @@
 
 	tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff;
 
-	free_irq(dev->irq);
+	free_irq(dev->irq, NULL);
 	irq2dev_map[dev->irq] = 0;
 
 	MOD_DEC_USE_COUNT;
diff -u --recursive --new-file v1.3.69/linux/drivers/net/wavelan.c linux/drivers/net/wavelan.c
--- v1.3.69/linux/drivers/net/wavelan.c	Sat Nov 25 19:04:47 1995
+++ linux/drivers/net/wavelan.c	Fri Mar  1 07:50:49 1996
@@ -77,7 +77,7 @@
 static int		wavelan_probe1(device *, unsigned short);
 static int		wavelan_open(device *);
 static int		wavelan_send_packet(struct sk_buff *, device *);
-static void		wavelan_interrupt(int, struct pt_regs *);
+static void		wavelan_interrupt(int, void *, struct pt_regs *);
 static int		wavelan_close(device *);
 static en_stats		*wavelan_get_stats(device *);
 static void		wavelan_set_multicast_list(device *);
@@ -1240,7 +1240,7 @@
 		||
 		(irq2dev_map[dev->irq] = dev) == (device *)0
 		||
-		request_irq(dev->irq, &wavelan_interrupt, 0, "WaveLAN") != 0
+		request_irq(dev->irq, &wavelan_interrupt, 0, "WaveLAN", NULL) != 0
 	)
 	{
 		irq2dev_map[dev->irq] = (device *)0;
@@ -1259,7 +1259,7 @@
 
 	if (r == -1)
 	{
-		free_irq(dev->irq);
+		free_irq(dev->irq, NULL);
 		irq2dev_map[dev->irq] = (device *)0;
 		if (wavelan_debug > 0)
 			printk("%s: <-wavelan_open(): -EAGAIN(2)\n", dev->name);
@@ -1856,7 +1856,7 @@
 
 static
 void
-wavelan_interrupt(int irq, struct pt_regs *regs)
+wavelan_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	device		*dev;
 	unsigned short	ioaddr;
@@ -1984,7 +1984,7 @@
 
 	wavelan_ints_off(dev);
 
-	free_irq(dev->irq);
+	free_irq(dev->irq, NULL);
 	irq2dev_map[dev->irq] = (device *)0;
 
 	/*
diff -u --recursive --new-file v1.3.69/linux/drivers/net/wd.c linux/drivers/net/wd.c
--- v1.3.69/linux/drivers/net/wd.c	Wed Dec 13 09:02:46 1995
+++ linux/drivers/net/wd.c	Fri Mar  1 07:50:49 1996
@@ -253,7 +253,7 @@
 
 	/* Snarf the interrupt now.  There's no point in waiting since we cannot
 	   share and the board will usually be enabled. */
-	if (request_irq(dev->irq, ei_interrupt, 0, model_name)) {
+	if (request_irq(dev->irq, ei_interrupt, 0, model_name, NULL)) {
 		printk (" unable to get IRQ %d.\n", dev->irq);
 		return EAGAIN;
 	}
@@ -261,7 +261,7 @@
 	/* Allocate dev->priv and fill in 8390 specific dev fields. */
 	if (ethdev_init(dev)) {	
 		printk (" unable to get memory for dev->priv.\n");
-		free_irq(dev->irq);
+		free_irq(dev->irq, NULL);
 		return -ENOMEM;
 	}
 
@@ -493,7 +493,7 @@
 			int ioaddr = dev->base_addr - WD_NIC_OFFSET;
 			kfree(dev->priv);
 			dev->priv = NULL;
-			free_irq(dev->irq);
+			free_irq(dev->irq, NULL);
 			irq2dev_map[dev->irq] = NULL;
 			release_region(ioaddr, WD_IO_EXTENT);
 			unregister_netdev(dev);
diff -u --recursive --new-file v1.3.69/linux/drivers/net/znet.c linux/drivers/net/znet.c
--- v1.3.69/linux/drivers/net/znet.c	Sun Dec 17 11:43:18 1995
+++ linux/drivers/net/znet.c	Fri Mar  1 07:50:49 1996
@@ -182,7 +182,7 @@
 int znet_probe(struct device *dev);
 static int	znet_open(struct device *dev);
 static int	znet_send_packet(struct sk_buff *skb, struct device *dev);
-static void	znet_interrupt(int irq, struct pt_regs *regs);
+static void	znet_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static void	znet_rx(struct device *dev);
 static int	znet_close(struct device *dev);
 static struct enet_statistics *net_get_stats(struct device *dev);
@@ -246,7 +246,7 @@
 	zn.tx_dma = netinfo->dma2;
 
 	/* These should never fail.  You can't add devices to a sealed box! */
-	if (request_irq(dev->irq, &znet_interrupt, 0, "ZNet")
+	if (request_irq(dev->irq, &znet_interrupt, 0, "ZNet", NULL)
 		|| request_dma(zn.rx_dma,"ZNet rx")
 		|| request_dma(zn.tx_dma,"ZNet tx")) {
 		printk(KERN_WARNING "%s: Not opened -- resource busy?!?\n", dev->name);
@@ -402,7 +402,7 @@
 }
 
 /* The ZNET interrupt handler. */
-static void	znet_interrupt(int irq, struct pt_regs * regs)
+static void	znet_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
 	struct device *dev = irq2dev_map[irq];
 	int ioaddr;
@@ -603,7 +603,7 @@
 	disable_dma(zn.rx_dma);
 	disable_dma(zn.tx_dma);
 
-	free_irq(dev->irq);
+	free_irq(dev->irq, NULL);
 
 	if (znet_debug > 1)
 		printk(KERN_DEBUG "%s: Shutting down ethercard.\n", dev->name);
diff -u --recursive --new-file v1.3.69/linux/drivers/scsi/53c7,8xx.c linux/drivers/scsi/53c7,8xx.c
--- v1.3.69/linux/drivers/scsi/53c7,8xx.c	Sat Feb 17 16:02:52 1996
+++ linux/drivers/scsi/53c7,8xx.c	Fri Mar  1 07:50:50 1996
@@ -277,7 +277,7 @@
 static int NCR53c8xx_run_tests (struct Scsi_Host *host);
 static int NCR53c8xx_script_len;
 static int NCR53c8xx_dsa_len;
-static void NCR53c7x0_intr(int irq, struct pt_regs * regs);
+static void NCR53c7x0_intr(int irq, void *dev_id, struct pt_regs * regs);
 static int ncr_halt (struct Scsi_Host *host);
 static void intr_phase_mismatch (struct Scsi_Host *host, struct NCR53c7x0_cmd 
     *cmd);
@@ -1114,7 +1114,7 @@
 	search->irq == host->irq && search != host); search=search->next);
 
     if (!search) {
-	if (request_irq(host->irq, NCR53c7x0_intr, SA_INTERRUPT, "53c7,8xx")) {
+	if (request_irq(host->irq, NCR53c7x0_intr, SA_INTERRUPT, "53c7,8xx", NULL)) {
 	    printk("scsi%d : IRQ%d not free, detaching\n"
 	           "         You have either a configuration problem, or a\n"
                    "         broken BIOS.  You may wish to manually assign\n"
@@ -4321,7 +4321,7 @@
 }
 
 /*
- * Function : static void NCR53c7x0_intr (int irq, struct pt_regs * regs)
+ * Function : static void NCR53c7x0_intr (int irq, void *dev_id, struct pt_regs * regs)
  *
  * Purpose : handle NCR53c7x0 interrupts for all NCR devices sharing
  *	the same IRQ line.  
@@ -4332,7 +4332,7 @@
  */
 
 static void 
-NCR53c7x0_intr (int irq, struct pt_regs * regs) {
+NCR53c7x0_intr (int irq, void *dev_id, struct pt_regs * regs) {
     NCR53c7x0_local_declare();
     struct Scsi_Host *host;			/* Host we are looking at */
     unsigned char istat; 			/* Values of interrupt regs */
@@ -5457,7 +5457,7 @@
 	    (hostdata->chip / 100 == 8 ? ISTAT_800_INTF : 0))) {
 	printk ("scsi%d : dropped interrupt for command %ld\n", host->host_no,
 	    cmd->pid);
-	NCR53c7x0_intr (host->irq, NULL);
+	NCR53c7x0_intr (host->irq, NULL, NULL);
 	return SCSI_ABORT_BUSY;
     }
 	
@@ -6351,7 +6351,7 @@
 		if (tmp->hostt == the_template && tmp->irq == host->irq)
 		    ++irq_count;
 	    if (irq_count == 1)
-		free_irq(host->irq);
+		free_irq(host->irq, NULL);
 	}
     if (host->dma_channel != DMA_NONE)
 	free_dma(host->dma_channel);
diff -u --recursive --new-file v1.3.69/linux/drivers/scsi/AM53C974.c linux/drivers/scsi/AM53C974.c
--- v1.3.69/linux/drivers/scsi/AM53C974.c	Fri Jan 26 01:37:06 1996
+++ linux/drivers/scsi/AM53C974.c	Fri Mar  1 07:50:50 1996
@@ -131,7 +131,7 @@
 static __inline__ void initialize_SCp(Scsi_Cmnd *cmd);
 static __inline__ void run_main(void);
 static void AM53C974_main (void);
-static void AM53C974_intr(int irq, struct pt_regs *regs);
+static void AM53C974_intr(int irq, void *dev_id, struct pt_regs *regs);
 static void AM53C974_intr_disconnect(struct Scsi_Host *instance); 
 static int AM53C974_sync_neg(struct Scsi_Host *instance, int target, unsigned char *msg);
 static __inline__ void AM53C974_set_async(struct Scsi_Host *instance, int target);
@@ -656,7 +656,7 @@
                  (search->irq != instance->irq) || (search == instance) );
      search = search->next);
 if (!search) {
-   if (request_irq(instance->irq, AM53C974_intr, SA_INTERRUPT, "AM53C974")) {
+   if (request_irq(instance->irq, AM53C974_intr, SA_INTERRUPT, "AM53C974", NULL)) {
       printk("scsi%d: IRQ%d not free, detaching\n", instance->host_no, instance->irq);
       scsi_unregister(instance);
       return -1; } 
@@ -916,16 +916,16 @@
 main_running = 0;
 }
 
-/*********************************************************************
-* Function : AM53C974_intr(int irq, struct pt_regs *regs)            *
-*                                                                    *
-* Purpose : interrupt handler                                        *
-*                                                                    *
-* Inputs : irq - interrupt line, regs - ?                            *
-*                                                                    *
-* Returns : nothing                                                  *
-**********************************************************************/
-static void AM53C974_intr(int irq, struct pt_regs *regs)
+/************************************************************************
+* Function : AM53C974_intr(int irq, void *dev_id, struct pt_regs *regs) *
+*                                                                       *
+* Purpose : interrupt handler                                           *
+*                                                                       *
+* Inputs : irq - interrupt line, regs - ?                               *
+*                                                                       *
+* Returns : nothing                                                     *
+************************************************************************/
+static void AM53C974_intr(int irq, void *dev_id, struct pt_regs *regs)
 {
 AM53C974_local_declare(); 
 struct Scsi_Host         *instance;
diff -u --recursive --new-file v1.3.69/linux/drivers/scsi/BusLogic.c linux/drivers/scsi/BusLogic.c
--- v1.3.69/linux/drivers/scsi/BusLogic.c	Thu Jan  4 21:54:55 1996
+++ linux/drivers/scsi/BusLogic.c	Fri Mar  1 07:50:50 1996
@@ -1162,7 +1162,7 @@
   if (BusLogic_IRQ_UsageCount[HostAdapter->IRQ_Channel - 9]++ == 0)
     {
       if (request_irq(HostAdapter->IRQ_Channel, BusLogic_InterruptHandler,
-		      SA_INTERRUPT, HostAdapter->InterruptLabel) < 0)
+		      SA_INTERRUPT, HostAdapter->InterruptLabel, NULL) < 0)
 	{
 	  BusLogic_IRQ_UsageCount[HostAdapter->IRQ_Channel - 9]--;
 	  printk("scsi%d: UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n",
@@ -1236,7 +1236,7 @@
   */
   if (HostAdapter->IRQ_ChannelAcquired)
     if (--BusLogic_IRQ_UsageCount[HostAdapter->IRQ_Channel - 9] == 0)
-      free_irq(HostAdapter->IRQ_Channel);
+      free_irq(HostAdapter->IRQ_Channel, NULL);
   /*
     Release exclusive access to the DMA Channel.
   */
diff -u --recursive --new-file v1.3.69/linux/drivers/scsi/NCR5380.c linux/drivers/scsi/NCR5380.c
--- v1.3.69/linux/drivers/scsi/NCR5380.c	Wed Feb 14 14:37:12 1996
+++ linux/drivers/scsi/NCR5380.c	Fri Mar  1 07:50:50 1996
@@ -616,7 +616,7 @@
 
 
 static int probe_irq;
-static void probe_intr (int irq, struct pt_regs * regs) {
+static void probe_intr (int irq, void *dev_id, struct pt_regs * regs) {
     probe_irq = irq;
 };
 
@@ -629,7 +629,7 @@
     NCR5380_setup(instance);
 
     for (trying_irqs = i = 0, mask = 1; i < 16; ++i, mask <<= 1) 
-	if ((mask & possible) &&  (request_irq(i, &probe_intr, SA_INTERRUPT, "NCR-probe") 
+	if ((mask & possible) &&  (request_irq(i, &probe_intr, SA_INTERRUPT, "NCR-probe", NULL) 
 	    == 0)) 
 	    trying_irqs |= mask;
 
@@ -660,7 +660,7 @@
 
     for (i = 0, mask = 1; i < 16; ++i, mask <<= 1)
 	if (trying_irqs & mask) 
-	    free_irq(i);
+	    free_irq(i, NULL);
 
     return probe_irq;
 }
@@ -1123,7 +1123,7 @@
  *
  */
 
-static void NCR5380_intr (int irq, struct pt_regs * regs) {
+static void NCR5380_intr (int irq, void *dev_id, struct pt_regs * regs) {
     NCR5380_local_declare(); 
     struct Scsi_Host *instance;
     int done;
diff -u --recursive --new-file v1.3.69/linux/drivers/scsi/NCR5380.h linux/drivers/scsi/NCR5380.h
--- v1.3.69/linux/drivers/scsi/NCR5380.h	Wed Feb  7 15:11:27 1996
+++ linux/drivers/scsi/NCR5380.h	Fri Mar  1 07:50:50 1996
@@ -275,7 +275,7 @@
 #endif
 static void NCR5380_init (struct Scsi_Host *instance, int flags);
 static void NCR5380_information_transfer (struct Scsi_Host *instance);
-static void NCR5380_intr (int irq, struct pt_regs * regs);
+static void NCR5380_intr (int irq, void *dev_id, struct pt_regs * regs);
 static void NCR5380_main (void);
 static void NCR5380_print_options (struct Scsi_Host *instance);
 static void NCR5380_print_phase (struct Scsi_Host *instance);
diff -u --recursive --new-file v1.3.69/linux/drivers/scsi/NCR53c406a.c linux/drivers/scsi/NCR53c406a.c
--- v1.3.69/linux/drivers/scsi/NCR53c406a.c	Wed Feb 14 14:37:12 1996
+++ linux/drivers/scsi/NCR53c406a.c	Fri Mar  1 07:50:51 1996
@@ -169,7 +169,7 @@
 };
 
 /* Static function prototypes */
-static  void NCR53c406a_intr(int, struct pt_regs *);
+static  void NCR53c406a_intr(int, void *, struct pt_regs *);
 static  void internal_done(Scsi_Cmnd *);
 static  void wait_intr(void);
 static  void chip_init(void);
@@ -537,7 +537,7 @@
     request_region(port_base, 0x10, "NCR53c406a");
     
     if(irq_level > 0) {
-        if(request_irq(irq_level, NCR53c406a_intr, 0, "NCR53c406a")){
+        if(request_irq(irq_level, NCR53c406a_intr, 0, "NCR53c406a", NULL)){
             printk("NCR53c406a: unable to allocate IRQ %d\n", irq_level);
             return 0;
         }
@@ -664,7 +664,7 @@
         return;
     }
     
-    NCR53c406a_intr(0, NULL);
+    NCR53c406a_intr(0, NULL, NULL);
 }
 
 int NCR53c406a_command(Scsi_Cmnd *SCpnt){
@@ -763,7 +763,7 @@
   }
      
      static void
-NCR53c406a_intr(int unused, struct pt_regs *regs){
+NCR53c406a_intr(int unused, void *dev_id, struct pt_regs *regs){
     DEB(unsigned char fifo_size;)
     DEB(unsigned char seq_reg;)
     unsigned char status, int_reg;
diff -u --recursive --new-file v1.3.69/linux/drivers/scsi/advansys.c linux/drivers/scsi/advansys.c
--- v1.3.69/linux/drivers/scsi/advansys.c	Wed Feb 28 11:50:06 1996
+++ linux/drivers/scsi/advansys.c	Fri Mar  1 07:50:51 1996
@@ -2551,7 +2551,7 @@
 #ifdef LINUX_1_3
 STATIC int			asc_proc_copy(off_t, off_t, char *, int , char *, int);
 #endif /* LINUX_1_3 */
-STATIC void 		advansys_interrupt(int, struct pt_regs *);
+STATIC void 		advansys_interrupt(int, void *, struct pt_regs *);
 STATIC void 		advansys_command_done(Scsi_Cmnd *);
 STATIC int 			asc_execute_scsi_cmnd(Scsi_Cmnd *);
 STATIC void 		asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
@@ -3107,7 +3107,7 @@
 			/* Register IRQ Number. */
 			ASC_DBG1(2, "advansys_detect: request_irq() %d\n", shp->irq);
 			if ((ret = request_irq(shp->irq, advansys_interrupt,
-								SA_INTERRUPT, "advansys")) != 0) {
+								SA_INTERRUPT, "advansys", NULL)) != 0) {
 				ASC_DBG1(0, "advansys_detect: request_irq() failed %d\n", ret);
 				release_region(shp->io_port, shp->n_io_port);
 				if (shp->dma_channel != NO_ISA_DMA) {
@@ -3130,7 +3130,7 @@
 				if (shp->dma_channel != NO_ISA_DMA) {
 					free_dma(shp->dma_channel);
 				}
-				free_irq(shp->irq);
+				free_irq(shp->irq, NULL);
 				scsi_unregister(shp);
 				asc_board_count--;
 				continue;
@@ -3152,7 +3152,7 @@
 advansys_release(struct Scsi_Host *shp)
 {
 	ASC_DBG(1, "advansys_release: begin\n");
-	free_irq(shp->irq);
+	free_irq(shp->irq, NULL);
 	if (shp->dma_channel != NO_ISA_DMA) {
 		ASC_DBG(1, "advansys_release: free_dma()\n");
 		free_dma(shp->dma_channel);
@@ -3577,7 +3577,7 @@
  * First-level interrupt handler.
  */
 STATIC void
-advansys_interrupt(int irq, struct pt_regs *regs)
+advansys_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	int			i;
 	int			flags;
diff -u --recursive --new-file v1.3.69/linux/drivers/scsi/aha152x.c linux/drivers/scsi/aha152x.c
--- v1.3.69/linux/drivers/scsi/aha152x.c	Tue Feb 20 14:37:24 1996
+++ linux/drivers/scsi/aha152x.c	Fri Mar  1 07:50:51 1996
@@ -381,7 +381,7 @@
 #endif
 };
 
-void aha152x_intr(int irq, struct pt_regs *);
+void aha152x_intr(int irq, void *dev_id, struct pt_regs *);
 void aha152x_done(struct Scsi_Host *shpnt, int error);
 void aha152x_setup(char *str, int *ints);
 int aha152x_checksetup(struct aha152x_setup *setup);
@@ -835,7 +835,7 @@
 
       SETBITS(DMACNTRL0, INTEN);
 
-      ok = request_irq(setup[i].irq, aha152x_intr, SA_INTERRUPT, "aha152x");
+      ok = request_irq(setup[i].irq, aha152x_intr, SA_INTERRUPT, "aha152x", NULL);
       
       if(ok<0)
         {
@@ -1307,7 +1307,7 @@
 /*
  * Interrupts handler (main routine of the driver)
  */
-void aha152x_intr(int irqno, struct pt_regs * regs)
+void aha152x_intr(int irqno, void *dev_id, struct pt_regs * regs)
 {
   struct Scsi_Host *shpnt = aha152x_host[irqno-IRQ_MIN];
   unsigned int flags;
diff -u --recursive --new-file v1.3.69/linux/drivers/scsi/aha1542.c linux/drivers/scsi/aha1542.c
--- v1.3.69/linux/drivers/scsi/aha1542.c	Tue Jan 23 21:15:43 1996
+++ linux/drivers/scsi/aha1542.c	Fri Mar  1 07:50:51 1996
@@ -353,7 +353,7 @@
 }
 
 /* A "high" level interrupt handler */
-static void aha1542_intr_handle(int irq, struct pt_regs *regs)
+static void aha1542_intr_handle(int irq, void *dev_id, struct pt_regs *regs)
 {
     void (*my_done)(Scsi_Cmnd *) = NULL;
     int errstatus, mbi, mbo, mbistatus;
@@ -1000,7 +1000,7 @@
 		    DEB(printk("aha1542_detect: enable interrupt channel %d\n", irq_level));
 		    save_flags(flags);
 		    cli();
-		    if (request_irq(irq_level,aha1542_intr_handle, 0, "aha1542")) {
+		    if (request_irq(irq_level,aha1542_intr_handle, 0, "aha1542", NULL)) {
 			    printk("Unable to allocate IRQ for adaptec controller.\n");
 			    goto unregister;
 		    }
@@ -1008,7 +1008,7 @@
 		    if (dma_chan != 0xFF) {
 			    if (request_dma(dma_chan,"aha1542")) {
 				    printk("Unable to allocate DMA channel for Adaptec.\n");
-				    free_irq(irq_level);
+				    free_irq(irq_level, NULL);
 				    goto unregister;
 			    }
 			    
diff -u --recursive --new-file v1.3.69/linux/drivers/scsi/aha1740.c linux/drivers/scsi/aha1740.c
--- v1.3.69/linux/drivers/scsi/aha1740.c	Tue Jan  2 16:46:27 1996
+++ linux/drivers/scsi/aha1740.c	Fri Mar  1 07:50:52 1996
@@ -174,7 +174,7 @@
 }
 
 /* A "high" level interrupt handler */
-void aha1740_intr_handle(int irq, struct pt_regs * regs)
+void aha1740_intr_handle(int irq, void *dev_id, struct pt_regs * regs)
 {
     void (*my_done)(Scsi_Cmnd *);
     int errstatus, adapstat;
@@ -472,7 +472,7 @@
 
     DEB(printk("aha1740_detect: enable interrupt channel %d\n", irq_level));
 
-    if (request_irq(irq_level,aha1740_intr_handle, 0, "aha1740"))
+    if (request_irq(irq_level,aha1740_intr_handle, 0, "aha1740", NULL))
     {
 	printk("Unable to allocate IRQ for adaptec controller.\n");
 	return 0;
diff -u --recursive --new-file v1.3.69/linux/drivers/scsi/aic7xxx.c linux/drivers/scsi/aic7xxx.c
--- v1.3.69/linux/drivers/scsi/aic7xxx.c	Fri Feb 16 11:34:08 1996
+++ linux/drivers/scsi/aic7xxx.c	Fri Mar  1 07:50:52 1996
@@ -1680,7 +1680,7 @@
  *         be disabled all through this function unless we say otherwise.
  *-F*************************************************************************/
 static void
-aic7xxx_isr(int irq, struct pt_regs * regs)
+aic7xxx_isr(int irq, void *dev_id, struct pt_regs * regs)
 {
   int base, intstat;
   struct aic7xxx_host *p;
@@ -3462,7 +3462,7 @@
     /*
      * Register IRQ with the kernel.
      */
-    if (request_irq(config->irq, aic7xxx_isr, SA_INTERRUPT, "aic7xxx"))
+    if (request_irq(config->irq, aic7xxx_isr, SA_INTERRUPT, "aic7xxx", NULL))
     {
       printk("aic7xxx: Couldn't register IRQ %d, ignoring.\n", config->irq);
       aic7xxx_boards[config->irq] = NULL;
diff -u --recursive --new-file v1.3.69/linux/drivers/scsi/eata.c linux/drivers/scsi/eata.c
--- v1.3.69/linux/drivers/scsi/eata.c	Mon Oct 23 18:02:10 1995
+++ linux/drivers/scsi/eata.c	Fri Mar  1 07:50:52 1996
@@ -322,7 +322,7 @@
 #define HD(board) ((struct hostdata *) &sh[board]->hostdata)
 #define BN(board) (HD(board)->board_name)
 
-static void eata2x_interrupt_handler(int, struct pt_regs *);
+static void eata2x_interrupt_handler(int, void *, struct pt_regs *);
 static int do_trace = FALSE;
 
 static inline unchar wait_on_busy(ushort iobase) {
@@ -448,7 +448,7 @@
 
    /* Board detected, allocate its IRQ if not already done */
    if ((irq >= MAX_IRQ) || ((irqlist[irq] == NO_IRQ) && request_irq
-       (irq, eata2x_interrupt_handler, SA_INTERRUPT, driver_name))) {
+       (irq, eata2x_interrupt_handler, SA_INTERRUPT, driver_name, NULL))) {
       printk("%s: unable to allocate IRQ %u, detaching.\n", name, irq);
       return FALSE;
       }
@@ -456,7 +456,7 @@
    if (subversion == ISA && request_dma(dma_channel, driver_name)) {
       printk("%s: unable to allocate DMA channel %u, detaching.\n",
 	     name, dma_channel);
-      free_irq(irq);
+      free_irq(irq, NULL);
       return FALSE;
       }
 
@@ -481,7 +481,7 @@
    if (sh[j] == NULL) {
       printk("%s: unable to register host, detaching.\n", name);
 
-      if (irqlist[irq] == NO_IRQ) free_irq(irq);
+      if (irqlist[irq] == NO_IRQ) free_irq(irq, NULL);
 
       if (subversion == ISA) free_dma(dma_channel);
 
@@ -884,7 +884,7 @@
       }
 }
 
-static void eata2x_interrupt_handler(int irq, struct pt_regs * regs) {
+static void eata2x_interrupt_handler(int irq, void *dev_id, struct pt_regs * regs) {
    Scsi_Cmnd *SCpnt;
    unsigned int i, j, k, flags, status, tstatus, loops, total_loops = 0;
    struct mssp *spp;
diff -u --recursive --new-file v1.3.69/linux/drivers/scsi/eata_dma.c linux/drivers/scsi/eata_dma.c
--- v1.3.69/linux/drivers/scsi/eata_dma.c	Mon Dec 11 15:42:03 1995
+++ linux/drivers/scsi/eata_dma.c	Fri Mar  1 07:50:52 1996
@@ -114,7 +114,7 @@
     return;
 }   
 
-void eata_fake_int_handler(s32 irq, struct pt_regs * regs)
+void eata_fake_int_handler(s32 irq, void *dev_id, struct pt_regs * regs)
 {
     fake_int_result = inb((ulong)fake_int_base + HA_RSTATUS);
     fake_int_happened = TRUE;
@@ -129,7 +129,7 @@
 int eata_release(struct Scsi_Host *sh)
 {
     uint i;
-    if (sh->irq && reg_IRQ[sh->irq] == 1) free_irq(sh->irq);
+    if (sh->irq && reg_IRQ[sh->irq] == 1) free_irq(sh->irq, NULL);
     else reg_IRQ[sh->irq]--;
     
     scsi_init_free((void *)status, 512);
@@ -150,7 +150,7 @@
 #endif
 
 
-void eata_int_handler(int irq, struct pt_regs * regs)
+void eata_int_handler(int irq, void *dev_id, struct pt_regs * regs)
 {
     uint i, result = 0;
     uint hba_stat, scsi_stat, eata_stat;
@@ -867,7 +867,7 @@
     
     if (reg_IRQ[gc->IRQ] == FALSE) {	/* Interrupt already registered ? */
 	if (!request_irq(gc->IRQ, (void *) eata_fake_int_handler, SA_INTERRUPT,
-			 "eata_dma")){
+			 "eata_dma", NULL)){
 	    reg_IRQ[gc->IRQ]++;
 	    if (!gc->IRQ_TR)
 		reg_IRQL[gc->IRQ] = TRUE;   /* IRQ is edge triggered */
@@ -892,7 +892,7 @@
 		   dma_channel, base);
 	    reg_IRQ[gc->IRQ]--;
 	    if (reg_IRQ[gc->IRQ] == 0)
-		free_irq(gc->IRQ);
+		free_irq(gc->IRQ, NULL);
 	    if (gc->IRQ_TR == FALSE)
 		reg_IRQL[gc->IRQ] = FALSE; 
 	    return (FALSE);
@@ -919,7 +919,7 @@
 		free_dma(dma_channel);
 	    reg_IRQ[gc->IRQ]--;
 	    if (reg_IRQ[gc->IRQ] == 0)
-		free_irq(gc->IRQ);
+		free_irq(gc->IRQ, NULL);
 	    if (gc->IRQ_TR == FALSE)
 		reg_IRQL[gc->IRQ] = FALSE; 
 	    return (FALSE);
@@ -956,7 +956,7 @@
 	
 	reg_IRQ[gc->IRQ]--;
 	if (reg_IRQ[gc->IRQ] == 0)
-	    free_irq(gc->IRQ);
+	    free_irq(gc->IRQ, NULL);
 	if (gc->IRQ_TR == FALSE)
 	    reg_IRQL[gc->IRQ] = FALSE; 
 	return (FALSE);
@@ -1306,8 +1306,8 @@
     
     for (i = 0; i <= MAXIRQ; i++) { /* Now that we know what we have, we     */
 	if (reg_IRQ[i]){            /* exchange the interrupt handler which  */
-	    free_irq(i);            /* we used for probing with the real one */
-	    request_irq(i, (void *)(eata_int_handler), SA_INTERRUPT, "eata_dma");
+	    free_irq(i, NULL);      /* we used for probing with the real one */
+	    request_irq(i, (void *)(eata_int_handler), SA_INTERRUPT, "eata_dma", NULL);
 	}
     }
     HBA_ptr = first_HBA;
diff -u --recursive --new-file v1.3.69/linux/drivers/scsi/eata_pio.c linux/drivers/scsi/eata_pio.c
--- v1.3.69/linux/drivers/scsi/eata_pio.c	Wed Nov  8 07:11:34 1995
+++ linux/drivers/scsi/eata_pio.c	Fri Mar  1 07:50:52 1996
@@ -99,7 +99,7 @@
 #ifdef MODULE
 int eata_pio_release(struct Scsi_Host *sh)
 {
-    if (sh->irq && reg_IRQ[sh->irq] == 1) free_irq(sh->irq);
+    if (sh->irq && reg_IRQ[sh->irq] == 1) free_irq(sh->irq, NULL);
     else reg_IRQ[sh->irq]--;
     if (SD(sh)->channel == 0) {
 	if (sh->io_port && sh->n_io_port)
@@ -124,7 +124,7 @@
     }
 }
 
-void eata_pio_int_handler(int irq, struct pt_regs * regs)
+void eata_pio_int_handler(int irq, void *dev_id, struct pt_regs * regs)
 {
     uint eata_stat = 0xfffff;
     Scsi_Cmnd *cmd;
@@ -707,7 +707,7 @@
     
     if (!reg_IRQ[gc->IRQ]) {    /* Interrupt already registered ? */
 	if (!request_irq(gc->IRQ, eata_pio_int_handler, SA_INTERRUPT, 
-			 "EATA-PIO")){
+			 "EATA-PIO", NULL)){
 	    reg_IRQ[gc->IRQ]++;
 	    if (!gc->IRQ_TR)
 		reg_IRQL[gc->IRQ] = TRUE;   /* IRQ is edge triggered */
@@ -989,7 +989,7 @@
     
     for (i = 0; i <= MAXIRQ; i++)
 	if (reg_IRQ[i])
-	    request_irq(i, eata_pio_int_handler, SA_INTERRUPT, "EATA-PIO");
+	    request_irq(i, eata_pio_int_handler, SA_INTERRUPT, "EATA-PIO", NULL);
     
     HBA_ptr = first_HBA;
   
diff -u --recursive --new-file v1.3.69/linux/drivers/scsi/fdomain.c linux/drivers/scsi/fdomain.c
--- v1.3.69/linux/drivers/scsi/fdomain.c	Wed Nov  8 07:11:34 1995
+++ linux/drivers/scsi/fdomain.c	Fri Mar  1 07:50:52 1996
@@ -339,7 +339,7 @@
 static int               FIFO_Size = 0x2000; /* 8k FIFO for
 						pre-tmc18c30 chips */
 
-extern void              fdomain_16x0_intr( int irq, struct pt_regs * regs );
+extern void              fdomain_16x0_intr( int irq, void *dev_id, struct pt_regs * regs );
 
 static void *addresses[] = {
    (void *)0xc8000,
@@ -981,7 +981,7 @@
       /* Register the IRQ with the kernel */
 
       retcode = request_irq( interrupt_level,
-			     fdomain_16x0_intr, SA_INTERRUPT, "fdomain" );
+			     fdomain_16x0_intr, SA_INTERRUPT, "fdomain", NULL);
 
       if (retcode < 0) {
 	 if (retcode == -EINVAL) {
@@ -1211,7 +1211,7 @@
 #endif
 }
 
-void fdomain_16x0_intr( int irq, struct pt_regs * regs )
+void fdomain_16x0_intr( int irq, void *dev_id, struct pt_regs * regs )
 {
    int      status;
    int      done = 0;
diff -u --recursive --new-file v1.3.69/linux/drivers/scsi/g_NCR5380.c linux/drivers/scsi/g_NCR5380.c
--- v1.3.69/linux/drivers/scsi/g_NCR5380.c	Wed Feb  7 15:11:28 1996
+++ linux/drivers/scsi/g_NCR5380.c	Fri Mar  1 07:50:52 1996
@@ -211,7 +211,7 @@
 	    instance->irq = NCR5380_probe_irq(instance, 0xffff);
 
 	if (instance->irq != IRQ_NONE) 
-	    if (request_irq(instance->irq, generic_NCR5380_intr, SA_INTERRUPT, "NCR5380")) {
+	    if (request_irq(instance->irq, generic_NCR5380_intr, SA_INTERRUPT, "NCR5380", NULL)) {
 		printk("scsi%d : IRQ%d not free, interrupts disabled\n", 
 		    instance->host_no, instance->irq);
 		instance->irq = IRQ_NONE;
@@ -249,7 +249,7 @@
 
     NCR5380_setup(instance);
 
-    free_irq(instance->irq);
+    free_irq(instance->irq, NULL);
 
 	return 0;
 }
diff -u --recursive --new-file v1.3.69/linux/drivers/scsi/in2000.c linux/drivers/scsi/in2000.c
--- v1.3.69/linux/drivers/scsi/in2000.c	Mon Oct 23 18:02:11 1995
+++ linux/drivers/scsi/in2000.c	Fri Mar  1 07:50:52 1996
@@ -278,7 +278,7 @@
 	ficmsk = 0;}
 }
 
-static void in2000_intr_handle(int irq, struct pt_regs *regs)
+static void in2000_intr_handle(int irq, void *dev_id, struct pt_regs *regs)
 {
     int result=0;
     unsigned int count,auxstatus,scsistatus,cmdphase,scsibyte;
@@ -632,7 +632,7 @@
 		"\n",base, irq_level);
 
     outb(2,ININTR);	/* Shut off the FIFO first, so it won't ask for data.*/
-    if (request_irq(irq_level,in2000_intr_handle, 0, "in2000"))
+    if (request_irq(irq_level,in2000_intr_handle, 0, "in2000", NULL))
     {
 	printk("in2000_detect: Unable to allocate IRQ.\n");
 	return 0;
diff -u --recursive --new-file v1.3.69/linux/drivers/scsi/pas16.c linux/drivers/scsi/pas16.c
--- v1.3.69/linux/drivers/scsi/pas16.c	Sun Dec 17 11:43:20 1995
+++ linux/drivers/scsi/pas16.c	Fri Mar  1 07:50:53 1996
@@ -401,7 +401,7 @@
 	    instance->irq = NCR5380_probe_irq(instance, PAS16_IRQS);
 
 	if (instance->irq != IRQ_NONE) 
-	    if (request_irq(instance->irq, pas16_intr, SA_INTERRUPT, "pas16")) {
+	    if (request_irq(instance->irq, pas16_intr, SA_INTERRUPT, "pas16", NULL)) {
 		printk("scsi%d : IRQ%d not free, interrupts disabled\n", 
 		    instance->host_no, instance->irq);
 		instance->irq = IRQ_NONE;
diff -u --recursive --new-file v1.3.69/linux/drivers/scsi/qlogic.c linux/drivers/scsi/qlogic.c
--- v1.3.69/linux/drivers/scsi/qlogic.c	Wed Nov  8 07:11:34 1995
+++ linux/drivers/scsi/qlogic.c	Fri Mar  1 07:50:53 1996
@@ -446,7 +446,7 @@
 #if QL_USE_IRQ
 /*----------------------------------------------------------------*/
 /* interrupt handler */
-static void		    ql_ihandl(int irq, struct pt_regs * regs)
+static void	       ql_ihandl(int irq, void *dev_id, struct pt_regs * regs)
 {
 Scsi_Cmnd	   *icmd;
 	REG0;
@@ -609,7 +609,7 @@
 	else
 		printk( "Ql: Using preset IRQ %d\n", qlirq );
 
-	if (qlirq >= 0 && !request_irq(qlirq, ql_ihandl, 0, "qlogic"))
+	if (qlirq >= 0 && !request_irq(qlirq, ql_ihandl, 0, "qlogic", NULL))
 		host->can_queue = 1;
 #endif
 	request_region( qbase , 0x10 ,"qlogic");
diff -u --recursive --new-file v1.3.69/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
--- v1.3.69/linux/drivers/scsi/scsi.c	Fri Feb 23 13:54:36 1996
+++ linux/drivers/scsi/scsi.c	Fri Mar  1 07:50:53 1996
@@ -267,8 +267,8 @@
 {"TEXEL","CD-ROM","1.06", BLIST_BORKEN},
 {"INSITE","Floptical   F*8I","*", BLIST_KEY},
 {"INSITE","I325VM","*", BLIST_KEY},
-{"PIONEER","CD-ROMDRM-602X","*", BLIST_FORCELUN | BLIST_SINGLELUN},
-{"PIONEER","CD-ROMDRM-604X","*", BLIST_FORCELUN | BLIST_SINGLELUN},
+{"PIONEER","CD-ROM DRM-602X","*", BLIST_FORCELUN | BLIST_SINGLELUN},
+{"PIONEER","CD-ROM DRM-604X","*", BLIST_FORCELUN | BLIST_SINGLELUN},
 /*
  * Must be at end of list...
  */
@@ -2288,8 +2288,12 @@
     struct Scsi_Host * host = NULL;
     
     for(j=0;j<SDpnt->host->cmd_per_lun;j++){
-	SCpnt = (Scsi_Cmnd *) scsi_init_malloc(sizeof(Scsi_Cmnd), GFP_ATOMIC);
-	SCpnt->host = SDpnt->host;
+	host = SDpnt->host;
+	SCpnt = (Scsi_Cmnd *)
+		scsi_init_malloc(sizeof(Scsi_Cmnd),
+				 GFP_ATOMIC |
+				 (host->unchecked_isa_dma ? GFP_DMA : 0));
+	SCpnt->host = host;
 	SCpnt->device = SDpnt;
 	SCpnt->target = SDpnt->id;
 	SCpnt->lun = SDpnt->lun;
@@ -2302,7 +2306,6 @@
 	SCpnt->underflow = 0;
 	SCpnt->transfersize = 0;
 	SCpnt->host_scribble = NULL;
-	host = SDpnt->host;
 	if(host->host_queue)
 	    host->host_queue->prev = SCpnt;
 	SCpnt->next = host->host_queue;
@@ -2859,7 +2862,7 @@
 		     * It should do the right thing for most correctly 
 		     * written host adapters. 
 		     */
-		    if (shpnt->irq) free_irq(shpnt->irq);
+		    if (shpnt->irq) free_irq(shpnt->irq, NULL);
 		    if (shpnt->dma_channel != 0xff) free_dma(shpnt->dma_channel);
 		    if (shpnt->io_port && shpnt->n_io_port)
 			release_region(shpnt->io_port, shpnt->n_io_port);
diff -u --recursive --new-file v1.3.69/linux/drivers/scsi/sd_ioctl.c linux/drivers/scsi/sd_ioctl.c
--- v1.3.69/linux/drivers/scsi/sd_ioctl.c	Sat Nov 11 17:41:33 1995
+++ linux/drivers/scsi/sd_ioctl.c	Wed Feb 28 15:48:17 1996
@@ -54,12 +54,24 @@
 	put_user(sd[MINOR(inode->i_rdev)].nr_sects,
 		 (long *) arg);
 	return 0;
+
     case BLKRASET:
-	if(!suser())  return -EACCES;
+	if (!suser())
+		return -EACCES;
 	if(!(inode->i_rdev)) return -EINVAL;
 	if(arg > 0xff) return -EINVAL;
 	read_ahead[MAJOR(inode->i_rdev)] = arg;
 	return 0;
+
+    case BLKRAGET:
+	if (!arg)
+		return -EINVAL;
+	error = verify_area(VERIFY_WRITE, (int *) arg, sizeof(int));
+	if (error)
+	    return error;
+	put_user(read_ahead[MAJOR(inode->i_rdev)], (int *) arg);
+	return 0;
+
     case BLKFLSBUF:
 	if(!suser())  return -EACCES;
 	if(!(inode->i_rdev)) return -EINVAL;
diff -u --recursive --new-file v1.3.69/linux/drivers/scsi/seagate.c linux/drivers/scsi/seagate.c
--- v1.3.69/linux/drivers/scsi/seagate.c	Tue Jan  2 16:46:27 1996
+++ linux/drivers/scsi/seagate.c	Fri Mar  1 07:50:54 1996
@@ -203,7 +203,7 @@
  */
 
 static int hostno = -1;
-static void seagate_reconnect_intr(int, struct pt_regs *);
+static void seagate_reconnect_intr(int, void *, struct pt_regs *);
 
 #ifdef FAST
 static int fast = 1;
@@ -358,7 +358,7 @@
 		instance = scsi_register(tpnt, 0);
 		hostno = instance->host_no;
 		if (request_irq((int) irq, seagate_reconnect_intr, SA_INTERRUPT,
-		   (controller_type == SEAGATE) ? "seagate" : "tmc-8xx")) {
+		   (controller_type == SEAGATE) ? "seagate" : "tmc-8xx", NULL)) {
 			printk("scsi%d : unable to allocate IRQ%d\n",
 				hostno, (int) irq);
 			return 0;
@@ -493,7 +493,7 @@
  * asserting SEL.
  */
 
-static void seagate_reconnect_intr(int irq, struct pt_regs * regs)
+static void seagate_reconnect_intr(int irq, void *dev_id, struct pt_regs *regs)
 	{
 	int temp;
 	Scsi_Cmnd * SCtmp;
diff -u --recursive --new-file v1.3.69/linux/drivers/scsi/t128.c linux/drivers/scsi/t128.c
--- v1.3.69/linux/drivers/scsi/t128.c	Fri Feb  9 17:53:04 1996
+++ linux/drivers/scsi/t128.c	Fri Mar  1 07:50:54 1996
@@ -245,7 +245,7 @@
 	    instance->irq = NCR5380_probe_irq(instance, T128_IRQS);
 
 	if (instance->irq != IRQ_NONE) 
-	    if (request_irq(instance->irq, t128_intr, SA_INTERRUPT, "t128")) {
+	    if (request_irq(instance->irq, t128_intr, SA_INTERRUPT, "t128", NULL)) {
 		printk("scsi%d : IRQ%d not free, interrupts disabled\n", 
 		    instance->host_no, instance->irq);
 		instance->irq = IRQ_NONE;
diff -u --recursive --new-file v1.3.69/linux/drivers/scsi/u14-34f.c linux/drivers/scsi/u14-34f.c
--- v1.3.69/linux/drivers/scsi/u14-34f.c	Mon Oct 23 18:02:12 1995
+++ linux/drivers/scsi/u14-34f.c	Fri Mar  1 07:50:54 1996
@@ -287,7 +287,7 @@
 #define HD(board) ((struct hostdata *) &sh[board]->hostdata)
 #define BN(board) (HD(board)->board_name)
 
-static void u14_34f_interrupt_handler(int, struct pt_regs *);
+static void u14_34f_interrupt_handler(int, void *, struct pt_regs *);
 static int do_trace = FALSE;
 
 static inline unchar wait_on_busy(ushort iobase) {
@@ -407,7 +407,7 @@
 
    /* Board detected, allocate its IRQ if not already done */
    if ((irq >= MAX_IRQ) || ((irqlist[irq] == NO_IRQ) && request_irq
-       (irq, u14_34f_interrupt_handler, SA_INTERRUPT, driver_name))) {
+       (irq, u14_34f_interrupt_handler, SA_INTERRUPT, driver_name, NULL))) {
       printk("%s: unable to allocate IRQ %u, detaching.\n", name, irq);
       return FALSE;
       }
@@ -415,7 +415,7 @@
    if (subversion == ISA && request_dma(dma_channel, driver_name)) {
       printk("%s: unable to allocate DMA channel %u, detaching.\n",
 	     name, dma_channel);
-      free_irq(irq);
+      free_irq(irq, NULL);
       return FALSE;
       }
 
@@ -424,7 +424,7 @@
    if (sh[j] == NULL) {
       printk("%s: unable to register host, detaching.\n", name);
 
-      if (irqlist[irq] == NO_IRQ) free_irq(irq);
+      if (irqlist[irq] == NO_IRQ) free_irq(irq, NULL);
 
       if (subversion == ISA) free_dma(dma_channel);
 
@@ -838,7 +838,7 @@
    return 0;
 }
 
-static void u14_34f_interrupt_handler(int irq, struct pt_regs * regs) {
+static void u14_34f_interrupt_handler(int irq, void *dev_id, struct pt_regs * regs) {
    Scsi_Cmnd *SCpnt;
    unsigned int i, j, k, flags, status, tstatus, loops, total_loops = 0;
    struct mscp *spp;
diff -u --recursive --new-file v1.3.69/linux/drivers/scsi/ultrastor.c linux/drivers/scsi/ultrastor.c
--- v1.3.69/linux/drivers/scsi/ultrastor.c	Thu Jan  4 21:54:56 1996
+++ linux/drivers/scsi/ultrastor.c	Fri Mar  1 07:50:54 1996
@@ -293,7 +293,7 @@
 };
 #endif
 
-static void ultrastor_interrupt(int, struct pt_regs *);
+static void ultrastor_interrupt(int, void *, struct pt_regs *);
 static inline void build_sg_list(struct mscp *, Scsi_Cmnd *SCpnt);
 
 
@@ -507,7 +507,7 @@
     config.mscp_free = ~0;
 #endif
 
-    if (request_irq(config.interrupt, ultrastor_interrupt, 0, "Ultrastor")) {
+    if (request_irq(config.interrupt, ultrastor_interrupt, 0, "Ultrastor", NULL)) {
 	printk("Unable to allocate IRQ%u for UltraStor controller.\n",
 	       config.interrupt);
 	return FALSE;
@@ -515,7 +515,7 @@
     if (config.dma_channel && request_dma(config.dma_channel,"Ultrastor")) {
 	printk("Unable to allocate DMA channel %u for UltraStor controller.\n",
 	       config.dma_channel);
-	free_irq(config.interrupt);
+	free_irq(config.interrupt, NULL);
 	return FALSE;
     }
     tpnt->sg_tablesize = ULTRASTOR_14F_MAX_SG;
@@ -577,7 +577,7 @@
 	  printk("U24F: invalid IRQ\n");
 	  return FALSE;
 	}
-      if (request_irq(config.interrupt, ultrastor_interrupt, 0, "Ultrastor"))
+      if (request_irq(config.interrupt, ultrastor_interrupt, 0, "Ultrastor", NULL))
 	{
 	  printk("Unable to allocate IRQ%u for UltraStor controller.\n",
 		 config.interrupt);
@@ -1025,7 +1025,7 @@
     return 0;
 }
 
-static void ultrastor_interrupt(int irq, struct pt_regs *regs)
+static void ultrastor_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
     unsigned int status;
 #if ULTRASTOR_MAX_CMDS > 1
diff -u --recursive --new-file v1.3.69/linux/drivers/scsi/wd7000.c linux/drivers/scsi/wd7000.c
--- v1.3.69/linux/drivers/scsi/wd7000.c	Mon Oct 23 18:02:13 1995
+++ linux/drivers/scsi/wd7000.c	Fri Mar  1 07:50:54 1996
@@ -808,7 +808,7 @@
 
 #define wd7000_intr_ack(host)  outb(0,host->iobase+ASC_INTR_ACK)
 
-void wd7000_intr_handle(int irq, struct pt_regs * regs)
+void wd7000_intr_handle(int irq, void *dev_id, struct pt_regs * regs)
 {
     register int flag, icmb, errstatus, icmb_status;
     register int host_error, scsi_error;
@@ -1048,13 +1048,13 @@
     }
     WAIT(host->iobase+ASC_STAT, ASC_STATMASK, ASC_INIT, 0);
 
-    if (request_irq(host->irq, wd7000_intr_handle, SA_INTERRUPT, "wd7000")) {
+    if (request_irq(host->irq, wd7000_intr_handle, SA_INTERRUPT, "wd7000", NULL)) {
 	printk("wd7000_init: can't get IRQ %d.\n", host->irq);
 	return 0;
     }
     if (request_dma(host->dma,"wd7000"))  {
 	printk("wd7000_init: can't get DMA channel %d.\n", host->dma);
-	free_irq(host->irq);
+	free_irq(host->irq, NULL);
 	return 0;
     }
     wd7000_enable_dma(host);
@@ -1062,7 +1062,7 @@
 
     if (!wd7000_diagnostics(host,ICB_DIAG_FULL))  {
 	free_dma(host->dma);
-	free_irq(host->irq);
+	free_irq(host->irq, NULL);
 	return 0;
     }
 
@@ -1197,7 +1197,7 @@
 
     if (inb(host->iobase+ASC_STAT) & INT_IM)  {
 	printk("wd7000_abort: lost interrupt\n");
-	wd7000_intr_handle(host->irq, NULL);
+	wd7000_intr_handle(host->irq, NULL, NULL);
 	return SCSI_ABORT_SUCCESS;
     }
 
diff -u --recursive --new-file v1.3.69/linux/drivers/sound/ad1848.c linux/drivers/sound/ad1848.c
--- v1.3.69/linux/drivers/sound/ad1848.c	Wed Feb 28 11:50:06 1996
+++ linux/drivers/sound/ad1848.c	Fri Mar  1 07:50:55 1996
@@ -39,9 +39,6 @@
  */
 #include <linux/config.h>
 
-
-#define DEB(x)
-#define DEB1(x)
 #include "sound_config.h"
 
 #if defined(CONFIG_AD1848)
@@ -600,7 +597,7 @@
   unsigned long   flags;
   ad1848_info    *devc = (ad1848_info *) audio_devs[dev]->devc;
 
-  DEB (printk ("ad1848_close(void)\n"));
+  DDB (printk ("ad1848_close(void)\n"));
 
   save_flags (flags);
   cli ();
@@ -1528,11 +1525,13 @@
       if (!share_dma)
 	{
 	  if (sound_alloc_dma (dma_playback, "Sound System"))
-	    printk ("ad1848.c: Can't allocate DMA%d\n", dma_playback);
+	    printk ("ad1848.c: Can't allocate DMA%d for playback\n",
+		    dma_playback);
 
-	  if (dma_capture != dma_playback)
+	  if (dma_capture != dma_playback && dma_capture != -1)
 	    if (sound_alloc_dma (dma_capture, "Sound System (capture)"))
-	      printk ("ad1848.c: Can't allocate DMA%d\n", dma_capture);
+	      printk ("ad1848.c: Can't allocate DMA%d for capture\n",
+		      dma_capture);
 	}
 
       /*
@@ -1588,7 +1587,7 @@
 }
 
 void
-ad1848_interrupt (int irq, struct pt_regs *dummy)
+ad1848_interrupt (int irq, void *dev_id, struct pt_regs *dummy)
 {
   unsigned char   status;
   ad1848_info    *devc;
diff -u --recursive --new-file v1.3.69/linux/drivers/sound/dev_table.h linux/drivers/sound/dev_table.h
--- v1.3.69/linux/drivers/sound/dev_table.h	Wed Feb 28 11:50:07 1996
+++ linux/drivers/sound/dev_table.h	Thu Feb 29 08:35:24 1996
@@ -411,9 +411,10 @@
 #endif
 
 #ifdef CONFIG_MSS
-#	ifndef PSEUDO_MSS
+	/* always define full MSS even for DEC Alphas, just in case... */
 		{SNDCARD_MSS, {MSS_BASE, MSS_IRQ, MSS_DMA, -1}, SND_DEFAULT_ENABLE},
-#	else
+#	ifdef __alpha__
+	/* MSS without IRQ/DMA config registers (for DEC Alphas) */
 		{SNDCARD_PSEUDO_MSS, {MSS_BASE, MSS_IRQ, MSS_DMA, -1}, SND_DEFAULT_ENABLE},
 #	endif
 #	ifdef MSS2_BASE
diff -u --recursive --new-file v1.3.69/linux/drivers/sound/gus_card.c linux/drivers/sound/gus_card.c
--- v1.3.69/linux/drivers/sound/gus_card.c	Wed Feb 28 11:50:07 1996
+++ linux/drivers/sound/gus_card.c	Fri Mar  1 07:50:55 1996
@@ -35,7 +35,7 @@
 
 #include "gus_hw.h"
 
-void            gusintr (int irq, struct pt_regs *dummy);
+void            gusintr (int irq, void *dev_id, struct pt_regs *dummy);
 
 int             gus_base, gus_irq, gus_dma;
 extern int      gus_wave_volume;
@@ -171,7 +171,7 @@
 }
 
 void
-gusintr (int irq, struct pt_regs *dummy)
+gusintr (int irq, void *dev_id, struct pt_regs *dummy)
 {
   unsigned char   src;
   extern int      gus_timer_enabled;
@@ -180,7 +180,7 @@
 
 #ifdef CONFIG_GUSMAX
   if (have_gus_max)
-    ad1848_interrupt (irq, NULL);
+    ad1848_interrupt (irq, NULL, NULL);
 #endif
 
   while (1)
diff -u --recursive --new-file v1.3.69/linux/drivers/sound/gus_wave.c linux/drivers/sound/gus_wave.c
--- v1.3.69/linux/drivers/sound/gus_wave.c	Wed Feb 28 11:50:07 1996
+++ linux/drivers/sound/gus_wave.c	Fri Mar  1 07:50:55 1996
@@ -837,7 +837,7 @@
 
   gus_select_voice (0);		/* This disables writes to IRQ/DMA reg */
 
-  gusintr (0, NULL);		/* Serve pending interrupts */
+  gusintr (0, NULL, NULL);      /* Serve pending interrupts */
   restore_flags (flags);
 }
 
diff -u --recursive --new-file v1.3.69/linux/drivers/sound/mad16_sb_midi.c linux/drivers/sound/mad16_sb_midi.c
--- v1.3.69/linux/drivers/sound/mad16_sb_midi.c	Wed Feb 14 14:37:14 1996
+++ linux/drivers/sound/mad16_sb_midi.c	Fri Mar  1 07:50:55 1996
@@ -90,7 +90,7 @@
 }
 
 void
-mad16_sbintr (int irq, struct pt_regs *dummy)
+mad16_sbintr (int irq, void *dev_id, struct pt_regs *dummy)
 {
   int             status;
 
diff -u --recursive --new-file v1.3.69/linux/drivers/sound/maui.c linux/drivers/sound/maui.c
--- v1.3.69/linux/drivers/sound/maui.c	Wed Feb 28 11:50:08 1996
+++ linux/drivers/sound/maui.c	Fri Mar  1 07:50:55 1996
@@ -134,7 +134,7 @@
 }
 
 void
-mauiintr (int irq, struct pt_regs *dummy)
+mauiintr (int irq, void *dev_id, struct pt_regs *dummy)
 {
   irq_ok = 1;
 }
diff -u --recursive --new-file v1.3.69/linux/drivers/sound/mpu401.c linux/drivers/sound/mpu401.c
--- v1.3.69/linux/drivers/sound/mpu401.c	Wed Feb 28 11:50:08 1996
+++ linux/drivers/sound/mpu401.c	Fri Mar  1 07:50:55 1996
@@ -450,7 +450,7 @@
 }
 
 void
-mpuintr (int irq, struct pt_regs *dummy)
+mpuintr (int irq, void *dev_id, struct pt_regs *dummy)
 {
   struct mpu_config *devc;
   int             dev;
diff -u --recursive --new-file v1.3.69/linux/drivers/sound/pas2_card.c linux/drivers/sound/pas2_card.c
--- v1.3.69/linux/drivers/sound/pas2_card.c	Wed Feb 28 11:50:08 1996
+++ linux/drivers/sound/pas2_card.c	Fri Mar  1 07:50:55 1996
@@ -84,7 +84,7 @@
 /******************* Begin of the Interrupt Handler ********************/
 
 void
-pasintr (int irq, struct pt_regs *dummy)
+pasintr (int irq, void *dev_id, struct pt_regs *dummy)
 {
   int             status;
 
diff -u --recursive --new-file v1.3.69/linux/drivers/sound/sb16_midi.c linux/drivers/sound/sb16_midi.c
--- v1.3.69/linux/drivers/sound/sb16_midi.c	Wed Feb 28 11:50:08 1996
+++ linux/drivers/sound/sb16_midi.c	Fri Mar  1 07:50:55 1996
@@ -108,7 +108,7 @@
 }
 
 void
-sbmidiintr (int irq, struct pt_regs *dummy)
+sbmidiintr (int irq, void *dev_id, struct pt_regs *dummy)
 {
   if (input_avail ())
     sb16midi_input_loop ();
diff -u --recursive --new-file v1.3.69/linux/drivers/sound/sb_dsp.c linux/drivers/sound/sb_dsp.c
--- v1.3.69/linux/drivers/sound/sb_dsp.c	Wed Feb 28 11:50:08 1996
+++ linux/drivers/sound/sb_dsp.c	Fri Mar  1 07:50:55 1996
@@ -180,7 +180,7 @@
 }
 
 void
-sbintr (int irq, struct pt_regs *dummy)
+sbintr (int irq, void *dev_id, struct pt_regs *dummy)
 {
   int             status;
 
diff -u --recursive --new-file v1.3.69/linux/drivers/sound/sound_calls.h linux/drivers/sound/sound_calls.h
--- v1.3.69/linux/drivers/sound/sound_calls.h	Wed Feb 14 14:37:16 1996
+++ linux/drivers/sound/sound_calls.h	Fri Mar  1 07:50:55 1996
@@ -83,7 +83,7 @@
 void request_sound_timer (int count);
 void sound_stop_timer(void);
 int snd_ioctl_return(int *addr, int value);
-int snd_set_irq_handler (int interrupt_level, void(*hndlr)(int, struct pt_regs *), char *name, int *osp);
+int snd_set_irq_handler (int interrupt_level, void(*hndlr)(int, void *, struct pt_regs *), char *name, int *osp);
 void snd_release_irq(int vect);
 void sound_dma_malloc(int dev);
 void sound_dma_free(int dev);
@@ -118,7 +118,7 @@
 long attach_sb16midi(long mem_start, struct address_info * hw_config);
 int probe_sb16midi(struct address_info *hw_config);
 void sb_midi_interrupt(int dummy);
-void sbmidiintr(int irq, struct pt_regs * dummy);
+void sbmidiintr(int irq, void *dev_id, struct pt_regs * dummy);
 
 /*	From sb_midi.c	*/
 void sb_midi_init(int model);
@@ -164,7 +164,7 @@
 long attach_gus_card(long mem_start, struct address_info * hw_config);
 int probe_gus(struct address_info *hw_config);
 int gus_set_midi_irq(int num);
-void gusintr(int irq, struct pt_regs * dummy);
+void gusintr(int irq, void *dev_id, struct pt_regs * dummy);
 long attach_gus_db16(long mem_start, struct address_info * hw_config);
 int probe_gus_db16(struct address_info *hw_config);
 
@@ -187,7 +187,7 @@
 /*	From mpu401.c */
 long attach_mpu401(long mem_start, struct address_info * hw_config);
 int probe_mpu401(struct address_info *hw_config);
-void mpuintr(int irq, struct pt_regs * dummy);
+void mpuintr(int irq, void *dev_id, struct pt_regs * dummy);
 
 /*	From uart6850.c */
 long attach_uart6850(long mem_start, struct address_info * hw_config);
@@ -220,7 +220,7 @@
 #define AD_F_CS4231	0x0001	/* Returned if a CS4232 (or compatible) detected */
 #define AD_F_CS4248	0x0001	/* Returned if a CS4248 (or compatible) detected */
 
-void     ad1848_interrupt (int irq, struct pt_regs * dummy);
+void     ad1848_interrupt (int irq, void *dev_id, struct pt_regs * dummy);
 long attach_ms_sound(long mem_start, struct address_info * hw_config);
 int probe_ms_sound(struct address_info *hw_config);
 long attach_pnp_ad1848(long mem_start, struct address_info * hw_config);
diff -u --recursive --new-file v1.3.69/linux/drivers/sound/soundcard.c linux/drivers/sound/soundcard.c
--- v1.3.69/linux/drivers/sound/soundcard.c	Wed Feb 28 11:50:09 1996
+++ linux/drivers/sound/soundcard.c	Fri Mar  1 07:50:55 1996
@@ -481,11 +481,11 @@
 }
 
 int
-snd_set_irq_handler (int interrupt_level, void (*hndlr) (int, struct pt_regs *), char *name, int *osp)
+snd_set_irq_handler (int interrupt_level, void (*hndlr) (int, void *, struct pt_regs *), char *name, int *osp)
 {
   int             retcode;
 
-  retcode = request_irq (interrupt_level, hndlr, 0 /* SA_INTERRUPT */ , name);
+  retcode = request_irq (interrupt_level, hndlr, 0 /* SA_INTERRUPT */ , name, NULL);
   if (retcode < 0)
     {
       printk ("Sound: IRQ%d already in use\n", interrupt_level);
@@ -500,7 +500,7 @@
 snd_release_irq (int vect)
 {
   irqs &= ~(1ul << vect);
-  free_irq (vect);
+  free_irq (vect, NULL);
 }
 
 int
diff -u --recursive --new-file v1.3.69/linux/drivers/sound/sscape.c linux/drivers/sound/sscape.c
--- v1.3.69/linux/drivers/sound/sscape.c	Wed Feb 14 14:37:16 1996
+++ linux/drivers/sound/sscape.c	Fri Mar  1 07:50:55 1996
@@ -301,7 +301,7 @@
 }
 
 void
-sscapeintr (int irq, struct pt_regs *dummy)
+sscapeintr (int irq, void *dev_id, struct pt_regs *dummy)
 {
   unsigned char   bits, tmp;
   static int      debug = 0;
@@ -323,7 +323,7 @@
 #if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
   if (bits & 0x01)
     {
-      mpuintr (irq, NULL);
+      mpuintr (irq, NULL, NULL);
       if (debug++ > 10)		/* Temporary debugging hack */
 	{
 	  sscape_write (devc, GA_INTENA_REG, 0x00);	/* Disable all interrupts */
diff -u --recursive --new-file v1.3.69/linux/drivers/sound/uart6850.c linux/drivers/sound/uart6850.c
--- v1.3.69/linux/drivers/sound/uart6850.c	Wed Feb 28 11:50:09 1996
+++ linux/drivers/sound/uart6850.c	Fri Mar  1 07:50:55 1996
@@ -109,7 +109,7 @@
 }
 
 void
-m6850intr (int irq, struct pt_regs *dummy)
+m6850intr (int irq, void *dev_id, struct pt_regs *dummy)
 {
   if (input_avail ())
     uart6850_input_loop ();
diff -u --recursive --new-file v1.3.69/linux/fs/ncpfs/sock.c linux/fs/ncpfs/sock.c
--- v1.3.69/linux/fs/ncpfs/sock.c	Wed Feb 28 11:50:10 1996
+++ linux/fs/ncpfs/sock.c	Fri Mar  1 07:22:56 1996
@@ -257,7 +257,7 @@
 			ntohs(sender.sipx_port),
 			packet_buf[0], packet_buf[1]);
 
-		ncp_trigger_message(sk->protinfo.ipx.ncp_server);
+		ncp_trigger_message(sk->protinfo.af_ipx.ncp_server);
 
 		set_fs(fs);
 	}
@@ -306,7 +306,7 @@
         }
 
         sk->data_ready = ncp_msg_data_ready;
-	sk->protinfo.ipx.ncp_server = server;
+	sk->protinfo.af_ipx.ncp_server = server;
         return 0;
 }
                 
diff -u --recursive --new-file v1.3.69/linux/include/asm-alpha/alcor.h linux/include/asm-alpha/alcor.h
--- v1.3.69/linux/include/asm-alpha/alcor.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-alpha/alcor.h	Wed Feb 28 11:36:37 1996
@@ -0,0 +1,407 @@
+#ifndef __ALPHA_ALCOR__H__
+#define __ALPHA_ALCOR__H__
+
+#include <linux/types.h>
+
+/*
+ * ALCOR is the internal name for the 2117x chipset which provides
+ * memory controller and PCI access for the 21164 chip based systems.
+ *
+ * This file is based on:
+ *
+ * DECchip 21171 Core Logic Chipset 
+ * Technical Reference Manual
+ *
+ * EC-QE18B-TE
+ *
+ * david.rusling@reo.mts.dec.com Initial Version.
+ *
+ */
+
+/*------------------------------------------------------------------------**
+**                                                                        **
+**  EB164 I/O procedures                                                   **
+**                                                                        **
+**      inport[b|w|t|l], outport[b|w|t|l] 8:16:24:32 IO xfers             **
+**	inportbxt: 8 bits only                                            **
+**      inport:    alias of inportw                                       **
+**      outport:   alias of outportw                                      **
+**                                                                        **
+**      inmem[b|w|t|l], outmem[b|w|t|l] 8:16:24:32 ISA memory xfers       **
+**	inmembxt: 8 bits only                                             **
+**      inmem:    alias of inmemw                                         **
+**      outmem:   alias of outmemw                                        **
+**                                                                        **
+**------------------------------------------------------------------------*/
+
+
+/* ALCOR ADDRESS BIT DEFINITIONS
+ *
+ *  3 3 3 3|3 3 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 
+ *  9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |1| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |0|0|0|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
+ *  |                                                                        \_/ \_/
+ *  |                                                                         |   |
+ *  +-- IO space, not cached.                                   Byte Enable --+   |
+ *                                                              Transfer Length --+
+ *
+ *
+ *
+ *   Byte      Transfer
+ *   Enable    Length    Transfer  Byte    Address
+ *   adr<6:5>  adr<4:3>  Length    Enable  Adder
+ *   ---------------------------------------------
+ *      00        00      Byte      1110   0x000
+ *      01        00      Byte      1101   0x020
+ *      10        00      Byte      1011   0x040
+ *      11        00      Byte      0111   0x060
+ *
+ *      00        01      Word      1100   0x008
+ *      01        01      Word      1001   0x028 <= Not supported in this code.
+ *      10        01      Word      0011   0x048
+ *
+ *      00        10      Tribyte   1000   0x010
+ *      01        10      Tribyte   0001   0x030
+ *
+ *      10        11      Longword  0000   0x058
+ *
+ *      Note that byte enables are asserted low.
+ *
+ */
+
+#define BYTE_ENABLE_SHIFT 5
+#define TRANSFER_LENGTH_SHIFT 3
+#define MEM_SP1_MASK 0x1fffffff  /* Mem sparse space 1 mask is 29 bits */
+
+
+#define ALCOR_DMA_WIN_BASE	(1024UL*1024UL*1024UL)
+#define ALCOR_DMA_WIN_SIZE	(1024*1024*1024)
+
+/*
+ * 21171-CA Control and Status Registers (p4-1)
+ */
+#define ALCOR_IOC_CIA_REV               (IDENT_ADDR + 0x8740000080UL)
+#define ALCOR_IOC_PCI_LAT               (IDENT_ADDR + 0x87400000C0UL)
+#define ALCOR_IOC_CIA_CTRL              (IDENT_ADDR + 0x8740000100UL)
+#define ALCOR_IOC_HAE_MEM               (IDENT_ADDR + 0x8740000400UL)
+#define ALCOR_IOC_HAE_IO                (IDENT_ADDR + 0x8740000440UL)
+#define ALCOR_IOC_CFG                   (IDENT_ADDR + 0x8740000480UL)
+#define ALCOR_IOC_CACK_EN               (IDENT_ADDR + 0x8740000600UL)
+
+/*
+ * 21171-CA Diagnostic Registers (p4-2)
+ */
+#define ALCOR_IOC_CIA_DIAG              (IDENT_ADDR + 0x8740002000UL)
+#define ALCOR_IOC_DIAG_CHECK            (IDENT_ADDR + 0x8740003000UL)
+
+/*
+ * 21171-CA Performance Monitor registers (p4-3)
+ */
+#define ALCOR_IOC_PERF_MONITOR          (IDENT_ADDR + 0x8740004000UL)
+#define ALCOR_IOC_PERF_CONTROL          (IDENT_ADDR + 0x8740004040UL)
+
+/*
+ * 21171-CA Error registers (p4-3)
+ */
+#define ALCOR_IOC_CPU_ERR0              (IDENT_ADDR + 0x8740008000UL)
+#define ALCOR_IOC_CPU_ERR1              (IDENT_ADDR + 0x8740008040UL)
+#define ALCOR_IOC_CIA_ERR               (IDENT_ADDR + 0x8740008200UL)
+#define ALCOR_IOC_CIA_STAT              (IDENT_ADDR + 0x8740008240UL)
+#define ALCOR_IOC_ERR_MASK              (IDENT_ADDR + 0x8740008280UL)
+#define ALCOR_IOC_CIA_SYN               (IDENT_ADDR + 0x8740008300UL)
+#define ALCOR_IOC_MEM_ERR0              (IDENT_ADDR + 0x8740008400UL)
+#define ALCOR_IOC_MEM_ERR1              (IDENT_ADDR + 0x8740008440UL)
+#define ALCOR_IOC_PCI_ERR0              (IDENT_ADDR + 0x8740008800UL)
+#define ALCOR_IOC_PCI_ERR1              (IDENT_ADDR + 0x8740008840UL)
+#define ALCOR_IOC_PCI_ERR3              (IDENT_ADDR + 0x8740008880UL)
+
+/*
+ * 2117A-CA PCI Address Translation Registers.   I've only defined
+ * the first window fully as that's the only one that we're currently using.
+ * The other window bases are needed to disable the windows.
+ */
+#define ALCOR_IOC_PCI_TBIA              (IDENT_ADDR + 0x8760000100UL)
+#define ALCOR_IOC_PCI_W0_BASE           (IDENT_ADDR + 0x8760000400UL)
+#define ALCOR_IOC_PCI_W0_MASK           (IDENT_ADDR + 0x8760000440UL)
+#define ALCOR_IOC_PCI_T0_BASE           (IDENT_ADDR + 0x8760000480UL)
+
+#define ALCOR_IOC_PCI_W1_BASE           (IDENT_ADDR + 0x8760000500UL)
+#define ALCOR_IOC_PCI_W2_BASE           (IDENT_ADDR + 0x8760000600UL)
+#define ALCOR_IOC_PCI_W3_BASE           (IDENT_ADDR + 0x8760000700UL)
+
+/*
+ * 21171-CA System configuration registers (p4-3)
+ */
+#define ALCOR_IOC_MCR                   (IDENT_ADDR + 0x8750000000UL)
+#define ALCOR_IOC_MBA0                  (IDENT_ADDR + 0x8750000600UL)
+#define ALCOR_IOC_MBA2                  (IDENT_ADDR + 0x8750000680UL)
+#define ALCOR_IOC_MBA4                  (IDENT_ADDR + 0x8750000700UL)
+#define ALCOR_IOC_MBA6                  (IDENT_ADDR + 0x8750000780UL)
+#define ALCOR_IOC_MBA8                  (IDENT_ADDR + 0x8750000800UL)
+#define ALCOR_IOC_MBAA                  (IDENT_ADDR + 0x8750000880UL)
+#define ALCOR_IOC_MBAC                  (IDENT_ADDR + 0x8750000900UL)
+#define ALCOR_IOC_MBAE                  (IDENT_ADDR + 0x8750000980UL)
+#define ALCOR_IOC_TMG0                  (IDENT_ADDR + 0x8750000B00UL)
+#define ALCOR_IOC_TMG1                  (IDENT_ADDR + 0x8750000B40UL)
+#define ALCOR_IOC_TMG2                  (IDENT_ADDR + 0x8750000B80UL)
+
+/*
+ * Memory spaces:
+ */
+#define ALCOR_IACK_SC		        (IDENT_ADDR + 0x8720000000UL)
+#define ALCOR_CONF		        (IDENT_ADDR + 0x8700000000UL)
+#define ALCOR_IO			(IDENT_ADDR + 0x8580000000UL)
+#define ALCOR_SPARSE_MEM		(IDENT_ADDR + 0x8000000000UL)
+#define ALCOR_DENSE_MEM		        (IDENT_ADDR + 0x8600000000UL)
+
+/*
+ * Bit definitions for I/O Controller status register 0:
+ */
+#define ALCOR_IOC_STAT0_CMD		0xf
+#define ALCOR_IOC_STAT0_ERR		(1<<4)
+#define ALCOR_IOC_STAT0_LOST		(1<<5)
+#define ALCOR_IOC_STAT0_THIT		(1<<6)
+#define ALCOR_IOC_STAT0_TREF		(1<<7)
+#define ALCOR_IOC_STAT0_CODE_SHIFT	8
+#define ALCOR_IOC_STAT0_CODE_MASK	0x7
+#define ALCOR_IOC_STAT0_P_NBR_SHIFT	13
+#define ALCOR_IOC_STAT0_P_NBR_MASK	0x7ffff
+
+#define HAE_ADDRESS	                ALCOR_IOC_HAE_MEM
+
+#ifdef __KERNEL__
+
+/*
+ * Translate physical memory address as seen on (PCI) bus into
+ * a kernel virtual address and vv.
+ */
+extern inline unsigned long virt_to_bus(void * address)
+{
+	return virt_to_phys(address) + ALCOR_DMA_WIN_BASE;
+}
+
+extern inline void * bus_to_virt(unsigned long address)
+{
+	return phys_to_virt(address - ALCOR_DMA_WIN_BASE);
+}
+
+/*
+ * I/O functions:
+ *
+ * Alcor (the 2117x PCI/memory support chipset for the EV5 (21164)
+ * series of processors uses a sparse address mapping scheme to
+ * get at PCI memory and I/O.
+ */
+
+#define vuip	volatile unsigned int *
+
+extern inline unsigned int __inb(unsigned long addr)
+{
+	long result = *(vuip) ((addr << 5) + ALCOR_IO + 0x00);
+	result >>= (addr & 3) * 8;
+	return 0xffUL & result;
+}
+
+extern inline void __outb(unsigned char b, unsigned long addr)
+{
+	unsigned int w;
+
+	asm ("insbl %2,%1,%0" : "r="(w) : "ri"(addr & 0x3), "r"(b));
+	*(vuip) ((addr << 5) + ALCOR_IO + 0x00) = w;
+	mb();
+}
+
+extern inline unsigned int __inw(unsigned long addr)
+{
+	long result = *(vuip) ((addr << 5) + ALCOR_IO + 0x08);
+	result >>= (addr & 3) * 8;
+	return 0xffffUL & result;
+}
+
+extern inline void __outw(unsigned short b, unsigned long addr)
+{
+	unsigned int w;
+
+	asm ("inswl %2,%1,%0" : "r="(w) : "ri"(addr & 0x3), "r"(b));
+	*(vuip) ((addr << 5) + ALCOR_IO + 0x08) = w;
+	mb();
+}
+
+extern inline unsigned int __inl(unsigned long addr)
+{
+	return *(vuip) ((addr << 5) + ALCOR_IO + 0x18);
+}
+
+extern inline void __outl(unsigned int b, unsigned long addr)
+{
+	*(vuip) ((addr << 5) + ALCOR_IO + 0x18) = b;
+	mb();
+}
+
+
+/*
+ * Memory functions.  64-bit and 32-bit accesses are done through
+ * dense memory space, everything else through sparse space.
+ * 
+ * For reading and writing 8 and 16 bit quantities we need to 
+ * go through one of the three sparse address mapping regions
+ * and use the HAE_MEM CSR to provide some bits of the address.
+ * The following few routines use only sparse address region 1
+ * which gives 1Gbyte of accessible space which relates exactly
+ * to the amount of PCI memory mapping *into* system address space.
+ * See p 6-17 of the specification but it looks something like this:
+ *
+ * 21164 Address:
+ * 
+ *          3         2         1                                                               
+ * 9876543210987654321098765432109876543210
+ * 1ZZZZ0.PCI.QW.Address............BBLL                 
+ *
+ * ZZ = SBZ
+ * BB = Byte offset
+ * LL = Transfer length
+ *
+ * PCI Address:
+ *
+ * 3         2         1                                                               
+ * 10987654321098765432109876543210
+ * HHH....PCI.QW.Address........ 00
+ *
+ * HHH = 31:29 HAE_MEM CSR
+ * 
+ */
+
+extern inline unsigned long __readb(unsigned long addr)
+{
+	unsigned long result, shift, msb;
+
+	shift = (addr & 0x3) * 8 ;
+	msb = addr & 0xE0000000 ;
+	addr &= MEM_SP1_MASK ;
+	if (msb != hae.cache) {
+	  set_hae(msb);
+	}
+	result = *(vuip) ((addr << 5) + ALCOR_SPARSE_MEM + 0x00) ;
+	result >>= shift;
+	return 0xffUL & result;
+}
+
+extern inline unsigned long __readw(unsigned long addr)
+{
+	unsigned long result, shift, msb;
+
+	shift = (addr & 0x3) * 8;
+	msb = addr & 0xE0000000 ;
+	addr &= MEM_SP1_MASK ;
+	if (msb != hae.cache) {
+	  set_hae(msb);
+	}
+	result = *(vuip) ((addr << 5) + ALCOR_SPARSE_MEM + 0x08);
+	result >>= shift;
+	return 0xffffUL & result;
+}
+
+extern inline unsigned long __readl(unsigned long addr)
+{
+	return *(vuip) (addr + ALCOR_DENSE_MEM);
+}
+
+extern inline void __writeb(unsigned char b, unsigned long addr)
+{
+        unsigned long msb ; 
+
+	msb = addr & 0xE0000000 ;
+	addr &= MEM_SP1_MASK ;
+	if (msb != hae.cache) {
+	  set_hae(msb);
+	}
+	*(vuip) ((addr << 5) + ALCOR_SPARSE_MEM + 0x00) = b * 0x01010101;
+}
+
+extern inline void __writew(unsigned short b, unsigned long addr)
+{
+        unsigned long msb ; 
+
+	msb = addr & 0xE0000000 ;
+	addr &= MEM_SP1_MASK ;
+	if (msb != hae.cache) {
+	  set_hae(msb);
+	}
+	*(vuip) ((addr << 5) + ALCOR_SPARSE_MEM + 0x08) = b * 0x00010001;
+}
+
+extern inline void __writel(unsigned int b, unsigned long addr)
+{
+	*(vuip) (addr + ALCOR_DENSE_MEM) = b;
+}
+
+#define inb(port) \
+(__builtin_constant_p((port))?__inb(port):_inb(port))
+
+#define outb(x, port) \
+(__builtin_constant_p((port))?__outb((x),(port)):_outb((x),(port)))
+
+#define readl(a)	__readl((unsigned long)(a))
+#define writel(v,a)	__writel((v),(unsigned long)(a))
+
+#undef vuip
+
+extern unsigned long alcor_init (unsigned long mem_start,
+				 unsigned long mem_end);
+
+#endif /* __KERNEL__ */
+
+/*
+ * Data structure for handling ALCOR machine checks:
+ */
+struct el_ALCOR_sysdata_mcheck {
+    u_long      coma_gcr;                       
+    u_long      coma_edsr;                      
+    u_long      coma_ter;                       
+    u_long      coma_elar;                      
+    u_long      coma_ehar;                      
+    u_long      coma_ldlr;                      
+    u_long      coma_ldhr;                      
+    u_long      coma_base0;                     
+    u_long      coma_base1;                     
+    u_long      coma_base2;                     
+    u_long      coma_cnfg0;                     
+    u_long      coma_cnfg1;                     
+    u_long      coma_cnfg2;                     
+    u_long      epic_dcsr;                      
+    u_long      epic_pear;                      
+    u_long      epic_sear;                      
+    u_long      epic_tbr1;                      
+    u_long      epic_tbr2;                      
+    u_long      epic_pbr1;                      
+    u_long      epic_pbr2;                      
+    u_long      epic_pmr1;                      
+    u_long      epic_pmr2;                      
+    u_long      epic_harx1;                     
+    u_long      epic_harx2;                     
+    u_long      epic_pmlt;                      
+    u_long      epic_tag0;                      
+    u_long      epic_tag1;                      
+    u_long      epic_tag2;                      
+    u_long      epic_tag3;                      
+    u_long      epic_tag4;                      
+    u_long      epic_tag5;                      
+    u_long      epic_tag6;                      
+    u_long      epic_tag7;                      
+    u_long      epic_data0;                     
+    u_long      epic_data1;                     
+    u_long      epic_data2;                     
+    u_long      epic_data3;                     
+    u_long      epic_data4;                     
+    u_long      epic_data5;                     
+    u_long      epic_data6;                     
+    u_long      epic_data7;                     
+};
+
+#define RTC_PORT(x)	(0x70 + (x))
+#define RTC_ADDR(x)	(0x80 | (x))
+#define RTC_ALWAYS_BCD	0
+
+#endif /* __ALPHA_ALCOR__H__ */
diff -u --recursive --new-file v1.3.69/linux/include/asm-alpha/floppy.h linux/include/asm-alpha/floppy.h
--- v1.3.69/linux/include/asm-alpha/floppy.h	Thu Nov  9 11:23:52 1995
+++ linux/include/asm-alpha/floppy.h	Fri Mar  1 07:50:55 1996
@@ -26,8 +26,8 @@
 #define fd_cacheflush(addr,size) /* nothing */
 #define fd_request_irq()        request_irq(FLOPPY_IRQ, floppy_interrupt, \
 					    SA_INTERRUPT|SA_SAMPLE_RANDOM, \
-				            "floppy")
-#define fd_free_irq()           free_irq(FLOPPY_IRQ);
+				            "floppy", NULL)
+#define fd_free_irq()           free_irq(FLOPPY_IRQ, NULL);
 
 __inline__ void virtual_dma_init(void)
 {
diff -u --recursive --new-file v1.3.69/linux/include/asm-alpha/io.h linux/include/asm-alpha/io.h
--- v1.3.69/linux/include/asm-alpha/io.h	Tue Feb 20 14:37:28 1996
+++ linux/include/asm-alpha/io.h	Wed Feb 28 11:36:37 1996
@@ -73,6 +73,8 @@
 # include <asm/lca.h>		/* get chip-specific definitions */
 #elif defined(CONFIG_ALPHA_APECS)
 # include <asm/apecs.h>		/* get chip-specific definitions */
+#elif defined(CONFIG_ALPHA_ALCOR)
+# include <asm/alcor.h>		/* get chip-specific definitions */
 #else
 # include <asm/jensen.h>
 #endif
diff -u --recursive --new-file v1.3.69/linux/include/asm-alpha/irq.h linux/include/asm-alpha/irq.h
--- v1.3.69/linux/include/asm-alpha/irq.h	Mon Sep 18 14:54:08 1995
+++ linux/include/asm-alpha/irq.h	Wed Feb 28 11:36:37 1996
@@ -10,7 +10,7 @@
 #include <linux/linkage.h>
 #include <linux/config.h>
 
-#if defined(CONFIG_ALPHA_CABRIOLET) || defined(CONFIG_ALPHA_EB66P)
+#if defined(CONFIG_ALPHA_CABRIOLET) || defined(CONFIG_ALPHA_EB66P) || defined(CONFIG_ALPHA_EB164)
 # define NR_IRQS	33
 #elif defined(CONFIG_ALPHA_EB66) || defined(CONFIG_ALPHA_EB64P)
 # define NR_IRQS	32
diff -u --recursive --new-file v1.3.69/linux/include/asm-alpha/mmu_context.h linux/include/asm-alpha/mmu_context.h
--- v1.3.69/linux/include/asm-alpha/mmu_context.h	Mon Jan  8 14:10:28 1996
+++ linux/include/asm-alpha/mmu_context.h	Thu Feb 29 08:59:44 1996
@@ -32,7 +32,7 @@
  * work correctly and can thus not be used (explaining the lack of PAL-code
  * support).
  */
-#ifdef CONFIG_EV5
+#ifdef CONFIG_ALPHA_EV5
 #define MAX_ASN 127
 #else
 #define MAX_ASN 63
@@ -55,26 +55,28 @@
  */
 extern inline void get_mmu_context(struct task_struct *p)
 {
-#ifdef CONFIG_EV5
+#ifdef CONFIG_ALPHA_EV5
 	static unsigned long asn_cache = ASN_FIRST_VERSION;
 	struct mm_struct * mm = p->mm;
-	unsigned long asn = mm->context;
 
-	/* Check if our ASN is of an older version and thus invalid */
-	if ((asn_cache ^ asn) & ASN_VERSION_MASK) {
-		/* get a new asn of the current version */
-		asn = asn_cache++;
-		/* check if it's legal.. */
-		if ((asn & ~ASN_VERSION_MASK) > MAX_ASN) {
-			/* start a new version, invalidate all old asn's */
-			tbiap(); imb();
-			asn_cache = (asn_cache & ASN_VERSION_MASK) + ASN_FIRST_VERSION;
-			if (!asn_cache)
-				asn_cache = ASN_FIRST_VERSION;
+	if (mm) {
+		unsigned long asn = mm->context;
+		/* Check if our ASN is of an older version and thus invalid */
+		if ((asn_cache ^ asn) & ASN_VERSION_MASK) {
+			/* get a new asn of the current version */
 			asn = asn_cache++;
+			/* check if it's legal.. */
+			if ((asn & ~ASN_VERSION_MASK) > MAX_ASN) {
+				/* start a new version, invalidate all old asn's */
+				tbiap(); imb();
+				asn_cache = (asn_cache & ASN_VERSION_MASK) + ASN_FIRST_VERSION;
+				if (!asn_cache)
+					asn_cache = ASN_FIRST_VERSION;
+				asn = asn_cache++;
+			}
+			mm->context = asn;			/* full version + asn */
+			p->tss.asn = asn & ~ASN_VERSION_MASK;	/* just asn */
 		}
-		mm->context = asn;			/* full version + asn */
-		p->tss.asn = asn & ~ASN_VERSION_MASK;	/* just asn */
 	}
 #endif
 }
diff -u --recursive --new-file v1.3.69/linux/include/asm-alpha/signal.h linux/include/asm-alpha/signal.h
--- v1.3.69/linux/include/asm-alpha/signal.h	Tue Oct 10 18:46:38 1995
+++ linux/include/asm-alpha/signal.h	Fri Mar  1 07:50:56 1996
@@ -53,6 +53,7 @@
  * the changes in signal handling. LBT 010493.
  * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
  * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_SHIRQ flag is for shared interrupt support on PCI and EISA.
  */
 #define SA_NOCLDSTOP	0x00000004
 
@@ -61,6 +62,7 @@
 #define SA_INTERRUPT	0x20000000
 #define SA_NOMASK	0x00000008
 #define SA_ONESHOT	0x00000010
+#define SA_SHIRQ	0x00000020
 
 #ifdef __KERNEL__
 /*
diff -u --recursive --new-file v1.3.69/linux/include/asm-alpha/system.h linux/include/asm-alpha/system.h
--- v1.3.69/linux/include/asm-alpha/system.h	Fri Feb 16 11:34:11 1996
+++ linux/include/asm-alpha/system.h	Wed Feb 28 12:03:42 1996
@@ -52,12 +52,12 @@
 
 #define halt() __asm__ __volatile__ ("call_pal %0" : : "i" (PAL_halt) : "memory")
 
-extern void alpha_switch_to(unsigned long pctxp);
-
 #define switch_to(p) do { \
 	current_set[0] = p; \
 	alpha_switch_to((unsigned long) &(p)->tss - 0xfffffc0000000000); \
 } while (0)
+
+extern void alpha_switch_to(unsigned long pctxp);
 
 extern void imb(void);
 
diff -u --recursive --new-file v1.3.69/linux/include/asm-i386/floppy.h linux/include/asm-i386/floppy.h
--- v1.3.69/linux/include/asm-i386/floppy.h	Thu Nov  9 11:23:52 1995
+++ linux/include/asm-i386/floppy.h	Fri Mar  1 07:50:56 1996
@@ -26,8 +26,8 @@
 #define fd_cacheflush(addr,size) /* nothing */
 #define fd_request_irq()        request_irq(FLOPPY_IRQ, floppy_interrupt, \
 					    SA_INTERRUPT|SA_SAMPLE_RANDOM, \
-				            "floppy")
-#define fd_free_irq()           free_irq(FLOPPY_IRQ);
+				            "floppy", NULL)
+#define fd_free_irq()           free_irq(FLOPPY_IRQ, NULL);
 
 __inline__ void virtual_dma_init(void)
 {
diff -u --recursive --new-file v1.3.69/linux/include/asm-i386/signal.h linux/include/asm-i386/signal.h
--- v1.3.69/linux/include/asm-i386/signal.h	Wed Sep 27 16:00:00 1995
+++ linux/include/asm-i386/signal.h	Fri Mar  1 07:50:56 1996
@@ -50,8 +50,10 @@
  * the changes in signal handling. LBT 010493.
  * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
  * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_SHIRQ flag is for shared interrupt support on PCI and EISA.
  */
 #define SA_NOCLDSTOP	1
+#define SA_SHIRQ	0x04000000
 #define SA_STACK	0x08000000
 #define SA_RESTART	0x10000000
 #define SA_INTERRUPT	0x20000000
diff -u --recursive --new-file v1.3.69/linux/include/asm-i386/smp.h linux/include/asm-i386/smp.h
--- v1.3.69/linux/include/asm-i386/smp.h	Wed Feb 28 11:50:11 1996
+++ linux/include/asm-i386/smp.h	Fri Mar  1 07:50:56 1996
@@ -173,18 +173,20 @@
  *	Private routines/data
  */
  
+extern int smp_found_config;
 extern void smp_scan_config(unsigned long, unsigned long);
 extern unsigned long smp_alloc_memory(unsigned long mem_base);
 extern unsigned char *apic_reg;
 extern unsigned char *kernel_stacks[NR_CPUS];
 extern unsigned char boot_cpu_id;
 extern unsigned long cpu_present_map;
+extern volatile int cpu_number_map[NR_CPUS];
 extern volatile unsigned long smp_invalidate_needed;
 extern void smp_invalidate(void);
 extern volatile unsigned long kernel_flag, kernel_counter;
 extern volatile unsigned char active_kernel_processor;
-extern void smp_message_irq(int cpl, struct pt_regs *regs);
-extern void smp_reschedule_irq(int cpl, struct pt_regs *regs);
+extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs);
+extern void smp_reschedule_irq(int cpl, void *dev_id, struct pt_regs *regs);
 extern unsigned long ipi_count;
 extern void smp_invalidate_rcv(void);		/* Process an NMI */
 extern volatile unsigned long kernel_counter;
diff -u --recursive --new-file v1.3.69/linux/include/asm-mips/floppy.h linux/include/asm-mips/floppy.h
--- v1.3.69/linux/include/asm-mips/floppy.h	Sun Dec 17 11:43:23 1995
+++ linux/include/asm-mips/floppy.h	Fri Mar  1 07:50:56 1996
@@ -33,8 +33,8 @@
 #define fd_cacheflush(addr, size)	feature->fd_cacheflush((void *)addr, size)
 #define fd_request_irq()        request_irq(FLOPPY_IRQ, floppy_interrupt, \
 					    SA_INTERRUPT|SA_SAMPLE_RANDOM, \
-				            "floppy")
-#define fd_free_irq()           free_irq(FLOPPY_IRQ);
+				            "floppy", NULL)
+#define fd_free_irq()           free_irq(FLOPPY_IRQ, NULL);
 
 #define MAX_BUFFER_SECTORS 24
 #define virtual_dma_init()                                              \
diff -u --recursive --new-file v1.3.69/linux/include/asm-mips/signal.h linux/include/asm-mips/signal.h
--- v1.3.69/linux/include/asm-mips/signal.h	Sun Dec 17 11:43:24 1995
+++ linux/include/asm-mips/signal.h	Fri Mar  1 07:50:56 1996
@@ -66,6 +66,7 @@
  * the changes in signal handling. LBT 010493.
  * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
  * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_SHIRQ flag is for shared interrupt support on PCI and EISA.
  */
 #define SA_STACK	0x1
 #define SA_ONSTACK	SA_STACK
@@ -75,6 +76,7 @@
 #define SA_INTERRUPT	0x01000000
 #define SA_NOMASK	0x02000000
 #define SA_ONESHOT	0x04000000
+#define SA_SHIRQ	0x08000000
 
 #ifdef __KERNEL__
 /*
diff -u --recursive --new-file v1.3.69/linux/include/asm-ppc/signal.h linux/include/asm-ppc/signal.h
--- v1.3.69/linux/include/asm-ppc/signal.h	Mon Nov 27 12:48:35 1995
+++ linux/include/asm-ppc/signal.h	Fri Mar  1 07:50:56 1996
@@ -50,8 +50,10 @@
  * the changes in signal handling. LBT 010493.
  * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
  * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_SHIRQ flag is for shared interrupt support on PCI and EISA.
  */
 #define SA_NOCLDSTOP	1
+#define SA_SHIRQ	0x04000000
 #define SA_STACK	0x08000000
 #define SA_RESTART	0x10000000
 #define SA_INTERRUPT	0x20000000
diff -u --recursive --new-file v1.3.69/linux/include/asm-sparc/floppy.h linux/include/asm-sparc/floppy.h
--- v1.3.69/linux/include/asm-sparc/floppy.h	Mon Nov 27 12:48:36 1995
+++ linux/include/asm-sparc/floppy.h	Fri Mar  1 07:50:56 1996
@@ -250,7 +250,7 @@
 }
 
 /* Our low-level entry point in arch/sparc/kernel/entry.S */
-extern void floppy_hardint(int irq, struct pt_regs *regs);
+extern void floppy_hardint(int irq, void *dev_id, struct pt_regs *regs);
 
 static int sun_fd_request_irq(void)
 {
@@ -259,7 +259,7 @@
 
 	if(!once) {
 		once = 1;
-		error = request_fast_irq(FLOPPY_IRQ, floppy_hardint, SA_INTERRUPT, "floppy");
+		error = request_fast_irq(FLOPPY_IRQ, floppy_hardint, SA_INTERRUPT, "floppy", NULL);
 		return ((error == 0) ? 0 : -1);
 	} else return 0;
 }
diff -u --recursive --new-file v1.3.69/linux/include/asm-sparc/signal.h linux/include/asm-sparc/signal.h
--- v1.3.69/linux/include/asm-sparc/signal.h	Sat Nov 25 19:04:51 1995
+++ linux/include/asm-sparc/signal.h	Fri Mar  1 07:50:56 1996
@@ -98,6 +98,7 @@
  * the changes in signal handling. LBT 010493.
  * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
  * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_SHIRQ flag is for shared interrupt support on PCI and EISA.
  */
 #define SA_NOCLDSTOP	SV_IGNCHILD
 #define SA_STACK	SV_SSTACK
@@ -105,6 +106,7 @@
 #define SA_INTERRUPT	SV_INTR
 #define SA_NOMASK	0x10
 #define SA_ONESHOT	0x20
+#define SA_SHIRQ	0x40
 
 #define SIG_BLOCK          0x00	/* for blocking signals */
 #define SIG_UNBLOCK        0x40	/* for unblocking signals */
diff -u --recursive --new-file v1.3.69/linux/include/linux/atalk.h linux/include/linux/atalk.h
--- v1.3.69/linux/include/linux/atalk.h	Wed Nov  8 07:11:41 1995
+++ linux/include/linux/atalk.h	Fri Mar  1 07:22:56 1996
@@ -94,9 +94,9 @@
 struct ddpshdr
 {
 	/* FIXME for bigendians */
-	__u8	dsh_sport;
-	__u8	dsh_dport;
 	__u16	dsh_len:10, dsh_pad:6;
+	__u8	dsh_dport;
+	__u8	dsh_sport;
 	/* And netatalk apps expect to stick the type in themselves */
 };
 
diff -u --recursive --new-file v1.3.69/linux/include/linux/genhd.h linux/include/linux/genhd.h
--- v1.3.69/linux/include/linux/genhd.h	Wed Nov  8 07:11:41 1995
+++ linux/include/linux/genhd.h	Wed Feb 28 08:42:33 1996
@@ -66,4 +66,12 @@
 
 extern struct gendisk *gendisk_head;	/* linked list of disks */
 
+/*
+ * disk_name() is used by genhd.c and md.c.
+ * It formats the devicename of the indicated disk
+ * into the supplied buffer, and returns a pointer
+ * to that same buffer (for convenience).
+ */
+char *disk_name (struct gendisk *hd, int minor, char *buf);
+
 #endif
diff -u --recursive --new-file v1.3.69/linux/include/linux/if_arp.h linux/include/linux/if_arp.h
--- v1.3.69/linux/include/linux/if_arp.h	Wed Feb  7 15:11:37 1996
+++ linux/include/linux/if_arp.h	Fri Mar  1 07:22:56 1996
@@ -44,6 +44,7 @@
 #define ARPHRD_FRAD	770		/* Frame Relay			*/
 #define ARPHRD_SKIP	771		/* SKIP vif			*/
 #define ARPHRD_LOOPBACK	772		/* Loopback device		*/
+#define ARPHRD_LOCALTLK 773		/* Localtalk device		*/
 
 /* ARP protocol opcodes. */
 #define	ARPOP_REQUEST	1		/* ARP request			*/
diff -u --recursive --new-file v1.3.69/linux/include/linux/if_ether.h linux/include/linux/if_ether.h
--- v1.3.69/linux/include/linux/if_ether.h	Wed Feb  7 15:11:37 1996
+++ linux/include/linux/if_ether.h	Fri Mar  1 07:22:56 1996
@@ -50,6 +50,11 @@
 #define ETH_P_AARP	0x80F3		/* Appletalk AARP		*/
 #define ETH_P_IPX	0x8137		/* IPX over DIX			*/
 #define ETH_P_IPV6	0x86DD		/* IPv6 over bluebook		*/
+
+/*
+ *	Non DIX types. Won't clash for 1500 types.
+ */
+ 
 #define ETH_P_802_3	0x0001		/* Dummy type for 802.3 frames  */
 #define ETH_P_AX25	0x0002		/* Dummy protocol id for AX.25  */
 #define ETH_P_ALL	0x0003		/* Every packet (be careful!!!) */
@@ -58,6 +63,7 @@
 #define ETH_P_DDCMP     0x0006          /* DEC DDCMP: Internal only     */
 #define ETH_P_WAN_PPP   0x0007          /* Dummy type for WAN PPP frames*/
 #define ETH_P_PPP_MP    0x0008          /* Dummy type for PPP MP frames */
+#define ETH_P_LOCALTALK 0x0009		/* Localtalk pseudeo type 	*/
 
 /* This is an Ethernet frame header. */
 struct ethhdr {
diff -u --recursive --new-file v1.3.69/linux/include/linux/interrupt.h linux/include/linux/interrupt.h
--- v1.3.69/linux/include/linux/interrupt.h	Fri Feb 23 13:54:38 1996
+++ linux/include/linux/interrupt.h	Fri Mar  1 07:50:56 1996
@@ -5,6 +5,16 @@
 #include <linux/kernel.h>
 #include <asm/bitops.h>
 
+struct irqaction {
+	void (*handler)(int, void *, struct pt_regs *);
+	unsigned long flags;
+	unsigned long mask;
+	const char *name;
+	void *dev_id;
+	struct irqaction *next;
+};
+
+
 struct bh_struct {
 	void (*routine)(void *);
 	void *data;
diff -u --recursive --new-file v1.3.69/linux/include/linux/sched.h linux/include/linux/sched.h
--- v1.3.69/linux/include/linux/sched.h	Fri Feb 23 13:54:40 1996
+++ linux/include/linux/sched.h	Fri Mar  1 10:37:14 1996
@@ -342,9 +342,12 @@
 extern int send_sig(unsigned long sig,struct task_struct * p,int priv);
 extern int in_group_p(gid_t grp);
 
-extern int request_irq(unsigned int irq,void (*handler)(int, struct pt_regs *),
-	unsigned long flags, const char *device);
-extern void free_irq(unsigned int irq);
+extern int request_irq(unsigned int irq,
+		       void (*handler)(int, void *, struct pt_regs *),
+		       unsigned long flags, 
+		       const char *device,
+		       void *dev_id);
+extern void free_irq(unsigned int irq, void *dev_id);
 
 extern void copy_thread(int, unsigned long, unsigned long, struct task_struct *, struct pt_regs *);
 extern void flush_thread(void);
diff -u --recursive --new-file v1.3.69/linux/include/linux/xd.h linux/include/linux/xd.h
--- v1.3.69/linux/include/linux/xd.h	Mon Sep 18 14:54:10 1995
+++ linux/include/linux/xd.h	Fri Mar  1 07:50:56 1996
@@ -117,7 +117,7 @@
 static int xd_readwrite (u_char operation,u_char drive,char *buffer,u_int block,u_int count);
 static void xd_recalibrate (u_char drive);
 
-static void xd_interrupt_handler (int irq, struct pt_regs * regs);
+static void xd_interrupt_handler (int irq, void *dev_id, struct pt_regs *regs);
 static u_char xd_setup_dma (u_char opcode,u_char *buffer,u_int count);
 static u_char *xd_build (u_char *cmdblk,u_char command,u_char drive,u_char head,u_short cylinder,u_char sector,u_char count,u_char control);
 static inline u_char xd_waitport (u_short port,u_char flags,u_char mask,u_long timeout);
diff -u --recursive --new-file v1.3.69/linux/init/main.c linux/init/main.c
--- v1.3.69/linux/init/main.c	Wed Feb 28 11:50:14 1996
+++ linux/init/main.c	Fri Mar  1 07:22:56 1996
@@ -568,18 +568,25 @@
 	 *	Create the slave init tasks as sharing pid 0.
 	 */
 
-	for(i=1;i<smp_num_cpus;i++)
+	for (i=0; i<NR_CPUS; i++)
 	{
 		/*
-		 *	We use kernel_thread for the idlers which are
-		 *	unlocked tasks running in kernel space.
+		 *	This should only do anything if the mapping
+		 *	corresponds to a live CPU which is not the boot CPU.
 		 */
-		kernel_thread(cpu_idle, NULL, CLONE_PID);
-		/*
-		 *	Assume linear processor numbering
-		 */
-		current_set[i]=task[i];
-		current_set[i]->processor=i;
+		if (cpu_number_map[i] > 0)
+		{
+			/*
+			 *	We use kernel_thread for the idlers which are
+			 *	unlocked tasks running in kernel space.
+			 */
+			kernel_thread(cpu_idle, NULL, CLONE_PID);
+			/*
+			 *	Don't assume linear processor numbering
+			 */
+			current_set[i]=task[cpu_number_map[i]];
+			current_set[i]->processor=i;
+		}
 	}
 }		
 
diff -u --recursive --new-file v1.3.69/linux/kernel/sys.c linux/kernel/sys.c
--- v1.3.69/linux/kernel/sys.c	Sat Feb 17 16:02:57 1996
+++ linux/kernel/sys.c	Fri Mar  1 08:18:12 1996
@@ -420,7 +420,7 @@
 	return old_fsgid;
 }
 
-asmlinkage int sys_times(struct tms * tbuf)
+asmlinkage long sys_times(struct tms * tbuf)
 {
 	if (tbuf) {
 		int error = verify_area(VERIFY_WRITE,tbuf,sizeof *tbuf);
diff -u --recursive --new-file v1.3.69/linux/net/appletalk/aarp.c linux/net/appletalk/aarp.c
--- v1.3.69/linux/net/appletalk/aarp.c	Thu Jan  4 21:54:59 1996
+++ linux/net/appletalk/aarp.c	Fri Mar  1 07:22:56 1996
@@ -432,6 +432,47 @@
 	unsigned long flags;
 	
 	/*
+	 *	Check for localtalk first
+	 */
+	 
+	if(dev->type==ARPHRD_LOCALTLK)
+	{
+		struct at_addr *at=atalk_find_dev_addr(dev);
+		int ft=2;
+		
+		/*
+		 *	Compressable ?
+		 */
+		 
+		if(at->s_net==sa->s_net)
+		{
+			skb_pull(skb,sizeof(struct ddpehdr)-4);
+			/*
+			 *	The uper two remaining bytes are the port 
+			 *	numbers	we just happen to need. Now put the 
+			 *	length in the lower two.
+			 */
+			*((__u16 *)skb->data)=htons(skb->len);
+			ft=1;
+		}
+		/*
+		 *	Nice and easy. No AARP type protocols occur here
+		 *	so we can just shovel it out with a 3 byte LLAP header
+		 */
+		 
+		skb_push(skb,3);
+		skb->data[0]=sa->s_node;
+		skb->data[1]=at->s_node;
+		skb->data[2]=ft;
+		 
+		if(skb->sk==NULL)
+			dev_queue_xmit(skb, skb->dev, SOPRI_NORMAL);
+		else
+			dev_queue_xmit(skb, skb->dev, skb->sk->priority);
+		return 1;
+	}	
+	 
+	/*
 	 *	Non ELAP we cannot do.
 	 */
 
diff -u --recursive --new-file v1.3.69/linux/net/appletalk/ddp.c linux/net/appletalk/ddp.c
--- v1.3.69/linux/net/appletalk/ddp.c	Sat Feb 17 16:02:57 1996
+++ linux/net/appletalk/ddp.c	Fri Mar  1 07:22:56 1996
@@ -18,6 +18,7 @@
  *						socket.
  *		Alan Cox		:	Added firewall hooks.
  *		Alan Cox		:	Supports new ARPHRD_LOOPBACK
+ *		Christer Weinigel	: 	Routing and /proc fixes.
  *
  *		This program is free software; you can redistribute it and/or
  *		modify it under the terms of the GNU General Public License
@@ -62,7 +63,7 @@
 
 #ifdef CONFIG_ATALK
 
-#define APPLETALK_DEBUG
+#undef APPLETALK_DEBUG
 
 
 #ifdef APPLETALK_DEBUG
@@ -247,9 +248,13 @@
 	{
 		len += sprintf (buffer+len,"%02X   ", s->type);
 		len += sprintf (buffer+len,"%04X:%02X:%02X  ",
-			s->protinfo.af_at.src_net,s->protinfo.af_at.src_node,s->protinfo.af_at.src_port);
+			ntohs(s->protinfo.af_at.src_net),
+			s->protinfo.af_at.src_node,
+			s->protinfo.af_at.src_port);
 		len += sprintf (buffer+len,"%04X:%02X:%02X  ",
-			s->protinfo.af_at.dest_net,s->protinfo.af_at.dest_node,s->protinfo.af_at.dest_port);
+			ntohs(s->protinfo.af_at.dest_net),
+			s->protinfo.af_at.dest_node,
+			s->protinfo.af_at.dest_port);
 		len += sprintf (buffer+len,"%08lX:%08lX ", s->wmem_alloc, s->rmem_alloc);
 		len += sprintf (buffer+len,"%02X %d\n", s->state, SOCK_INODE(s->socket)->i_uid);
 		
@@ -715,10 +720,16 @@
 				return -EPERM;
 			if(sa->sat_family!=AF_APPLETALK)
 				return -EINVAL;
-			if(dev->type!=ARPHRD_ETHER&&dev->type!=ARPHRD_LOOPBACK)
+			if(dev->type!=ARPHRD_ETHER&&dev->type!=ARPHRD_LOOPBACK
+				&&dev->type!=ARPHRD_LOCALTLK)
 				return -EPROTONOSUPPORT;
 			nr=(struct netrange *)&sa->sat_zero[0];
-			if(nr->nr_phase!=2)
+			/*
+			 *	Phase 1 is fine on localtalk but we don't
+			 *	do Ethertalk phase 1. Anyone wanting to add
+			 *	it go ahead.
+			 */
+			if(dev->type==ARPHRD_ETHER && nr->nr_phase!=2)
 				return -EPROTONOSUPPORT;
 			if(sa->sat_addr.s_node==ATADDR_BCAST || sa->sat_addr.s_node == 254)
 				return -EINVAL;
@@ -882,13 +893,13 @@
 	if(atrtr_default.dev)
 	{
 		rt=&atrtr_default;
-		len += sprintf (buffer+len,"Default     %5d:%-3d  %-4d  %s\n",
+		len += sprintf (buffer+len,"Default     %04X:%02X  %-4d  %s\n",
 			ntohs(rt->gateway.s_net), rt->gateway.s_node, rt->flags,
 			rt->dev->name);
 	}
 	for (rt = atalk_router_list; rt != NULL; rt = rt->next)
 	{
-		len += sprintf (buffer+len,"%04X:%02X     %5d:%-3d  %-4d  %s\n",
+		len += sprintf (buffer+len,"%04X:%02X     %04X:%02X  %-4d  %s\n",
 			ntohs(rt->target.s_net),rt->target.s_node,
 			ntohs(rt->gateway.s_net), rt->gateway.s_node, rt->flags,
 			rt->dev->name);
@@ -1360,7 +1371,7 @@
  *	extracted.
  */
  
-int atalk_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
+static int atalk_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
 {
 	atalk_socket *sock;
 	struct ddpehdr *ddp=(void *)skb->h.raw;
@@ -1470,6 +1481,17 @@
 		}
 		ddp->deh_hops++;
 
+		/*
+		 *      Route goes through another gateway, so
+		 *      set the target to the gateway instead.
+		 */
+ 
+		if(rt->flags&RTF_GATEWAY)
+		{
+			ta.s_net = rt->gateway.s_net;
+			ta.s_node = rt->gateway.s_node;
+		}
+
                 /* Fix up skb->len field */
                 skb_trim(skb,min(origlen, rt->dev->hard_header_len + 
 			ddp_dl->header_length + ddp->deh_len));
@@ -1478,6 +1500,9 @@
 		/*
 		 *	Send the buffer onwards
 		 */
+		 
+		skb->arp = 1;	/* Resolved */
+		
 		if(aarp_send_ddp(rt->dev, skb, &ta, NULL)==-1)
 			kfree_skb(skb, FREE_READ);
 		return 0;
@@ -1512,6 +1537,69 @@
 	return(0);
 }
 
+/*
+ *	Receive a localtalk frame. We make some demands on the caller here.
+ *	Caller must provide enough headroom on the packet to pull the short
+ *	header and append a long one.
+ */
+
+ 
+static int ltalk_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
+{
+	struct ddpehdr *ddp;
+	struct at_addr *ap;
+	/*
+	 *	Expand any short form frames.
+	 */
+	 
+	if(skb->mac.raw[2]==1)
+	{
+		/*
+		 *	Find our address.
+		 */
+		 
+		ap=atalk_find_dev_addr(dev);
+		if(ap==NULL || skb->len<sizeof(struct ddpshdr))
+		{
+			kfree_skb(skb, FREE_READ);
+			return 0;
+		}
+	
+		/*
+		 *	The push leaves us with a ddephdr not an shdr, and
+		 *	handily the port bytes in the right place preset.
+		 */
+	 
+		skb_push(skb, sizeof(*ddp)-4);
+		ddp=(struct ddpehdr *)skb->data;
+	
+		/*
+		 *	Now fill in the long header.
+		 */
+	 
+	 	/*
+	 	 *	These two first. The mac overlays the new source/dest
+	 	 *	network information so we MUST copy these before
+	 	 *	we write the network numbers !
+	 	 */
+	 	 
+		ddp->deh_dnode=skb->mac.raw[0];	/* From physical header */
+		ddp->deh_snode=skb->mac.raw[1];	/* From physical header */
+		
+		ddp->deh_dnet=ap->s_net;	/* Network number */
+		ddp->deh_snet=ap->s_net;	
+		ddp->deh_sum=0;			/* No checksum */
+		/*
+		 *	Not sure about this bit...
+		 */
+		ddp->deh_len=skb->len;
+		ddp->deh_hops=15;		/* Non routable, so force a drop 
+						   if we slip up later */
+		*((__u16 *)ddp)=htons(*((__u16 *)ddp));		/* Mend the byte order */
+	}
+	return atalk_rcv(skb,dev,pt);
+}
+
 static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, int len, int nonblock, int flags)
 {
 	atalk_socket *sk=(atalk_socket *)sock->data;
@@ -1875,6 +1963,15 @@
 	0
 };
 
+struct packet_type ltalk_packet_type=
+{
+	0,
+	NULL,
+	ltalk_rcv,
+	NULL,
+	NULL
+};
+
 /* Called by proto.c on kernel start up */
 
 void atalk_proto_init(struct net_proto *pro)
@@ -1883,6 +1980,10 @@
 	(void) sock_register(atalk_proto_ops.family, &atalk_proto_ops);
 	if ((ddp_dl = register_snap_client(ddp_snap_id, atalk_rcv)) == NULL)
 		printk("Unable to register DDP with SNAP.\n");
+	
+	ltalk_packet_type.type=htons(ETH_P_LOCALTALK);	
+	dev_add_pack(&ltalk_packet_type);
+	
 	register_netdevice_notifier(&ddp_notifier);
 	aarp_proto_init();
 
@@ -1905,6 +2006,6 @@
 		atalk_if_get_info
 	});
 
-	printk("Appletalk 0.14 for Linux NET3.032\n");
+	printk("Appletalk 0.16 for Linux NET3.033\n");
 }
 #endif
diff -u --recursive --new-file v1.3.69/linux/net/ethernet/eth.c linux/net/ethernet/eth.c
--- v1.3.69/linux/net/ethernet/eth.c	Sat Feb 17 16:02:57 1996
+++ linux/net/ethernet/eth.c	Fri Mar  1 07:22:56 1996
@@ -28,7 +28,8 @@
  *		Alan Cox	: MAC layer pointers/new format.
  *		Paul Gortmaker	: eth_copy_and_sum shouldn't csum padding.
  *		Alan Cox	: Protect against forwarding explosions with
- *				  older network drivers and IFF_ALLMULTI
+ *				  older network drivers and IFF_ALLMULTI.
+ *	Christer Weinigel	: Better rebuild header message.
  *
  *		This program is free software; you can redistribute it and/or
  *		modify it under the terms of the GNU General Public License
@@ -147,7 +148,7 @@
 	 
 	if(eth->h_proto != htons(ETH_P_IP)) 
 	{
-		printk("eth_rebuild_header: Don't know how to resolve type %d addresses?\n",(int)eth->h_proto);
+		printk(KERN_DEBUG "%s: unable to resolve type %X addresses.\n",dev->name,(int)eth->h_proto);
 		memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
 		return 0;
 	}
diff -u --recursive --new-file v1.3.69/linux/net/ipv4/af_inet.c linux/net/ipv4/af_inet.c
--- v1.3.69/linux/net/ipv4/af_inet.c	Wed Feb 28 11:50:17 1996
+++ linux/net/ipv4/af_inet.c	Fri Mar  1 07:22:57 1996
@@ -863,7 +863,7 @@
 				/*
 				 *	Allow only if both are setting reuse.
 				 */
-				if(sk2->reuse && sk->reuse)
+				if(sk2->reuse && sk->reuse && sk2->state!=TCP_LISTEN)
 					continue;
 				sti();
 				return(-EADDRINUSE);
diff -u --recursive --new-file v1.3.69/linux/net/ipv4/icmp.c linux/net/ipv4/icmp.c
--- v1.3.69/linux/net/ipv4/icmp.c	Wed Feb 28 11:50:17 1996
+++ linux/net/ipv4/icmp.c	Fri Mar  1 07:22:57 1996
@@ -402,9 +402,9 @@
 					 *	are needed for AMPRnet AX.25 paths.
 					 */
 					else if (old_mtu > 216)
-						old_mtu = 216;
+						new_mtu = 216;
 					else if (old_mtu > 128)
-						old_mtu = 128;
+						new_mtu = 128;
 					else
 					/*
 					 *	Despair..
diff -u --recursive --new-file v1.3.69/linux/net/ipv4/route.c linux/net/ipv4/route.c
--- v1.3.69/linux/net/ipv4/route.c	Fri Feb 23 13:54:42 1996
+++ linux/net/ipv4/route.c	Fri Mar  1 07:22:57 1996
@@ -902,7 +902,7 @@
 
 	if (offset<128)
 	{
-		sprintf(buffer,"%-127s\n","Iface\tDestination\tGateway \tFlags\tRefCnt\tUse\tMetric\tSource\t\tMTU\tWindow\tIRTT\tHH\tARP\n");
+		sprintf(buffer,"%-127s\n","Iface\tDestination\tGateway \tFlags\tRefCnt\tUse\tMetric\tSource\t\tMTU\tWindow\tIRTT\tHH\tARP");
 		len = 128;
   	}
 	
diff -u --recursive --new-file v1.3.69/linux/net/ipx/af_ipx.c linux/net/ipx/af_ipx.c
--- v1.3.69/linux/net/ipx/af_ipx.c	Wed Feb 28 11:50:18 1996
+++ linux/net/ipx/af_ipx.c	Fri Mar  1 07:22:57 1996
@@ -1385,7 +1385,7 @@
 #ifdef CONFIG_IPX_INTERN
 			len += sprintf(buffer+len,
 				       "%08lX:%02X%02X%02X%02X%02X%02X:%04X  ", 
-				       htonl(s->ipx_intrfc->if_netnum),
+				 htonl(s->protinfo.af_ipx.intrfc->if_netnum),
 				       s->protinfo.af_ipx.node[0],
 				       s->protinfo.af_ipx.node[1], 
 				       s->protinfo.af_ipx.node[2], 
diff -u --recursive --new-file v1.3.69/linux/scripts/lxdialog/checklist.c linux/scripts/lxdialog/checklist.c
--- v1.3.69/linux/scripts/lxdialog/checklist.c	Wed Feb 28 11:50:18 1996
+++ linux/scripts/lxdialog/checklist.c	Wed Feb 28 08:28:31 1996
@@ -113,8 +113,7 @@
  */
 int
 dialog_checklist (const char *title, const char *prompt, int height, int width,
-	int list_height, int item_no, const char * const * items, int flag,
-	int separate_output)
+	int list_height, int item_no, const char * const * items, int flag)
 {
     int i, x, y, cur_x, cur_y, box_x, box_y;
     int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status;
diff -u --recursive --new-file v1.3.69/linux/scripts/tkgen.c linux/scripts/tkgen.c
--- v1.3.69/linux/scripts/tkgen.c	Wed Feb 28 11:50:18 1996
+++ linux/scripts/tkgen.c	Thu Feb 29 10:30:26 1996
@@ -922,10 +922,10 @@
 	    {
 	      if(cfg->tok == tok_dep_tristate)
 		{
-		  printf("\tif {$%s == 2 } then {\n"
+		  printf("\tif {$%s == 0 } then {\n"
 		  	 "\t\twrite_variable $cfg $autocfg %s $notset $notmod\n"
 		  	 "\t} else {\n"
-		  	 "\t\twrite_variable $cfg $autocfg %s $%s %s\n"
+		  	 "\t\twrite_variable $cfg $autocfg %s $%s $%s\n"
 		  	 "\t}\n",
 		  	 cfg->depend.str,
 			 cfg->optionname,
